begin / rescue
CoddyのRubyジャーニー「ロジックとフロー」セクションの一部 — レッスン 44/56。
例外によってプログラムがクラッシュするのを防ぐには、リスクのあるコードを begin ... rescue ... end で囲みます。begin 内で例外が発生した場合、Rubyは処理を中断する代わりに、対応する rescue ブロックにジャンプします。
begin
result = 10 / 0
puts result
rescue ZeroDivisionError
puts "Cannot divide by zero!"
end
# ゼロで割ることはできません!=> e を使用して例外オブジェクト自体を取得し、その .message を読み取ることができます:
begin
Integer("hello")
rescue ArgumentError => e
puts "Bad input: #{e.message}"
end
# Bad input: invalid value for Integer(): "hello"例外クラスを指定しない場合、rescue 単体では StandardError とその子孫(日常的に発生するほとんどの失敗)を捕捉します。捕捉が最も役立つのは、rescue ブロック内で何かを実行できる場合です。例えば、デフォルト値で代用する、問題をログに記録する、ユーザーに再入力を促す、といった処理です。
チャレンジ
簡単入力から2行読み込みます。どちらも整数である必要がありますが、2行目は有効な数値ではない可能性があります。
2行目の解析を begin / rescue で囲んでください:
Integer(input)を使用します(不正な文字列の場合、ArgumentErrorが発生します)- 解析に成功した場合は、
Sum: <a + b>を出力します - 失敗した場合は、
Bad number!を出力します
入力が 3 次に 4 の場合、出力は Sum: 7 です。入力が 3 次に abc の場合、出力は Bad number! です。
チートシート
クラッシュさせずに例外を処理するには、begin ... rescue ... end を使用します:
begin
result = 10 / 0
rescue ZeroDivisionError
puts "Cannot divide by zero!"
end例外オブジェクトを => e でキャプチャして、そのメッセージにアクセスします:
begin
Integer("hello")
rescue ArgumentError => e
puts "Bad input: #{e.message}"
endクラスを指定せずに rescue を使用すると、StandardError とその子孫がキャッチされます。
自分で試してみよう
a = gets.to_i
raw_b = gets.chomp
# TODO: Integer(raw_b) を begin/rescue で囲む。合計または "Bad number!" を出力する。
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。