当 Ruby 中出现第二个异常时,如何让旧的引用生效?
Posted
技术标签:
【中文标题】当 Ruby 中出现第二个异常时,如何让旧的引用生效?【英文标题】:How to get the reference alive to the older one, when there is a second exception in Ruby? 【发布时间】:2013-01-25 03:27:17 【问题描述】:begin
raise "explosion"
rescue
p $!
raise "Are you mad"
p $!
end
# #<RuntimeError: explosion>
# RuntimeError: Are you mad
# from (irb):5:in `rescue in irb_binding'
# from (irb):1
# from /usr/bin/irb:12:in `<main>'
$!
始终只保存当前异常对象引用。
但是在引发另一个异常之后,有什么方法可以获取对原始异常对象的引用(这里是“爆炸”)?
我自己尝试并得到了答案,希望现在对我的问题处于Smokey情况的所有人来说更清楚。
【问题讨论】:
您可能会被否决,因为您的要求非常不清楚。包含一个期望结果应该是什么的样本是个好主意。在这种情况下,您想对原始异常做什么?你不抢救第二个异常,那为什么又要原来的异常呢?当人们不得不猜测你可能想要什么时,他们往往会投反对票。 @TheMiddleMan Andrew Marshall 的编辑使您的问题变得清晰,但现在您添加了一个额外的段落,没有添加任何新信息,并且您的英语蹩脚再次使其不清楚。 我也给出了答案。也谢谢你们。 @sawa 你能告诉我现在出了什么问题吗,我也发布了我的答案。那么现在理解我在寻找什么的困惑是什么?如果还有什么烟雾,请告诉我。 @TheMiddleMan 我的错;我道歉。正如布拉德指出的那样,我们一直看到这样的帖子,这些帖子用于为原始问题添加额外的代码/细节。您可以通过补充您的代码并解释它是什么以及它如何解决您的问题来帮助我们避免混淆。 【参考方案1】:您是说在挽救第二个异常时要参考原始异常吗?如果是这样,那么您需要在救援期间在变量中捕获原始异常。这是通过这样做来完成的:
rescue StandardError => e
其中 StandardError 可以是任何类型的异常或省略(在这种情况下 StandardError 是默认值)。
例如代码:
begin
raise "original exception"
rescue StandardError => e
puts "Original Exception:"
puts $!
puts e
begin
raise "second exception"
rescue
puts "Second Exception:"
puts $!
puts e
end
end
给出输出:
Original Exception:
original exception
original exception
Second Exception:
second exception
original exception
如您所见,e
已经存储了原始异常以供第二个异常之后使用。
【讨论】:
【参考方案2】:class MyError < StandardError
attr_reader :original
def initialize(msg, original=$!)
super(msg)
@original = original;
end
end
begin
begin
raise "explosion"
rescue => error
raise MyError, "Are you mad"
end
rescue => error
puts "Current failure: #error.inspect"
puts "Original failure: #error.original.inspect"
end
输出
Current failure: #<MyError: Are you mad>
Original failure: #<RuntimeError: explosion>
=> nil
【讨论】:
以上是关于当 Ruby 中出现第二个异常时,如何让旧的引用生效?的主要内容,如果未能解决你的问题,请参考以下文章
对 ITVF 的引用会引发“在前一个操作完成之前在此上下文上启动的第二个操作”异常