-9
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>'

$! always holds only the current exception object reference.

But is there any way to get a reference to the original exception object (here it is "explosion"), after another exception has been raised? <~~~ Here is my question.

Myself tried and reached to the answer,hope now it is more clearer to all who was in Smokey situation with my queries.

4

2 回答 2

3

您是说在挽救第二个异常时要参考原始异常吗?如果是这样,那么您需要在救援期间在变量中捕获原始异常。这是通过执行以下操作来完成的:

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,已存储原始异常以供在第二个异常之后使用。

于 2013-02-09T14:31:27.590 回答
-1
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
于 2013-02-09T15:18:46.280 回答