Ruby:获取变量名称

我如何获得变量名称? 例如,

def get_var_name(var) # return variable name end myname = nil get_var_name myname #=> myname 

初衷:

 somevar = "value" puti somevar #=> somevar = "value" # that is a shortage for # `puts "somevar = #{somevar.inspect}"` 

我的尝试:

 def puti(symb) var_name = symb.to_s var_value = eval(var_name) puts "#{var_name} = #{var_value.inspect}" end puti :@somevar # that actually will work only with class vars or whatever considering var scope; 

首先,你puti并直接调用puti a_var来获得输出a_var = value of a_var 。 在puti的主体,Ruby只看到puti的forms参数名称,它无法推断出实际的参数名称。

在其他语言如C / C ++中,您可以使用Macro来实现您的puti 。 那是另一个故事。

但是,您可以在Continuation的帮助下实现put :a_var 。 在另一个问题“ 你可以在Ruby中调用者的上下文中评估代码吗? ”, Sony Santos提供了一个caller_binding实现来获得调用者的绑定(类似于perl调用函数)。

实现应该稍微改变一下,因为callcc在第一次返回时返回块的返回值。 因此,您将获得Continuation的实例而不是nil 。 这是更新版本:

 require 'continuation' if RUBY_VERSION >= '1.9.0' def caller_binding cc = nil # must be present to work within lambda count = 0 # counter of returns set_trace_func lambda { |event, file, lineno, id, binding, klass| # First return gets to the caller of this method # (which already know its own binding). # Second return gets to the caller of the caller. # That's we want! if count == 2 set_trace_func nil # Will return the binding to the callcc below. cc.call binding elsif event == "return" count += 1 end } # First time it'll set the cc and return nil to the caller. # So it's important to the caller to return again # if it gets nil, then we get the second return. # Second time it'll return the binding. return callcc { |cont| cc = cont; nil } end # Example of use: def puti *vars return unless bnd = caller_binding vars.each do |s| value = eval s.to_s, bnd puts "#{s} = #{value.inspect}" end end a = 1 b = 2 puti :a, :b e = 1 # place holder... # => a = 1 # b = 2 

请注意, puti不应该是程序的最后一个语句,否则ruby解释器将立即终止并且跟踪function无法运行。 所以这就是最后一个“占位符”线的重点。

您需要执行当前变量范围的绑定 ,这与Binding类一起使用 :

 def puti(symb, the_binding) var_name = symb.to_s var_value = eval(var_name, the_binding) puts "#{var_name} = #{var_value.inspect}" end somevar = 3 puti :somevar, binding # Call the binding() method #=> outputs "somevar = 3" 

binding()方法给出一个Binding对象,它记住调用方法时的上下文。 然后将绑定传递给eval() ,并在该上下文中计算变量。