Objektzuweisung in Ruby [geschlossen
-
27-10-2019 - |
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
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.