Assegnazione oggetto in Ruby [chiuso]
-
27-10-2019 - |
Domanda
Venendo da un C ++ sfondo Sono curioso di sapere assegnazione oggetto in Ruby. Quali considerazioni (se presente) deve essere fatta per le seguenti assegnazioni di oggetto:
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
Soluzione
Se si ha familiarità con C ++, allora si potrebbe prendere in considerazione tutte le variabili in Ruby, istanza o altrimenti, come un riferimento a un altro oggetto. Poiché tutto in Ruby è un oggetto, anche nil
, che è di tipo NilClass, questo vale in ogni circostanza.
Per determinare quale oggetto fari riferimento, è possibile utilizzare il metodo object_id
per differenziare. Questo è simile alla conversione a un puntatore utilizzando &
in C ++.
Considerate questo:
a = "foo"
b = a
a.object_id == b.object_id
# => true
Poiché a
è un riferimento a tale stringa e b
è una copia di a
, allora sono effettivamente differenti riferimenti allo stesso oggetto.
Questo è importante perché le operazioni che modificano un oggetto influenzano ogni riferimento a tale ugualmente:
a << "bar"
# => "foobar"
b
# => "foobar"
Tuttavia, le operazioni che creano un nuovo oggetto non modificare tutte le copie:
a += "baz"
# => "foobarbaz"
b
# => "foobar"
Molti metodi in Ruby sono identificati da un !
per distinguere sul posto rispetto alle versioni di nuova copia, ma questo non è sempre il caso, quindi bisogna avere familiarità con ogni metodo, al fine di essere sicuri.
In genere un incarico andrà a sostituire un vecchio di riferimento con uno nuovo, così come regola generale, =
sostituirà i vecchi riferimenti. Questo vale per +=
, -=
, ||=
, &&=
e così via.
Modifica:. Aggiornamento in base a commento di Phrogz sull'utilizzo ObjectSpace._id2ref(object_id)
per convertire un identificatore di oggetto in un oggetto
Altri suggerimenti
Poiché tutto è un oggetto in rubino, assegnazione è sempre in funzione.
Quindi, prendendo la classe come ingresso, il successivo sarà l'output per diverse operazioni:
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
vorrei riscrivere questo come:
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
In questo modo si sta usando i metodi getter / setter definiti dalla attr_accessor
all'interno della vostra classe
Quando si q = n
assegnare, q solo fa riferimento alla stessa posizione di memoria che è stato fissato per il n. L'oggetto non viene copiato.