我想为我的简单 ruby 函数添加一些调试,我编写了如下函数,
def debug(&block)
varname = block.call.to_s
puts "#{varname} = #{eval(varname,block)}"
end
debug {:x} #prints x = 5
debug {:y} #prints y = 5
我知道 eval 是邪恶的。所以我有两个问题。
- 有没有什么方法可以不使用 eval 来编写调试方法?如果否,是否有首选方法?
- 有什么方法可以将参数列表传递给这个方法吗?理想情况下,我更喜欢 debug {:x, :y。 :anynumOfvariables}。我不太清楚如何将其纳入调试方法(即获取参数列表)
最佳答案
只需使用数组。您可以使用 Array
方法来确保您始终拥有一个数组,即使有人只传入一个值也是如此:
def debug(&block)
Array(block[]).each do |var| puts "#{var} = #{eval var.to_s, block}" end
end
x, y = 3, 5
debug {:x} # => "x = 3"
debug {[:x, :y]} # => "x = 3" "y = 5"
顺便说一句:在 Ruby 1.9 中,将 block 作为绑定(bind)传递不再有效。 (尽管文档说它确实有效。)您必须显式调用 Proc#binding
来为那个 Binding
对象 过程
:
def debug(&block)
Array(block.()).flatten.each do |var|
puts "#{var} = #{eval var.to_s, block.binding}"
end
end
幸运的是,这个已经在 Ruby 1.8 中工作,因此您可以通过包含它来验证您的代码。
另一种方法是完全放弃区 block 。我的意思是,您已经 强制调试
的用户使用不熟悉的习惯用法,即在 block 中而不是在括号中传递参数。为什么不强制他们只传递绑定(bind)呢?
def debug(*vars, bnd)
vars.each do |var|
puts "#{var} = #{eval var.to_s, bnd}"
end
end
x, y = 3, 5
debug :x, binding # => "x = 3"
debug :x, :y, binding # => "x = 3" "y = 5"
这增加了灵 active ,他们实际上可以传递一个不同的绑定(bind),而不是调用站点的绑定(bind),例如如果他们想在应用程序的不同部分实际调试一段代码。
顺便说一句:Ruby 1.9.2 的参数内省(introspection)(Proc#parameters
)有一些有趣的地方:
def debug(&block)
block.parameters.map(&:last).each do |var|
puts "#{var} = #{eval var.to_s, block.binding}"
end
end
x, y = 3, 5
debug {|x|} # => "x = 3"
debug {|x, y|} # => "x = 3" "y = 5"
关于ruby - 在 Ruby 中放置变量名 = 值格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2509250/