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

$!常に現在の例外オブジェクト参照のみを保持します。

しかし、別の例外が発生した後、元の例外オブジェクト (ここでは「爆発」) への参照を取得する方法はありますか? <~~~ これが私の質問です。

私自身が試して答えにたどり着きました。私の質問でスモーキーな状況にあったすべての人にとって、それがより明確になることを願っています.

4

2 に答える 2

3

2 番目の例外をレスキューするときに、元の例外を参照したいということですか? その場合は、レスキュー中に元の例外を変数にキャプチャする必要があります。これは、次のようにして行われます。

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 番目の例外の後に使用するために、元の例外が保存されています。

于 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 に答える