Ruby - конвертировать из символа в переменную - PullRequest
10 голосов
/ 06 октября 2009

Как я могу преобразовать: obj обратно в переменную с именем obj внутри def?

def foo(bar)
  bar.some_method_call
end

foo :obj

UPDATE : Окончательный код более сложный, чем этот, но ...

Мне нравится, когда я могу сказать

foo :obj  

вместо

foo obj  

Я работаю над некоторым DSL-подобным синтаксисом. И это одно изменение позволит вещам читать немного яснее.

Ответы [ 5 ]

11 голосов
/ 06 октября 2009

Какая переменная obj в вашем примере? Если это локальная переменная в области видимости, где вызывается foo, к ней нельзя получить доступ из foo, если вы не передадите текущую привязку в качестве второго параметра.

Если вы хотите получить доступ к переменной экземпляра @obj, это просто:

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

@obj = "lala"
foo("obj") #=> 4
5 голосов
/ 07 октября 2009

Вы можете использовать eval

def foo(bar)
  eval(bar.to_s).some_method_call
end
3 голосов
/ 07 октября 2009

Это немного странно, но если вы хотите пропустить пустой блок (или если вы все равно его пропускаете), вы можете получить привязку из блока, затем вызвать eval и передать привязку:

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

  eval(symbol.to_s, binding)
end

var = 3

puts foo(:var) {}

Это напечатает 3.

В качестве альтернативы, ActiveSupport, очевидно, имеет нечто, называемое Binding.of_caller, которое вы можете использовать, чтобы вам не приходилось пропускать блок, но я не знаю, насколько хорошо он работает.

Другая альтернатива - вызвать foo и передать привязку в:

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

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

puts foo(binding, :var)
1 голос
/ 06 октября 2009

Вы имеете в виду переменную или метод доступа? Sepp2k дал имя для переменной экземпляра; для доступа использовать

def foo(bar)
  self.send(bar).some_method_call
end
0 голосов
/ 06 октября 2009

Вы почти наверняка не можете. Это определение не будет иметь доступа к локальным переменным вызывающей области. Если вы хотите более подробно объяснить, что вы пытаетесь сделать, мы могли бы предложить полезную альтернативу.

...