2009-10-06 2 views
8

Come posso convertire: obj di nuovo in una variabile chiamata obj all'interno della def?Ruby - conversione da simbolo a variabile

def foo(bar) 
    bar.some_method_call 
end 

foo :obj 

UPDATE: Il codice finale è più elaborato di questo, ma ...

Mi piace essere in grado di dire

foo :obj 

invece di

foo obj 

Sto lavorando su una sintassi simile a DSL. E questo cambiamento permetterebbe alle cose di leggere un po 'più chiaramente.

+0

Significa questo vostro simbolo, rappresentato bar interno, corrisponde direttamente ad una variabile di istanza? – Matt

risposta

0

Quasi non si può. Quella definizione non avrà accesso alle variabili locali dell'ambito chiamante. Se vuoi spiegare un po 'più a fondo ciò che stai cercando di fare, potremmo essere in grado di offrire un'alternativa utile.

+0

vedi aggiornamento e commenti – BuddyJoe

11

Che tipo di variabile è obj nell'esempio? Se si tratta di una variabile locale dell'ambito in cui viene chiamato foo, non è possibile accedervi dall'interno di foo, a meno che non si passi il binding corrente come secondo parametro.

Se si desidera accedere alla variabile di istanza @obj, è facile:

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

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

obj è al di fuori dell'ambito di foo. +1 buone informazioni – BuddyJoe

1

Vuoi dire la variabile o il metodo di accesso? Sepp2k ha dato il nome per una variabile di istanza; per una funzione di accesso utilizzare

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

si potrebbe usare eval

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

E 'un po' strano, ma se siete disposti a passare un blocco vuoto (o se si passa uno comunque), si può ottenere l'associazione dal blocco, quindi chiamare eval e passare il binding:

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

    eval(symbol.to_s, binding) 
end 

var = 3 

puts foo(:var) {} 

Questo stamperà 3.

In alternativa, ActiveSupport apparentemente ha qualcosa chiamato Binding.of_caller che potresti essere in grado di usare in modo da non dover passare il blocco, ma non so quanto bene funzioni.

Un'altra alternativa è quella di chiamare foo e passare il vincolante:

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

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

puts foo(binding, :var)