ensureとraise
CoddyのRubyジャーニー「ロジックとフロー」セクションの一部。レッスン 46/56。
エラー処理ツールキットを完成させる要素が、さらに2つあります。
ensureは、beginが正常に終了した場合でも、rescueブランチが例外を捕捉した場合でも、例外が捕捉されなかった場合でさえも、何があっても実行されるブロックです。クリーンアップコードを記述する場所です。
begin
puts "opening file"
raise "something broke"
rescue
puts "caught it"
ensure
puts "closing file"
end
# ファイルを開いています
# キャッチしました
# ファイルを閉じていますraise は独自の例外を作成する方法です。メッセージには文字列を渡すか、クラスとメッセージを渡します。
def withdraw(amount)
raise ArgumentError, "amount must be positive" if amount <= 0
# ... 出金を行う
end引数が間違っている場合に早期に失敗できるよう、メソッドの先頭でraiseするのが慣例です。呼び出し元は、適切な回復処理がある場合はrescueできますし、そのまま上位へ伝播させることもできます。
チャレンジ
簡単safe_divide(a, b)メソッドを定義します。このメソッドは次の処理を行います。
b == 0の場合、メッセージ"b cannot be zero"を付けてArgumentErrorを発生させる- それ以外の場合、
a / bを返す
次に、入力から2つの整数を読み取ります。begin / rescue / ensureの中でsafe_divideを呼び出します。
- 成功した場合、
Result: <value>を出力する ArgumentErrorの場合、Error: <message>を出力するensureでは、常にDone.を出力する
入力が10 / 2の場合、出力は次のようになります。
Result: 5
Done.入力が10 / 0の場合:
Error: b cannot be zero
Done.自分で試してみよう
# TODO: safe_divide(a, b) を定義し、b == 0 のときに ArgumentError を発生させる
a = gets.to_i
b = gets.to_i
# TODO: begin ... Result を print; rescue ArgumentError => e ... Error を print; ensure ... Done を print。
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
ロジックとフローのすべてのレッスン
自分で練習してみよう: Rubyオンラインコンパイラ