【Ruby】Ctrl-cの強制停止はrescueで補足できる

zomです。 Rubyのtips二本立てです。 ※2013/09/27追記 ensureはあんまり関係無かったのでensureに関わるタイトルと記事の内容を修正しました

今回もまぁ掲題のとおりでございます。 Unix系においてプログラムの強制終了、停止でCtrl-cを使うことは周知のことかと思いますが Rubyでも実行中にCtrl-cをやることで止めることができます。 ただし、どこまで処理が進んでいるのかわからないので、IOが発生するものはむやみにやるべきではないと思います。

でも、やらざるをえない場合もあると思います。 処理に3時間かかるバッチを間違えて実行しちゃった!3時間も待ってらんね!止まれぇェェ!! みたいな。なにこのテンション。

そこで掲題の話でございます。 百聞は一見にしかず。サンプルソースです。

begin
  sleep 1000
rescue Interrupt
  p 'exec Ctrl-C!'
ensure
  p 'done!'
end
# 'exec Ctrl-C!'
# 'done!'

見ての通りですが、実行すると1000秒待ちます。 「殺人鬼のいる部屋で1000秒も待ってられるか!俺は自分の部屋に戻る!」 と言いながらCtrl-cをするとInterruptが発生します。 rescueで指定しているInterruptはRuby1.9.3では例外クラスの一つとして定義されています。 そのため、rescueで補足できるし、ensureも実行されます。

ただし、rescueでエラータイプを指定しない場合はStandardErrorしか補足されないため、rescue節は実行されません。 というのもInterruptはSignalExceptionという別のクラスに属しているからです。

ということで、デバッグのためにわざわざInterruptを補足する処理を書くのか?いや、書かない(反語)となるようなtipsでした。 とりあえずrescueで補足してロールバックするような処理を書くことは可能、ってことだけ覚えておけばいいのかなー、と思います。

あ、ちなみに「殺人鬼のいる部屋で~」とかいう必要ないですよ。