Hatena::Grouparaistudy

czk-htnの日記

2006-08-01

[] 8. 例外catchとthrow

Rubyの例外処理はJavaに似ている。

8.1 Exceptionクラス

8.2 例外の処理

基本的に下の構造でbegin~rescureの例外が補足される。補足できなかった例外は呼び出しスタックを上にたどり例外ハンドラを検索する。

begin
  # 本処理
  # Javaでいうtryブロック
rescue <例外クラス> => <Exceptionローカル変数>
  # 例外処理
  # Javaでいうcatchブロック
else
  # 例外が発生しなかった場合の処理
ensure
  # 後片付け
  # Javaでいうfinallyブロック
end
  • rescueの引数として補足したいExceptionクラス名を記述する
    • 省略した場合はStandardErrorが使用される
  • Exceptionオブジェクトは$!に格納される
  • raiseで例外を再発生させれば例外を上位レベルに渡せる
  • rescue内でretryするとbeginを再処理できる

retry文ってのはループ以外にも適用できるようだ。

#3回試行してダメなら失敗
tryCount = 0
begin
  tryCount += 1
  puts "Try #{tryCount}"
  file = File.open("/hoge/fuga.txt", "w")
rescue
  retry if tryCount < 3
  puts "Error: #{$!}"
ensure
  puts "Cleaning..."
end
% ruby sample01.rb
Try 1
Try 2
Try 3
Error: No such file or directory - /hoge/fuga.txt
Cleaning...

例外を発生させる

raise文で自身で例外を発生させることもできる。一般的なのは次の3つ。

raise
raise "Error occured"
raise MyExcepton, "#{num} is invalid", caller
  • 例外クラスを指定しない場合はRuntimeErrorとなる
  • 例外クラスを指定する場合は3つ目の構文

8.4 catchとthrow

try~rescueでなく、ラベルによる例外処理も可能。

catch (:label) do
  # 処理
  throw :label if error
end

throwにラベルを指定すると、対応するラベルを持ったcatchブロックを抜ける。goto文みたいなものか。throwはcatchブロック内以外でも指定できるので、システム全体のエラー処理などに用いるのか。

トラックバック - http://araistudy.g.hatena.ne.jp/czk-htn/20060801