0
0

More than 3 years have passed since last update.

[Ruby]例外処理基本

Last updated at Posted at 2020-12-27

はじめに

今回は例外について改めて勉強しましたので
忘れないように記述していきます。
今回は少しずつ理解して行こうということで第1回目:ok_woman:

例外処理とは

コード実行時にエラーが発生したときにする処理のことです。
原因の調査がしやすくなるなどのメリットがあります。

使用するメイン機能

  • 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を使用し意図的に発生させ、発生した呼び出し元に戻すことができます。

例外処理の継承関係

たくさんの例外クラスがあります。

例外処理の継承.png

こちらに詳細が載っています。 例外クラスリファレンス

参考: 伊藤 淳一. プロを目指す人のための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のエラー文章を出力します。


...なので思った通りの文章を出力したいときは


:zap:rescueの順番に注意!!:zap:


まとめ

・・・と、今回はこのような感じで学習しました。

次回はもう少し深掘りしてみたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0