はじめに
Rubyにおける例外処理では、begin ... ensure
構文を使って、例外の発生にかかわらず必ず実行されるコードを記述できます。しかし、return
を省略した場合にensure
節の値が返り値として評価されないという特性があります。
ensure
節の基本動作
Rubyのensure
節は、begin
ブロック内の処理が正常に完了した場合でも例外が発生した場合でも、必ず実行されることを保証します。
以下は、ensure
節の基本的な例です:
def example_method
begin
puts 'Doing some work'
42
ensure
puts 'Cleaning up'
99
end
end
puts example_method
このコードの出力は以下のようになります:
Doing some work
Cleaning up
42
ensure
節の中で99
を評価していますが、この値は返り値には影響しません。代わりに、begin
ブロック内で最後に評価された値(この場合は42
)が返されます。
Rubyは言語仕様として、ensure節の評価値を無視するようになっています。
begin式全体の評価値は、本体/rescue節/else節のうち最後に評価された文の値です。また各節において文が存在しなかったときの値はnilです。いずれにしてもensure節の値は無視されます。
回避策
変数を利用する
def example_with_variable
result = nil
begin
result = 10
ensure
puts 'Cleaning up'
end
result
end
puts example_with_variable
出力:
Cleaning up
10
まとめ
Rubyでは、ensure
節の評価結果がメソッドの返り値に影響しない設計になっています。この仕様を理解していないと、意図しないバグが発生する可能性があります。
-
ensure
節は、例外の発生有無にかかわらず実行される -
ensure
節の中で評価された値は返り値として使用されない
参考