Ruby には、Throw/Catch と Raise/Rescue という 2 つの異なる例外メカニズムがあります。
なぜ2つあるのですか?
一方を使用し、もう一方を使用しないのはいつですか?
raise
、fail
、rescue
、およびensure
ハンドルエラー(例外とも呼ばれる)throw
とcatch
は制御フローです他の言語とは異なり、Ruby の throw と catch は例外に使用されません。代わりに、それ以上の作業が不要になったときに実行を早期に終了する方法を提供します。(グリム、2011)
ループのような単一レベルの制御フローを終了するにwhile
は、単純なreturn
. ネストされたループのように、多くのレベルの制御フローを終了するには、throw
.
レイズとレスキューの例外メカニズムは、問題が発生したときに実行を放棄するのに最適ですが、通常の処理中に深くネストされた構造から飛び出すことができると便利な場合があります。ここでキャッチアンドスローが役に立ちます。(トーマスとハント、2001)
http://hasno.info/ruby-gotchas-and-caeatsには、違いの適切な説明があると思います。
キャッチ/スローはレイズ/レスキューと同じではありません。キャッチ/スローを使用すると、特定のシンボルに対してキャッチが定義されているポイントまでブロックをすばやく終了できます。レイズ レスキューは、Exception オブジェクトに関連する実際の例外処理です。
https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raiseは、私が改善できるとは思えない優れた説明を提供しています。要約すると、ブログ投稿からいくつかのコード サンプルを抜粋します。
raise
/は、他の言語 (または Python の/ )で使い慣れた/コンストラクトrescue
に最も近い類似物です。エラー状態に遭遇し、別の言語でそれを上書きする場合は、Ruby を使用する必要があります。throw
catch
raise
except
throw
raise
Ruby のthrow
/を使用すると、実行を中断して( /のように)catch
を探してスタックを上ることができますが、実際にはエラー状態を想定したものではありません。これはめったに使用されるべきではなく、「対応するものが見つかるまでスタックを上る」動作が、作成しているアルゴリズムにとって意味があるが、エラーに対応すると考えるのは意味がない場合にのみ存在します。調子。catch
raise
rescue
catch
throw
Rubyでキャッチアンドスローは何に使用されますか? throw
/catch
コンストラクトの適切な使用法についていくつかの提案を提供します。
それらの間の具体的な動作の違いは次のとおりです。
rescue Foo
Foo
のサブクラスを含むインスタンスをレスキューしますFoo
。は同じオブジェクトcatch(foo)
のみをキャッチします。クラス名を渡してそのインスタンスをキャッチできないだけでなく、等値比較もできません。例えばFoo
catch
catch("foo") do
throw "foo"
end
UncaughtThrowError: uncaught throw "foo"
(または2.2ArgumentError
より前のバージョンの Ruby では)
複数のレスキュー節をリストできます...
begin
do_something_error_prone
rescue AParticularKindOfError
# Insert heroism here.
rescue
write_to_error_log
raise
end
複数のcatch
es をネストする必要がありますが...
catch :foo do
catch :bar do
do_something_that_can_throw_foo_or_bar
end
end
裸rescue
は と同等でrescue StandardError
あり、慣用的な構造です。のような「ベアcatch
」は、catch() {throw :foo}
何もキャッチしないため、使用しないでください。