有时回溯足以诊断问题。但有时在不知道传递给函数的内容的情况下,崩溃的原因并不明显。
获取传递给导致崩溃的函数的信息将非常有用,特别是在重现不明显的情况下,因为它是由例如网络连接异常、奇怪的用户输入或因为程序依赖于随机化或进程引起的来自外部传感器的数据。
假设有以下程序
def handle_changed_input(changed_input)
raise 'ops' if changed_input =~ /magic/
end
def do_something_with_user_input(input)
input = "#{input.strip}c"
handle_changed_input(input)
end
input = gets
do_something_with_user_input(input)
用户输入“magic”作为输入。通常一个人有
test.rb:2:in `handle_changed_input': ops (RuntimeError)
from test.rb:7:in `do_something_with_user_input'
from test.rb:11:in `<main>'
作为输出。可以做什么来显示传递给函数的内容?有点像
test.rb:2:in `handle_changed_input("magic")': ops (RuntimeError)
from test.rb:7:in `do_something_with_user_input("magi\n")'
from test.rb:11:in `<main>'
它在许多情况下都很有用(在参数不能表示为合理长度的字符串时并不是真正有用,默认情况下不启用它是有充分理由的)。
如何添加此功能?程序在正常运行期间必须像往常一样工作,最好在崩溃前没有额外的输出。
例如我试过
def do_something_with_user_input(input)
method(__method__).parameters.map do |_, name|
puts "#{name}=#{binding.local_variable_get(name)}"
end
raise 'ops' if input =~ /magic/
end
input = gets
发现于 Is there a way to access method arguments in Ruby?但它会在每个单独的入口上打印以运行什么,这既会淹没输出又会使程序显着变慢。
最佳答案
我没有完整的解决方案但是...但是您可以使用 TracePoint 在受控环境中获取所有调用方法的方法参数来自 Ruby 核心库的类。
看例子:
trace = TracePoint.new(:call) do |tp|
puts "===================== #{tp.method_id}"
b_self = tp.binding.eval('self')
names = b_self.method(tp.method_id).parameters.map(&:last)
values = names.map { |name| tp.binding.eval(name.to_s) }
p names.zip(values)
end
trace.enable
def method_a(p1, p2, p3)
end
method_a(1, "foobar", false)
#=> ===================== method_a
#=> [[:p1, 1], [:p2, "foobar"], [:p3, false]]
关于ruby - 如何让 ruby 打印包含传递给函数的参数的完整回溯?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44227589/