Menu
Coddy logo textTech

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できますし、そのまま上位へ伝播させることもできます。

challenge icon

チャレンジ

簡単

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。
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

ロジックとフローのすべてのレッスン

自分で練習してみよう: Rubyオンラインコンパイラ