Ruby(rails)初心者です。ちょっと不具合出してしまったので、自分への戒めのためにメモっておきます。Rubyのexitまわりの処理についての話です。
Rubyのバージョン
2.1.1
問題
def hoge
if #...
exit
end
rescue Exception
p "rescue"
# なんらかの処理
end
こんな感じのコードがあって、if内の処理が走ったときにexitで処理が終了するだろうなんて思い込んでしまっていたのですが、例外がキャッチされていて、rescue内の想定していない(良くない)処理が実行されていた。
原因
他の記事参考にしつつrails cなんかで試してみると、以下のコードでは例外がキャッチされない(=rescue内の処理は実行されない)。
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