5
x = StandardError.new(:hello)
y = StandardError.new(:hello)
x == y # => true
x === y # => true

begin
  raise x
rescue x
  puts "ok" # gets printed
end

begin
  raise x
rescue y
  puts "ok" # doesn't get printed
end

2番目の「ok」が印刷されないのはなぜですか?私はそれを理解することはできません。ここで、rubyが===演算子を使用して例外をレスキュー句に一致させることを読みましたが、表面上はそうではありません。

Ruby1.9.3を使用しています

編集:それで、それをした後のように見えますraise xx == yそしてx === yもはや保持しません。これは、同じバックトレースがなくなっxたためと思われます。y

4

4 に答える 4

3

これはバグであり、Ruby1.9の仕様が不足していると思います。Ruby2.0は

TypeError: class or module required for rescue clause

8行目と14行目。

raiseは、必ずしもあなたが思っていることをするわけではないことに注意してください。オブジェクトを作成する場合raise、実際にはそのオブジェクトを作成するのではなく、次の単純なルールに従って渡したオブジェクトから構築された新しいオブジェクトを作成します。

  • オブジェクトが応答する場合は、オブジェクトをexception呼び出しexceptionて戻り値を上げます
  • オブジェクトがのサブクラスである場合はException、呼び出しnewて戻り値を上げます
  • そうでなければ失敗します
  • 上記のメソッドのいずれかの戻り値が次のインスタンスでない場合も失敗しますException

だから、あなたは実際に育てているのではなくx、あなたは育てているのx.exceptionです。ただし、のドキュメントによるとException#exception x.exceptionですx

于 2012-12-04T20:07:16.737 に答える
1

テーブルに何かを追加したいだけです:OPコードは、2つの例外が同じであることを示唆していますが、そうではありません-さらに、OPの意味を説明したい:

したがって、raise x を実行した後、x == y と x === y が成り立たなくなったようです。x と y が同じバックトレースを持たなくなったためと思われます。

 x = StandardError.new(:hello)
 y = StandardError.new(:hello)
 class Object
   def all_equals(o)
     ops = [:==, :===, :eql?, :equal?]
     Hash[ops.map(&:to_s).zip(ops.map {|s| send(s, o) })]
   end
 end

 puts x.all_equals y # => {"=="=>true, "==="=>true, "eql?"=>false, "equal?"=>false}

 begin
   raise x
 rescue
   puts "ok" # gets printed
 end

 puts x.all_equals y # => {"=="=>false, "==="=>false, "eql?"=>false, "equal?"=>false}
于 2012-12-04T21:04:24.393 に答える
0

編集:私の回答が間違っていると思うので、今後の回答の問題を明確にするために、ここでの微妙な点は、クラスxyはなくインスタンスであり、通常はステートメントでクラスを使用することです。raise


意図した動作が 2 番目のレスキューで印刷することである場合、yはうまくいきません。クラス の例外を発生さxせていますが、 を処理するレスキュー句がありませんxStandardErrorただし、共通の基本クラスであるをキャッチすると、2 番目のブロックに "ok" が表示されます。

begin
  raise x
rescue StandardError
  puts "ok"
end

#=== に関しては、発生させるときに、クラスとしてではなくインスタンスを扱っていることが問題だと思います。xx

于 2012-12-04T18:13:01.557 に答える
0

レスキューの定義は次のようです。

[rescue [error_type [=> var],..]

厳密にはどちらxでもありません。これらはエラー タイプのインスタンスです。あなたが実際に実行している方法で有効なコードを実行しているとは思いません。yerror_type

実行する場合:

begin
  raise x
rescue y.class
  puts "ok"
end

その後、期待どおりに動作します。

x == yまた、Ruby 1.8 では noもx === y返さないことにも注意してくださいtrue

于 2012-12-04T18:25:01.563 に答える