参见英文答案 >
Ruby – print the variable name and then its value8个
我如何获得变量名称?例如.,
我如何获得变量名称?例如.,
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 = a_var的值.在puti的主体,Ruby只看到puti的形式参数名称,它无法推断出实际的参数名称.
在其他语言如C/C++中,您可以使用Macro来实现您的puti.那是另一个故事.
但是,您可以在Continuation的帮助下实现put:a_var.在另一个问题“Can you eval code in the context of a caller in 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解释器将立即终止并且跟踪功能无法运行.这就是最后一个“占位符”行的重点.