Frage

Wenn ich aus einem C ++ - Hintergrund komme, bin ich neugierig auf die Objektzuweisung in Ruby. Welche Überlegungen (falls vorhanden) sollten für die folgenden Objektzuweisungen vorgenommen werden:

class MyClass

  attr_accessor :a, :b

  def initialize(a, b)
    @a = a
    @b = b
  end

  def some_method
    puts "#{self.a} #{self.b}"
  end
end

m = MyClass.new("first", "last")
n = MyClass.new("pizza", "hello")

q = n
q.some_method
War es hilfreich?

Lösung

Wenn Sie mit C ++ vertraut sind, möchten Sie möglicherweise jede Variable in Ruby, Instanz oder auf andere Weise als Verweis auf ein anderes Objekt betrachten. Da alles in Ruby ein Objekt ist, ist es sogar ein Objekt nil, was vom Typ Nilclass ist, dies gilt unter allen Umständen.

Um festzustellen, auf welches Objekt Sie sich verweisen, können Sie die verwenden object_id Methode zur Differenzierung. Das ähnelt der Konvertierung in einen Zeiger mit Verwendung & in C ++.

Bedenken Sie:

a = "foo"
b = a

a.object_id == b.object_id
# => true

Seit a ist ein Hinweis auf diese Zeichenfolge und b ist eine Kopie von a, Dann sind sie tatsächlich unterschiedliche Verweise auf dasselbe Objekt.

Dies ist wichtig, da Vorgänge, die ein Objekt ändern, alle Verweise auf diese gleichermaßen beeinflussen:

a << "bar"
# => "foobar"
b
# => "foobar"

Operationen, die a jedoch erzeugen Neu Das Objekt ändert nicht alle Kopien:

a += "baz"
# => "foobarbaz"
b
# => "foobar"

Viele Methoden in Ruby werden durch a identifiziert ! Um in der Vergleich zu New Copy-Versionen zu unterscheiden, ist dies jedoch nicht immer der Fall. Daher müssen Sie mit jeder Methode vertraut sein, um sicher zu sein.

Im Allgemeinen ersetzt eine Zuordnung eine alte Referenz durch eine neue, so dass als Faustregel = wird alte Referenzen ersetzen. Dies gilt für +=, -=, ||=, &&= usw.

Bearbeiten: Basierend auf PHROGZ 'Kommentar zur Verwendung aktualisiert ObjectSpace._id2ref(object_id) Um einen Objektkennung in ein Objekt umzuwandeln.

Andere Tipps

Da alles ein Objekt in Ruby ist, wird die Zuordnung immer nach Bezugnahme erfolgt.

Wenn Sie also Ihre Klasse als Eingabe nehmen, ist Folgendes die Ausgabe für mehrere Vorgänge:

str = "foo"
foo = MyClass.new(str, "bar")
foo.some_method # foo bar
bar = foo
bar == foo # true
bar.some_method # foo bar
str << "bar" # strings are mutable on ruby, so str is now "foobar"
foo.some_method # foobar bar
bar.some_method # foobar bar

Ich würde dies als:

class MyClass

  attr_accessor :a, :b

  def initialize(a, b)
    self.a = a
    self.b = b
  end

  def some_method
    puts "#{a} #{b}"
  end
end

Auf diese Weise verwenden Sie tatsächlich die von Getter/Setter -Methoden definierten Methoden attr_accessor Innerhalb Ihrer Klasse

Wenn Sie zuweisen q = n, q verweist nur auf den gleichen Speicherort, der für n festgelegt wurde. Das Objekt wird nicht kopiert.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top