Ruby – 打印变量名称,然后打印其值

编写允许我在Ruby中编写此代码的函数(或DSLish)的最佳方法是什么。 我如何构造函数write_pair?

username = "tyndall" write_pair username # where write_pair username outputs username: tyndall 

有可能吗? 寻找最简单的方法来做到这一点。

当然有可能!

我的解决方案通过Object#object_id标识测试var: http : //codepad.org/V7TXRxmL
它在绑定传递方式中瘫痪……
虽然它只适用于本地变量,但它可以很容易地“通用”添加使用其他范围变量列表方法,如instance_variables等。

 # the function must be defined in such a place # ... so as to "catch" the binding of the vars ... cheesy # otherwise we're kinda stuck with the extra param on the caller @_binding = binding def write_pair(p, b = @_binding) eval(" local_variables.each do |v| if eval(v.to_s + \".object_id\") == " + p.object_id.to_s + " puts v.to_s + ': ' + \"" + p.to_s + "\" end end " , b) end # if the binding is an issue just do here: # write_pair = lambda { |p| write_pair(p, binding) } # just some test vars to make sure it works username1 = "tyndall" username = "tyndall" username3 = "tyndall" # the result: write_pair(username) # username: tyndall 

如果您可以使用符号而不是变量名称,则可以执行以下操作:

 def wp (s, &b) puts "#{s} = #{eval(s.to_s, b.binding)}" end 

正在使用:

 irb(main):001:0> def wp (s, &b) irb(main):002:1> puts "#{s} = #{eval(s.to_s, b.binding)}" irb(main):003:1> end => nil irb(main):004:0> var = 3 => 3 irb(main):005:0> wp(:var) {} var = 3 

请注意,您必须将空块{}传递给方法,否则无法获取绑定来评估符号。

我为此制作了一个vim宏:

 " Inspect the variable on the current line (in Ruby) autocmd FileType ruby nmap ,i ^"oy$Iputs "A: #{("opA).inspect}" 

将您想要检查的变量单独放在一行上,然后在正常模式下键入,i (逗号,然后是i)。 它变成了这样:

 foo 

进入这个:

 puts "foo: #{(foo).inspect}" 

这很好,因为它没有任何外部依赖项(例如,您不必加载库来使用它)。

这是一个简单的解决方案:

  def bug string puts string + eval(string) end 

这更具可读性:

  def bug string puts '#' * 100 puts string + ': ' + eval(string).inspect end 

因此调用它:

 bug "variable" 

如果你需要携带实际变量,你必须输入两次,但是你可以内联。 从而:

 puts "variable: #{variable}" 

基于以前与符号和绑定相关的答案…如果传入变量名称作为符号适合您(谁不喜欢削减额外的击键?!),请尝试这样做:

 def wp(var_name_as_sym) # gets caller binding, which contains caller's execution environment parent_binding = RubyVM::DebugInspector.open{|i| i.frame_binding(2) } # now puts the symbol as string + the symbol executed as a variable in the caller's binding puts %Q~#{var_name_as_sym.to_s} = #{eval("#{var_name_as_sym.to_s}.inspect", parent_binding)}~ end aa=1 bb='some bb string' os = OpenStruct.new(z:26, y:25) 

控制台输出:

 > wp :aa aa = 1 => nil > wp :bb bb = "some bb string" => nil > wp :os os = # => nil 

使用ruby 2.2.2p95

(感谢banister 获取调用上下文的绑定 )

你实际上无法在Ruby中获得变量的名称。 但你可以这样做:

data = {"username" => "tyndall"}

甚至,

 username = "tyndall" data = {"username", "password", "favorite_color"} data.each { |param| value = eval(param) puts "#{param}: #{value}" } 
 def write_pair var, binding puts "#{ var } = #{ eval(var, binding)}" end username = "tyndall" write_pair "username", binding 

这似乎很奇怪,因为从未定义绑定,但它可以工作。 来自Ruby:获取变量名称 :

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

一定要传递一个字符串,而不是变量。

 # make use of dynamic scoping via methods and instance vars @_binding = binding def eval_debug(expr, binding = @_binding) "#{expr} => #{eval(expr, binding)}" end # sample invocation: x = 10 puts eval_debug "x" puts eval_debug "x**x"