2009-10-06 7 views
8

Jak mogę przekonwertować: obiekt z powrotem na zmienną o nazwie obj wewnątrz def?Ruby - konwersja z symbolu na zmienną

def foo(bar) 
    bar.some_method_call 
end 

foo :obj 

UPDATE: Ostateczny kod jest bardziej skomplikowany niż to, ale ...

Chciałbym móc powiedzieć

foo :obj 

zamiast

foo obj 

Pracuję nad pewną składnią podobną do DSL. I ta jedna zmiana pozwoliłaby, by rzeczy stały się trochę jaśniejsze.

+0

Czy to znaczy swój symbol, reprezentowany wewnątrz baru, bezpośrednio odpowiada zmiennej instancji? – Matt

Odpowiedz

0

Prawie na pewno nie możesz. Ta definicja nie będzie miała dostępu do zmiennych lokalnych zakresu wywoływania. Jeśli chcesz dokładniej wyjaśnić, co próbujesz zrobić, być może będziemy mogli zaoferować przydatną alternatywę.

+0

zobacz aktualizację i komentarze – BuddyJoe

11

Jaką zmienną jest obj w twoim przykładzie? Jeśli jest to lokalna zmienna zakresu, w którym jest wywoływana foo, nie można uzyskać do niej dostępu z wewnątrz foo, chyba że przekazujesz bieżące powiązanie jako drugi parametr.

Jeśli chcesz uzyskać dostęp do instancji zmiennej @obj, to proste:

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

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

obj jest poza zakresem foo. +1 dobre informacje – BuddyJoe

1

Czy chodziło Ci o zmiennej lub metody dostępowej? Sepp2k podał nazwę zmiennej instancji; dla akcesor używać

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

Można użyć eval

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

To trochę dziwne, ale jeśli jesteś gotów przekazać pusty blok (lub jeśli przechodzą jeden w każdym razie), można uzyskać wiązanie z bloku, a następnie zadzwonić eval i przekazać wiązanie:

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

    eval(symbol.to_s, binding) 
end 

var = 3 

puts foo(:var) {} 

To będzie drukować 3.

Alternatywnie, ActiveSupport najwyraźniej ma coś o nazwie Binding.of_caller, którego możesz używać, więc nie musisz przekazywać bloku, ale nie wiem, jak to działa.

Inną alternatywą jest wywołanie foo i przekazać wiązanie w:

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

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

puts foo(binding, :var)