回答:
私はhttp://hasno.info/ruby-gotchas-and-caveatsに違いの適切な説明があると思います:
キャッチ/スローはレイズ/レスキューと同じではありません。catch / throwを使用すると、特定のシンボルに対してcatchが定義されているポイントまでブロックをすばやく終了できます。レイズレスキューは、Exceptionオブジェクトに関連する実際の例外処理です。
raise
があります。非常に高価です。throw
ではありません。ループから抜け出すためにthrow
を使用goto
すると考えてください。
raise
、fail
、rescue
、およびensure
ハンドルエラーとしても知られている、例外throw
そして、catch
されている制御フロー他の言語とは異なり、Rubyのスローとキャッチは例外には使用されません。代わりに、追加の作業が不要になったときに実行を早期に終了する方法を提供します。(グリム、2011)
while
ループのような単一レベルの制御フローの終了は、単純なで実行できますreturn
。ネストされたループのように、制御フローの多くのレベルを終了するには、を使用しthrow
ます。
レイズとレスキューの例外メカニズムは、問題が発生したときに実行を中止するのに最適ですが、通常の処理中に深くネストされた構造からジャンプできるのは良いことです。これは、キャッチとスローが便利になる場所です。(トーマスとハント、2001)
https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raiseは、改善できるとは思えない優れた説明を提供します。要約すると、私が行くにつれてブログの投稿からいくつかのコードサンプルにニックを入れます:
raise
/ rescue
は、他の言語(またはPythonの/ )でおなじみのthrow
/ catch
構造に最も近いものです。エラー状態が発生し、それを別の言語で上書きする場合は、Rubyを使用する必要があります。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"
(またはArgumentError
2.2より前にルビーのバージョンでは)
複数のレスキュー条項をリストすることができます...
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
bare rescue
はrescue StandardError
、慣用的な構成要素と同等であり、慣用的な構成要素です。のcatch
ような「ベア」はcatch() {throw :foo}
何もキャッチせず、使用すべきではありません。
goto
したC / C ++のほかに、Javaはbreakおよびcontinueとラベルを付けました。(Pythonにもこれに対する拒否された提案があります。)