2009-10-06 8 views
8

¿Cómo puedo convertir: obj de nuevo en una variable llamada obj dentro de la definición?Ruby - convertir de símbolo a variable

def foo(bar) 
    bar.some_method_call 
end 

foo :obj 

ACTUALIZACIÓN: El código final es más elaborado que esto, pero ...

Me gustaría ser capaz de decir

foo :obj 

en lugar de

foo obj 

Estoy trabajando en alguna sintaxis similar a DSL. Y este cambio permitiría que las cosas se lean un poco más.

+0

¿Quiere esto decir que su símbolo, representado en el interior de la barra, corresponde directamente a una variable de instancia? – Matt

Respuesta

0

Es casi seguro que no. Esa definición no tendrá acceso a las variables locales del alcance de la llamada. Si desea explicar un poco más completamente lo que está tratando de hacer, podríamos ofrecerle una alternativa útil.

+0

ver la actualización y los comentarios – BuddyJoe

11

¿Qué tipo de variable es obj en su ejemplo? Si se trata de una variable local del alcance donde se llama a foo, no se puede acceder desde foo, a menos que pase el enlace actual como un segundo parámetro.

Si desea acceder a la instancia de variable @obj, es fácil:

def foo(bar) 
    instance_variable_get("@#{bar}").length 
end 

@obj = "lala" 
foo("obj") #=> 4 
+0

obj está fuera del alcance de foo. +1 buena información – BuddyJoe

1

¿Quiere decir que la variable o el método de acceso? Sepp2k dio el nombre para una variable de instancia; para un descriptor de acceso utilizan

def foo(bar) 
    self.send(bar).some_method_call 
end 
4

usted podría utilizar eval

def foo(bar) 
    eval(bar.to_s).some_method_call 
end 
3

Es un poco extraño, pero si usted está dispuesto a pasar a un bloque vacío (o si estás de paso uno de todos modos), que puede llegar la unión del bloque, a continuación, llamar eval y pasar la unión:

def foo(symbol, &block) 
    binding = block.send(:binding) 

    eval(symbol.to_s, binding) 
end 

var = 3 

puts foo(:var) {} 

Esto imprimirá 3.

Alternativamente, ActiveSupport aparentemente tiene algo llamado Binding.of_caller que puede usar para no tener que pasar el bloque, pero no sé qué tan bien funciona.

Otra alternativa es llamar foo y pasar a la unión en:

def foo(binding, symbol) 
    eval(symbol.to_s, binding) 
end 

binding = self.send(:binding) 
var = 3 

puts foo(binding, :var) 
Cuestiones relacionadas