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
階層を覚えるうえでのポイント
StandardError:rescue節で例外クラスを省略した場合のデフォルトの捕捉対象RuntimeError:raiseで例外クラスを省略した場合のデフォルトNoMemoryErrorやSystemExitなどはStandardErrorの外側にあり、通常のrescueでは捕捉されない
実践的な活用方法
例外がクラスツリーとして整理されている最大の理由は、似た種類の例外をまとめて簡単にrescue(捕捉)できるようにするためです。
例えば、次のようなコードを考えてみましょう。
begin
do_something
rescue StandardError => e
end
このコードはStandardErrorそのものだけでなく、そこから継承されたすべての例外を捕捉します。実務で遭遇するほとんどの例外(NoMethodErrorやTypeErrorなど)は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しておけば、きめ細かいエラーハンドリングが可能になります。
-
Rubyで学ぶ挿入ソート:仕組みから計算量まで徹底解説
※本記事は、Rubyでさまざまなソートアルゴリズムを実装するシリーズの第4回です。第1回ではバブルソート、第2回では選択ソート、第3回ではマージソートを取り上げました。データのソート手法をさまざまな角度から探っていくシリーズもいよいよ折り返し地点。今回は挿入ソート(Insertion Sort)に焦点を当てます。挿入ソートには魅力的な特徴がたくさんあります。まず、挿入ソートは安定(stable)なアルゴリズムです。つまり、同じキーを持つ要素同士の相対的な順序が入れ替わることがありません。また、インプレース(in-place)アルゴリズムでもあるため、ソート結果を保存するための新しい配列を作成す
-
Rubyのdupとcloneの違いを徹底解説!オブジェクト複製の基礎知識
Rubyではオブジェクトをコピーできることをご存じでしょうか?しかも、コピー用のメソッドは2種類用意されています。 そのメソッドとは: dup clone それぞれの違いについては後ほど詳しく見ていきますが、まず最初に… そもそもなぜオブジェクトをクローンする必要があるのでしょうか? Rubyの多くのオブジェクトはミュータブル(変更可能)です。つまり、作成した後に内容を書き換えることができます。 元のオブジェクトはそのまま保持しつつ、内容を変更したい場合には、クローン(複製)を作成するのが有効です。 具体例を挙げてみましょう。 「先頭以外のすべての要素を含む配列」が欲しい場面を想定します。