提问人:pedz 提问时间:3/22/2022 更新时间:3/23/2022 访问量:66
在 Ruby 中,是否有在救援期间出现异常时创建的可用绑定?
In Ruby, is there a Binding available that is created at the time of the exception available during the rescue?
问:
我遇到的确切痛点是我正在解析文件列表。每个文件都有多行。当出现问题时,我想打印出诸如当前文件名、当前行号、当前行和其他一些有趣的变量之类的内容,然后在大多数情况下退出,因为错误将出现在我的代码中,需要增强。
大多数变量是嵌套块的局部变量。有很多地方可能会出错。#each
我想做的是只有一个全局 , , 块,并在 中有一个可供我使用的变量,这样我就可以挖掘出我有兴趣打印出来的各种变量。begin
rescue
end
rescue
Binding
这似乎是一个相当明显的事情,所以我觉得很奇怪,我是第一个想要这样东西的人。然而,我在 Ruby 文档的异常处理部分没有看到任何闭包概念。通常这意味着我从根本上滥用了语言的概念。Ruby
Binding
答:
0赞
Leon
3/23/2022
#1
好吧,最简单的方法是在 .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
但是,如果您想在异常发生之前获得最后一个 - 您的解决方案是使用 TracePoint: https://ruby-doc.org/core-2.5.0/TracePoint.htmlbinding
这允许您跟踪定义了所需局部变量的绑定,然后获取最后一个绑定。当然,如果你使用这种方法,它会让你的程序变慢一点。使用示例:
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
评论
0赞
pedz
3/23/2022
谢谢。我知道我可以使用全局变量......这对我来说简直太恶心了。Tracepoint 听起来像是一个跟踪工具。异常的运行时开销为零,但跟踪为零。追踪还有其他微妙的、难以诊断的副作用。听起来我问题的真正答案是“不”。我想我会在 Ruby bug 网站上提交一个功能。
评论