¿Pasa el parámetro por referencia en Ruby?
-
03-07-2019 - |
Pregunta
En Ruby, ¿es posible pasar por referencia un parámetro con semántica de tipo de valor (por ejemplo, un Fixnum)? Estoy buscando algo similar a la palabra clave '#strong> ref ' de C # 's.
Ejemplo:
def func(x)
x += 1
end
a = 5
func(a) #this should be something like func(ref a)
puts a #should read '6'
Por cierto. Sé que podría usar:
a = func(a)
Solución
Puede lograr esto pasando explícitamente el enlace actual:
def func(x, bdg)
eval "#{x} += 1", bdg
end
a = 5
func(:a, binding)
puts a # => 6
Otros consejos
Ruby no admite " pasar por referencia " en absoluto. Todo es un objeto y las referencias a esos objetos siempre se pasan por valor. En realidad, en su ejemplo, está pasando una copia de la referencia al objeto Fixnum
por valor.
El problema con su código es que x + = 1
no modifica el objeto Fixnum
pasado, sino que crea un objeto completamente nuevo e independiente.
Creo que los programadores de Java llamarían objetos Fixnum
inmutables .
En Ruby no puedes pasar parámetros por referencia. Para su ejemplo, tendría que devolver el nuevo valor y asignarlo a la variable a o crear una nueva clase que contenga el valor y pasar una instancia de esta clase. Ejemplo:
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
Puedes probar el siguiente truco:
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
Los objetos Fixnum tienen valor inmediato. Esto significa que cuando son asignados o pasados ??como parámetros, se pasa el objeto real, en lugar de una referencia a ese objeto.
También Ruby se pasa por valor .
Sin embargo, parece que los objetos compuestos, como los hashes, se pasan por referencia:
fp = {}
def changeit(par)
par[:abc] = 'cde'
end
changeit(fp)
p fp
da
{:abc=>"cde"}