【发布时间】:2017-10-28 21:11:52
【问题描述】:
有时回溯足以诊断问题。但有时在不知道传递给函数的内容的情况下,崩溃的原因并不明显。
获取传递给导致崩溃的函数的信息将非常有用,尤其是在复制不明显的情况下,因为它是由例如网络连接中的异常、奇怪的用户输入或因为程序依赖于随机化或进程而引起的来自外部传感器的数据。
假设有以下程序
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)
用户输入“魔法”作为输入。通常有一个
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? 中找到,但它会在每个入口处打印,以实现既会淹没输出又会使程序显着变慢的功能。
【问题讨论】:
-
如果我理解正确,您需要打印出哪些参数被传递给引发错误的方法。对吗?
-
对所有方法调用进行概括是没有意义的,因为对象参数可能没有有意义的字符串表示。你所看到的只是:
#<Object:0x007ff6d3b7af08> -
@fylooi 我知道有很多很多情况下这是没有意义的(没有转换为字符串的对象、非常长的字符串、处理私有数据的程序以及许多其他情况)。但是在方法的参数是字符串或实现到字符串转换的对象的情况下,它会非常有用。另请参阅“默认情况下不启用它是有充分理由的”。
-
@Efesto 非常感谢,问题的初始版本不清楚。我想打印出堆栈跟踪中所有方法的参数 - 从发生异常的地方开始。我修改了问题,使我想查看所有方法的参数更加明显。
-
@MateuszKonieczny:我想收集那个赏金,但我担心你想做的事情实际上是不可能的。
标签: ruby debugging stack-trace printstacktrace