'passa parametro per riferimento' in Ruby?
-
03-07-2019 - |
Domanda
In Ruby è possibile passare per riferimento un parametro con semantica di tipo valore (ad es. Fixnum)? Sto cercando qualcosa di simile alla parola chiave ref 'di C #.
Esempio:
def func(x)
x += 1
end
a = 5
func(a) #this should be something like func(ref a)
puts a #should read '6'
Btw. So che potrei semplicemente usare:
a = func(a)
Soluzione
È possibile ottenere questo risultato passando esplicitamente il binding corrente:
def func(x, bdg)
eval "#{x} += 1", bdg
end
a = 5
func(:a, binding)
puts a # => 6
Altri suggerimenti
Ruby non supporta " passa per riferimento " affatto. Tutto è un oggetto e i riferimenti a tali oggetti vengono sempre passati per valore. In realtà, nel tuo esempio stai passando una copia del riferimento all'oggetto Fixnum
per valore.
Il problema con il tuo codice è che x + = 1
non modifica l'oggetto Fixnum
passato ma crea invece un oggetto completamente nuovo e indipendente.
Penso che i programmatori Java chiamerebbero Fixnum
oggetti immutabili .
In Ruby non puoi passare parametri per riferimento. Per il tuo esempio, dovresti restituire il nuovo valore e assegnarlo alla variabile a oppure creare una nuova classe che contiene il valore e trasmettere un'istanza di questa classe. Esempio:
class Container
attr_accessor :value
def initialize value
@value = value
end
end
def func(x)
x.value += 1
end
a = Container.new(5)
func(a)
puts a.value
Puoi provare il seguente trucco:
def func(x)
x[0] += 1
end
a = [5]
func(a) #this should be something like func(ref a)
puts a[0] #should read '6'
http://ruby-doc.org/core-2.1.5 /Fixnum.html
Gli oggetti Fixnum hanno un valore immediato. Ciò significa che quando sono assegnati o passato come parametro, l'oggetto reale viene passato, piuttosto che un riferimento a quell'oggetto.
Anche Il ruby ??è passato per valore .
Tuttavia, sembra che gli oggetti compositi, come gli hash, vengano passati per riferimento:
fp = {}
def changeit(par)
par[:abc] = 'cde'
end
changeit(fp)
p fp
dà
{:abc=>"cde"}