山傘のプログラミング勉強日記

プログラミングに関する日記とどうでもよい雑記からなるブログです。

プロを目指す人のためのRuby入門 その17

第9章 例外処理を理解する

前回に引き続き例外処理について学びます。

rescue 節と継承関係

rescue 節が複数あるとき、上から順番に例外クラスにエラーがマッチするかどうかを調べるので、指定した例外クラスの順番によって補足されない例外クラスが存在する可能性があります。

begin
  # NoMethodError
  'aaa'.foo
rescue NameError => e
  puts "NameError"
  puts "#{e.class}" # NoMehodError
rescue NoMethodError
  puts "NoMethodError"
end
# => NameError

begin
  # NoMethodError
  'aaa'.foo
rescue NoMethodError
  puts "NoMethodError"
rescue NameError
  puts "NameError"
end
# => NoMethodError

NoMethodError クラスは NameError クラスのサブクラスなので、スーパークラスよりもサブクラスを前にする必要があります。

retry

retry で begin 節をもう一度実行することができます。

retry_count = 0
begin
  puts "処理開始"
  1 / 0
rescue
  retry_count += 1;
  if retry_count <= 3
    puts "retry #{retry_count} 回目の処理"
    retry
  else
    puts "retry に失敗"
  end
end

raise メソッド

コードの中で意図的に例外を発生させるときに、raise メソッドを使います。

def color_of_food(food)
  case food
  when :apple
    'red'
  when :orange
    'orange'
  else
    raise ArgumentError.new("無効な食べ物です。#{food}")
  end
end

puts color_of_food(:orange)
puts color_of_food(:grape)