Ruby - 从符号转换为变量

时间:2009-10-06 17:52:00

标签: ruby metaprogramming

如何将obj转换回def中名为obj的变量?

def foo(bar)
  bar.some_method_call
end

foo :obj

更新: 最终的代码比这更详细,但......

我希望能够说出

foo :obj  

而不是

foo obj  

我正在研究一些类似DSL的语法。而这一改变会让事情看得更清楚。

5 个答案:

答案 0 :(得分:11)

您的示例中的obj是什么类型的变量?如果它是调用foo的作用域的局部变量,则无法从foo内部访问它,除非您将当前绑定作为第二个参数传递。

如果要访问实例变量@obj,则很容易:

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

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

答案 1 :(得分:5)

你可以使用eval

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

答案 2 :(得分:3)

这有点奇怪,但是如果你愿意传递一个空块(或者你是否正在传递一个空块),你可以从块中获取绑定,然后调用eval并传递绑定:< / p>

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)

答案 3 :(得分:1)

你的意思是变量还是访问者方法? Sepp2k给出了一个实例变量的名称;对于访问者使用

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

答案 4 :(得分:0)

你几乎肯定不能。该定义将无法访问调用范围的局部变量。如果你想更全面地解释一下你想要做的事情,我们或许可以提供一个有用的替代方案。