1. ホーム
  2. ruby

[解決済み] raise "foo"`と`raise Exception.new("foo")` の違いは何ですか?

2022-11-21 15:16:41

質問

技術的、哲学的、概念的、あるいはその他の点で、次のような違いがありますか。

raise "foo"

raise Exception.new("foo")

?

どのように解決するのですか?

技術的には、最初のものは RuntimeError を発生させ、メッセージは次のように設定されます。 "foo" に設定されたメッセージでExceptionを発生させ、2つ目は "foo" .

実務的には、前者を使いたいときと、後者を使いたいときとでは、かなりの差があります。

簡単に言えば、おそらくあなたは RuntimeError ではなく Exception . 引数のないレスキューブロックは RuntimeErrors は捕捉されますが Exception s. ですから、もし Exception を発生させても、このコードはそれを捕捉しません。

begin
rescue
end

をキャッチするために Exception をキャッチするためには、このようにする必要があります。

begin
rescue Exception
end

これは、ある意味で Exception よりも悪いエラーであるということです。 RuntimeError というのは、そこから回復するために、より多くの作業をしなければならないからです。

つまり、どちらを選ぶかは、プロジェクトがどのようにエラー処理を行うかによります。例えば、私たちのデーモンでは、メインループに空白のレスキューがあり、そこで RuntimeErrors をキャッチし、それらを報告し、そして継続します。しかし、1つか2つの状況では、デーモンが本当に本当にエラーで死ぬことを望みます。そして、その場合、私たちは Exception を発生させ、それは私たちのquot;通常のエラー処理コード"を通過して外に出ます。

また、ライブラリコードを書いている場合は、おそらく RuntimeError ではなく Exception というエラーが発生すると、ライブラリのユーザは驚くでしょう。 rescue ブロックでは捕捉できないようなエラーが発生した場合、ユーザーは驚くでしょうし、その理由を理解するのに時間がかかるでしょう。

最後に言っておきますが RuntimeError のサブクラスである StandardError クラスのサブクラスであり、実際のルールとしては raise 任意の はオブジェクトのタイプ、空白は rescue を継承するものだけを捕捉します。 StandardError . それ以外はすべて特定する必要があります。