update.begin~rescue~ensureとraiseを利用した例外処理の流れと捕捉についてEffectiveRubyの項目23「できる限りもっとも対象の狭い例外を処理できるようにしよう」を読んでいるときに、Rubyにおける例外処理の流れと捕捉について気になったためまとめます。※else節は例外が発生しなかった場合に実行されるため、今回は対象外とします。Rubyにおける例外処理の基本(begin~rescue~end)まずは、Rubyにおける簡単な例外処理について。サンプルコードでは、適当なクラスとインスタンスメソッドを定義し、0での除算を行うことで例外を発生させ、それを捕捉しています。ZeroDivisionError問題なく例外が捕捉されています。今回は捕捉する例外の範囲を狭めており、ZeroDivisionErrorのみの捕捉を行っています。ZeroDivisionErrorはStandardErrorのサブクラスになります。次に、先ほどのコードにZeroDivisionErrorクラスの親クラスであるStandardErrorを追加します。StandardErrorプロンプトには、「StandardError」が表示されます。Rubyでは上から下に向かい処理が実行されるため、発生した例外(今回ならZeroDivisionError)の親クラスであるStandardErrorクラスのrescue節が例外を捕捉し、処理を行った後終了しています。捕捉の順序を逆にするとZeroDivisionErrorのrescue節が実行されます。次に、先ほどのコードにraiseを追加します。raiseは例外を発生させるKernelモジュールのインスタンスメソッドです。`<main>'=endError内容からわかるとおり、raiseが発生した時点で実行中のrescue節が終了し、呼び出し元に戻っています。Rubyは例外が発生した場合、発生した地点から例外が捕捉されるまでスタックをたどり続けます。今回の場合、呼び出し元に例外捕捉の処理を加えます。ZeroDivisionError=endしっかりとスタックをたどり、例外が捕捉されていることがわかります。rescue節内で実行されるraiseメソッドに引数を省略した場合、対象のrescue節の引数と同じオブジェクトが渡されるようです。最後に例外の発生にかかわらず実行されるensureを追加します。ZeroDivisionError=endensure節を追加したことにより処理が行われていますが、raiseにより発生した例外捕捉の前にensure節が実行されています。例外が発生した時点で、呼び出し元に戻るというわけではないようです。else)->ensure捕捉する例外の範囲(例外クラス)はなるべく狭める。raiseによる例外発生は、実行中のrescure節を抜ける。例外を発生させたからといって、その場で処理が終わるわけではない。Rubyにおける例外は例外が捕捉されるまでスタックをたどる。ensure節は必ず最後に実行される。upLoginユーザーは見つかりませんでした。