2008-10-02 53 views
25

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 'ref' de C#.'pasar parámetro por referencia' en Ruby?

Ejemplo:

def func(x) 
    x += 1 
end 

a = 5 
func(a) #this should be something like func(ref a) 
puts a #should read '6' 

BTW. Sé que podría usar:

a = func(a) 

Respuesta

30

Esto se puede hacer mediante el paso de manera explícita en la unión actual:

def func(x, bdg) 
    eval "#{x} += 1", bdg 
end 

a = 5 
func(:a, binding) 
puts a # => 6 
+3

¿Es seguro este subproceso? – Dex

18

Ruby no es compatible con "pasar por referencia" en absoluto. Todo es un objeto y las referencias a esos objetos siempre pasan por valor. En realidad, en su ejemplo está pasando una copia de la referencia al objeto Fixnum por valor.

El problema con el código es que x += 1 no modifica el objeto pasado Fixnum sino que crea un objeto completamente nuevo e independiente.

Creo que los programadores de Java llamarían Fixnum objetos inmutables.

+3

No entiendo esto que Ruby no pasa por ref, cuando las variables y los parámetros solo pueden contener referencias a objetos. Decir que las referencias se pasan por valor es lo mismo que decir que los objetos se pasan por referencia. –

+2

@Damien: no, no lo es. Pase por referencia (por ejemplo, en C++, C#, PHP, Perl) le permite * asignar * a la variable como si le hubiera asignado en el ámbito externo. Lo que estás tratando de hacer aquí sería posible con un pase verdadero por referencia; pero no con pasar por el valor de las referencias. – newacct

+6

Tienes razón, estoy leyendo la respuesta de Christoph y mi comentario otra vez y no estoy de acuerdo con mi 2009-self. Hmm ... –

10

en Ruby no se puede pasar parámetros por referencia. Para su ejemplo, debería 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 
6

Puede probar 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' 
+0

sí, que funciona –

+0

Técnicamente, esto también reemplaza la variable (y la referencia en la lista) en la escritura. – itarato

Cuestiones relacionadas