はじめに
今回は例外について改めて勉強しましたので
忘れないように記述していきます。
今回は少しずつ理解して行こうということで第1回目
例外処理とは
コード実行時にエラーが発生したときにする処理のことです。
原因の調査がしやすくなるなどのメリットがあります。
使用するメイン機能
-
begin 例外が起こるであろうコードを指定して処理の問題を検索する。
-
rescue 問題が発生したときに対応する内容を記述する。
-
raise 意図的にエラーを発生したいときに記述する。
-
ensure エラーが発生してもしなくても実行する。
シンプルなものを書く
流れが分かりやすいように"puts" で番号をふっています。
puts 1
begin # エラーが起きそうなところをbeginで囲む
number = 0
answer = 100 / number
puts 2 # ↓ エラーが起きたら対応する内容をrescueに記述
rescue ZeroDivisionError => e # e変数に発生した例外を表すオブジェクトが代入
p e #=> <ZeroDivisionError: divided by 0>
ensure # エラーが発生しても実行する
puts 3
end
puts 4
# 動きは 1 → 3 → 4
(変数は「 e 」 じゃなくても大丈夫。)
例外が発生したらその直後の処理はされずにrescueの処理に飛びます。
**例外ハンドラ**
例外に対応するrescueブロックの部分のこと
rescueの出力は以下のものもあります。("p e
"のところに同様に記述)
記述 | 出力内容 |
---|---|
p "0では割り算できません" (出力したい内容を記述) | "0では割り算できません" |
p e.class | ZeroDivisionError |
p e.class.superclass | StandardError |
p e.message | "divided by 0" |
p e.backtrace | ["exception.rb:23:in /'", "exception.rb:23:in '"] |
STDERR.puts "0ですよ!!" | "0ですよ!!"(標準出力エラーに出力) |
このように記述すると色々な情報を見ることができます。
例外処理の動きを見てみる
呼び出しもとで例外をキャッチできるようにします。
def test_exception(number)
puts 2
begin
puts 3
answer = 100 / number # ここで例外が発生!!
return answer
puts 4
rescue ZeroDivisionError => e
puts 5
raise e
end
puts 6
end
puts 1
begin
answer = test_exception(0)
puts 7
rescue ZeroDivisionError => e
puts 8
p e # 最後に実行される
end
# 動きは 1 → 2 → 3 → 5 → 8 → #<ZeroDivisionError: divided by 0>
発生した例外は呼び出しもとへ自動で伝わります。(戻される)
rescueブロック内でraiseを使用し意図的に発生させ、発生した呼び出し元に戻すことができます。
例外処理の継承関係
たくさんの例外クラスがあります。
こちらに詳細が載っています。 例外クラスリファレンス
参考: 伊藤 淳一. プロを目指す人のためのRuby入門 言語仕様からテスト駆動開発・デバッグ技法まで
例
rescue部分を記述するときに気をつけなくてはいけないことがあります。
begin
number = 0
answer = 100 / number
rescue Exception => e
puts "予期せぬエラーが発生しました"
p e
rescue ZeroDivisionError => e
puts "0ですよ!!"
p e
end
#=> 予期せぬエラーが発生しました
#=> #<ZeroDivisionError: divided by 0>
Exceptionは全てのスーパークラス(親クラス)なので2番目のrescueは実行されずに先にエラーをキャッチし、初めのExceptionのエラー文章を出力します。
...なので思った通りの文章を出力したいときは
rescueの順番に注意!!
まとめ
・・・と、今回はこのような感じで学習しました。
次回はもう少し深掘りしてみたいと思います。