Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubys Exception vs StandardError:違いは何ですか?

「Rubyで例外を救出しないでください!」

たぶんあなたはこれを前に聞いたことがあるでしょう。それは良いアドバイスですが、あなたがすでに知っているのでない限り、それはかなり混乱します。このステートメントを分解して、その意味を見てみましょう。

Rubyでは、次のような例外を救済できることをおそらくご存知でしょう:

begin
  do_something()
rescue => e
  puts e # e is an exception object containing info about the error. 
end

また、エラーのクラス名を指定することで、特定のエラーを救済できます。

begin
  do_something()
rescue ActiveRecord::RecordNotFound => e
  puts e # Only rescues RecordNotFound exceptions, or classes that inherit from RecordNotFound
end

Rubyのすべてのタイプの例外は単なるクラスです。上記の例では、ActiveRecord ::RecordNotFoundは、特定の規則に従うクラスの名前にすぎません。

RecordNotFoundを救出するときは、これは重要です。 、それから継承する例外もすべて救済します。

例外をレスキューしてはいけない理由

Exceptionの救済に関する問題 Exceptionから継承するすべての例外を実際にレスキューするということです 。それは....それらすべてです!

Rubyによって内部的に使用されるいくつかの例外があるため、これは問題です。彼らはあなたのアプリとは何の関係もありません、そしてそれらを飲み込むと悪いことが起こります。

ここにいくつかの大きなものがあります:

  • SignalException ::Interrupt -これを救済すると、control-cを押してアプリを終了することはできません。

  • ScriptError ::SyntaxError -構文エラーを飲み込むということは、puts("Forgot something)のようなものを意味します 黙って失敗します。

  • NoMemoryError -プログラムがすべてのRAMを使い果たした後も実行を続けるとどうなるか知りたいですか?私も。

begin
  do_something()
rescue Exception => e
  # Don't do this. This will swallow every single exception. Nothing gets past it. 
end

これらのシステムレベルの例外を実際に飲み込みたくないと思います。アプリケーションレベルのエラーをすべてキャッチしたいだけです。例外があなたのコードを引き起こしました。

幸いなことに、これを行う簡単な方法があります。

代わりにStandardErrorをレスキュー

気にする必要のあるすべての例外は、StandardErrorから継承します 。これらは私たちの旧友です:

  • NoMethodError -存在しないメソッドを呼び出そうとすると発生します

  • TypeError -1 + ""などが原因

  • RuntimeError -古き良きRuntimeErrorを忘れることができるのは誰ですか?

このようなエラーを救済するには、StandardErrorを救済する必要があります 。次のように書くことでそれを行うことができます:

begin
  do_something()
rescue StandardError => e
  # Only your app's exceptions are swallowed. Things like SyntaxErrror are left alone. 
end

しかし、Rubyはそれをはるかに使いやすくしました。

例外クラスをまったく指定しない場合、rubyはStandardErrorを意味すると想定します。したがって、以下のコードは上記のコードと同じです。

begin
  do_something()
rescue => e
  # This is the same as rescuing StandardError
end
カスタム例外はStandardErrorから継承する必要があります

では、独自のカスタム例外を作成している場合、これはどのような意味がありますか?

これは、常にStandardErrorから継承する必要があることを意味します 、およびExceptionからは絶対にしないでください 。例外からの継承は、予想されるレスキューの動作を損なうため、悪いことです。人々は、すべてのアプリケーションレベルのエラーを救済していると思いますが、あなたのエラーはそのまま進みます。

class SomethingBad < StandardError
end

raise SomethingBad
例外ツリー

Rubyの例外はクラス階層に実装されているため、Rubyのレイアウトを確認すると役立つ場合があります。以下は、Rubyの標準ライブラリに付属している例外クラスのリストです。 railsのようなサードパーティの宝石はこのチャートに追加の例外クラスを追加しますが、それらはすべてこのリストのいくつかのクラスから継承します。

Exception
 NoMemoryError
 ScriptError
   LoadError
   NotImplementedError
   SyntaxError
 SignalException
   Interrupt
 StandardError
   ArgumentError
   IOError
     EOFError
   IndexError
   LocalJumpError
   NameError
     NoMethodError
   RangeError
     FloatDomainError
   RegexpError
   RuntimeError
   SecurityError
   SystemCallError
   SystemStackError
   ThreadError
   TypeError
   ZeroDivisionError
 SystemExit
 fatal

  1. OneDrive と OneDrive for Business の違いは?

    Microsoft の OneDrive クラウド ストレージ サービスを使用すると、どこにいてもファイルにアクセスできます。同社は、実際には 2 つの異なるが名前が似ている OneDrive のバージョンを維持しています。 OneDrive を使用するか、別の OneDrive for Business を使用するかは、クラウドに保存する内容と、それにアクセスする方法によって異なります。 「OneDrive」は、マイクロソフトのコンシューマ向けクラウドです。個人の Outlook アカウントに表示され、Windows 10 に自動的にリンクされます。OneDrive は、自分自身や友人や家

  2. Windows 10 Home と Pro の違いは?

    新しいデバイスを検討している場合でも、自分で Windows を購入する場合でも、Windows 10 Home と Pro の違いに注意することをお勧めします。どちらも表示されていない場合は、製品に Windows 10 Home が付属していると想定してください。 「ホーム」エディションは「Windows 10 Standard」というより適切なタイトルにすることができるという点で、ネーミングはおそらく少し役に立たない.これは、価格が 1,000 ポンド未満のほとんどの Windows デバイスに搭載されており、オペレーティング システムのコア機能がすべて含まれています。 Pro ディ