Ruby(rails)初心者です。ちょっと不具合出してしまったので、自分への戒めのためにメモっておきます。Rubyのexit
まわりの処理についての話です。
Rubyのバージョン
2.1.1
問題
元のコード
def hoge
if #...
exit
end
rescue Exception
p "rescue"
# なんらかの処理
end
こんな感じのコードがあって、if
内の処理が走ったときにexit
で処理が終了するだろうなんて思い込んでしまっていたのですが、例外がキャッチされていて、rescue
内の想定していない(良くない)処理が実行されていた。
原因
他の記事参考にしつつrails c
なんかで試してみると、以下のコードでは例外がキャッチされない(=rescue
内の処理は実行されない)。
元のコードから'Exception'をとったもの
def hoge
if #...
exit
end
rescue => e # Exceptionの指定をとると
p "rescue" # ここの処理は走らなくなる
# なんらかの処理
end
どうやら型指定なしでrescueすると、StandardError
のサブクラスのみをキャッチする模様。
元のコードで指定していたException
クラスは調べてみると例外の大元の親クラスだった。
で、exit
が発生させる例外クラスはSystemExit
というもので、
-
SystemExit
は当然Exception
のサブクラスである -
SystemExit
は当然StandardError
のサブクラスではない
これでようやく上2つのコードの現象の理屈が通った。
解決
そもそもException
をrescue
で指定すること自体がそもそも良くないのだろうけど、既存のコードでどんな例外発生するか読めず、exit
をexit!
にすることで例外を発生させずに処理を終了できるようなのでそれで対応した。
修正したのコード
def hoge
if #...
exit! # '!'をつけた
end
rescue Exception
p "rescue"
# なんらかの処理
end