我的确切痛点是解析文件列表。每个文件都有多行。当出现问题时,我想打印出当前文件名、当前行号、当前行和其他一些有趣的变量,然后在大多数情况下退出,因为错误将出现在需要增强的代码中。
大多数变量是嵌套的#each
块的本地变量。有很多地方可能出现问题。
我想做的只是有一个全局begin
、rescue
、end
块,在rescue
中有一个Binding
可供我使用,这样我就可以挖掘出我感兴趣打印出来的各种变量。
这似乎是一个相当明显的Ruby
类型的东西,所以我觉得很奇怪,我是第一个想要这样东西的人。然而,在Ruby文档的异常处理部分中,我没有看到任何Binding
或闭包概念。通常,这意味着我完全滥用了语言的概念。
好吧,最简单的方法是在begin ... rescue ... end block
之前定义要跟踪的所有变量。
然后,您可以在救援区块内轻松访问它们:
variable = 0
another_variable = 0
begin
3.times do |a|
variable = a
5.times do |b|
another_variable = b
if a == 2 and b == 4
raise KeyError
end
end
end
at_exit do
puts binding.eval 'variable'
puts binding.eval 'another_variable'
end
rescue KeyError
puts variable
puts another_variable
end
但是,如果您想在异常发生之前获得最后一个binding
,您的解决方案是使用TracePoint:https://ruby-doc.org/core-2.5.0/TracePoint.html
这允许u跟踪定义了所需局部变量的绑定,然后获取最后一个绑定。当然,如果你将使用这种方法,它会使你的程序有点慢。使用示例:
last_binding = nil
trace = TracePoint.new(:b_return) do |tp|
last_binding = tp.binding if tp.binding.local_variable_defined?('variable')
end
trace.enable
begin
3.times do |a|
variable = a
5.times do |b|
another_variable = b
if a == 2 and b == 4
raise KeyError
end
end
end
at_exit do
puts binding.eval 'variable'
puts binding.eval 'another_variable'
end
rescue KeyError
trace.disable
puts last_binding.eval 'another_variable'
end
(你最好跟踪的事件是b_return
——它发生在每个区块结束后,所以这将使你的跟踪时间达到最佳(