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

Rubyの例外階層を理解する|Exception継承ツリーとrescueの基本

Rubyにおける例外は、実は単なるクラスです。「例外階層」とは、Exceptionクラスを継承するすべてのクラスで構成される木構造のことを指します。

以下は、Ruby 2.1標準ライブラリにおける例外階層の一覧です。

Exception
  NoMemoryError
  ScriptError
    LoadError
    NotImplementedError
    SyntaxError
  SecurityError
  SignalException
    Interrupt
  StandardError -- rescueのデフォルト
    ArgumentError
      UncaughtThrowError
    EncodingError
    FiberError
    IOError
      EOFError
    IndexError
      KeyError
      StopIteration
    LocalJumpError
    NameError
      NoMethodError
    RangeError
      FloatDomainError
    RegexpError
    RuntimeError -- raiseのデフォルト
    SystemCallError
      Errno::*
    ThreadError
    TypeError
    ZeroDivisionError
  SystemExit
  SystemStackError

階層を覚えるうえでのポイント

  • StandardErrorrescue節で例外クラスを省略した場合のデフォルトの捕捉対象
  • RuntimeErrorraiseで例外クラスを省略した場合のデフォルト
  • NoMemoryErrorSystemExitなどはStandardErrorの外側にあり、通常のrescueでは捕捉されない

実践的な活用方法

例外がクラスツリーとして整理されている最大の理由は、似た種類の例外をまとめて簡単にrescue(捕捉)できるようにするためです。

例えば、次のようなコードを考えてみましょう。

begin
  do_something
rescue StandardError => e
end

このコードはStandardErrorそのものだけでなく、そこから継承されたすべての例外を捕捉します。実務で遭遇するほとんどの例外(NoMethodErrorTypeErrorなど)はStandardErrorの子孫にあたるため、結果として「通常処理すべき例外」をほぼ網羅できることになります。

独自ライブラリでの応用

自作のライブラリやアプリケーションでは、カスタム例外をすべて1つの基底クラスから継承させておくと便利です。

module MyLib

  class Error < StandardError
  end

  class TimeoutError < Error
  end

  class ConnectionError < Error
  end

end

...

begin
  do_something
rescue MyLib::Error => e
  # 上記で定義したすべての例外を一括して捕捉できる
end

この設計により、ライブラリ利用者はMyLib::Errorを1つ指定するだけで、そのライブラリが発生させる可能性のあるすべての例外を捕捉できます。さらに、特定のエラーだけ個別に対応したい場合は、MyLib::TimeoutErrorなどより具体的なサブクラスを先にrescueしておけば、きめ細かいエラーハンドリングが可能になります。

  1. Rubyで学ぶ挿入ソート:仕組みから計算量まで徹底解説

    ※本記事は、Rubyでさまざまなソートアルゴリズムを実装するシリーズの第4回です。第1回ではバブルソート、第2回では選択ソート、第3回ではマージソートを取り上げました。データのソート手法をさまざまな角度から探っていくシリーズもいよいよ折り返し地点。今回は挿入ソート(Insertion Sort)に焦点を当てます。挿入ソートには魅力的な特徴がたくさんあります。まず、挿入ソートは安定(stable)なアルゴリズムです。つまり、同じキーを持つ要素同士の相対的な順序が入れ替わることがありません。また、インプレース(in-place)アルゴリズムでもあるため、ソート結果を保存するための新しい配列を作成す

  2. Rubyのdupとcloneの違いを徹底解説!オブジェクト複製の基礎知識

    Rubyではオブジェクトをコピーできることをご存じでしょうか?しかも、コピー用のメソッドは2種類用意されています。 そのメソッドとは: dup clone それぞれの違いについては後ほど詳しく見ていきますが、まず最初に… そもそもなぜオブジェクトをクローンする必要があるのでしょうか? Rubyの多くのオブジェクトはミュータブル(変更可能)です。つまり、作成した後に内容を書き換えることができます。 元のオブジェクトはそのまま保持しつつ、内容を変更したい場合には、クローン(複製)を作成するのが有効です。 具体例を挙げてみましょう。 「先頭以外のすべての要素を含む配列」が欲しい場面を想定します。