違いは何ですか-技術的、哲学的、概念的、またはそうでなければ-
raise "foo"
そして
raise Exception.new("foo")
?
技術的には、最初は"foo"
に設定されたメッセージでRuntimeErrorを発生させ、2番目は"foo"
に設定されたメッセージで例外を発生させます。
実際には、前者を使用する場合と後者を使用する場合との間には大きな違いがあります。
簡単に言えば、おそらくRuntimeError
ではなくException
が必要でしょう。引数なしのレスキューブロックはRuntimeErrors
をキャッチしますが、Exception
sはキャッチしません。したがって、コードでException
を発生させた場合、このコードはそれをキャッチしません。
begin
rescue
end
Exception
をキャッチするには、これを行う必要があります。
begin
rescue Exception
end
これは、ある意味で、Exception
はRuntimeError
よりも「悪い」エラーであることを意味します。回復するには、さらに多くの作業を行う必要があるためです。
したがって、どちらを望むかは、プロジェクトのエラー処理方法によって異なります。たとえば、デーモンでは、メインループに空白のレスキューがあり、RuntimeErrors
をキャッチしてレポートし、続行します。しかし、1つまたは2つの状況では、デーモンが実際にエラーで死ぬことを望みます。その場合、Exception
を発生させます。これは、「通常のエラー処理コード」をそのまま通過します。
繰り返しますが、ライブラリコードを記述している場合は、RuntimeError
ではなくException
が必要です。これは、空白のrescue
ブロックはキャッチできず、その理由を理解するには少し時間がかかります。
最後に、RuntimeError
はStandardError
クラスのサブクラスであり、実際のルールはraise
any typeオブジェクトの場合、空白のrescue
はデフォルトでStandardError
から継承したもののみをキャッチします。それ以外はすべて具体的でなければなりません。
raise
raise( string )
raise( exception [, string [, array ] ] )
引数なしで、$!
で例外を発生させるか、$!
がnilの場合にRuntimeError
を発生させます。単一のString
引数を使用すると、文字列をメッセージとしてRuntimeError
を生成します。それ以外の場合、最初のパラメーターはException
クラス(または例外を送信したときにException
を返すオブジェクト)の名前にする必要があります。オプションの2番目のパラメーターは、例外に関連付けられたメッセージを設定し、3番目のパラメーターはコールバック情報の配列です。例外は、begin...end
ブロックのレスキュー句によってキャッチされます。
raise "Failed to create socket"
raise ArgumentError, "No parameters", caller