dopo una giornata intera a cercare su internet non sono riuscito a
capire se e` possibile definire un metodo che modifica i parametri
ricevuti ‘in place’.
Faccio un esempio:
def funz! a
a = “Pluto”
end
a = “Pippo”
funz! a
print a #vorrei che stampasse Pluto
In realtà credo che Ruby utilizzi esclusivamente il
passaggio per
valore e non per riferimento… Del resto è “logico”
in un’ottica
OO…
il contrario, il passaggio è sempre per riferimento,
ovvero l’oggetto non viene mai copiato, viene sempre
passato un riferimento allo stesso.
E’ proprio per questo che se usi metodi che modificano
l’oggetto come String#gsub! questo viene cambiato
anche nell’ambito del chiamante.
Il problema per cui non è possibile fare:
def change(a)
oggetto passato = 20
end
a= 10
change(a)
puts a # 20
è che all’interno del metodo #change puoi solo
cambiare il “nome” ma non la “sostanza”[1]
Se ti serve un comportamento di questo tipo, che al
99% è errato, di conviene costruire una tua classe
Klass che mantiene in una variabile d’istanza il
valore effettivo, e fornisce un metodo #update (o #set, o @value=) per cambiarlo.
[1] a meno di hack malvagi, ad esempio in evil.rb
esiste un metodo Object#become(another), copiato da
Smalltalk, che permette di trasformare un oggetto in
un altro
Aspetta aspetta…
String.chomp! è un metodo che ti modifica l’oggetto String che lo
invoca, e non il parametro che gli passi (che tra l’altro serve a
tutt’altro)
Ruby passa i parametri per valore. Non puoi cambiare l’identità
dell’oggetto passato; però puoi invocare sull’oggetto passato dei metodi
che
ne modificano lo stato. Ad esempio:
def change(a); a[0] = “pluto”; end
=> nil
x = [“pippo”]
=> [“pippo”]
change x
=> “pluto”
x
=> [“pluto”]
M
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.