Rubyにおける終了

スクリプトを途中で止めたいときにどうすればいいか分からなくて困ったことがあったのでKernel.#exitをメモ。

exit(status = true) -> ()


Rubyプログラムの実行を終了します。status として整数が与えられた場合、その値を Ruby コマンドの終了ステータスとします。 デフォルトの終了ステータスは 0(正常終了)です。
status が true の場合 0、 false の場合 1 を引数に指定したとみなされます。この値はCレベルの定数 EXIT_SUCCESS、EXIT_FAILURE の値なので、正確には環境依存です。
exit は例外 SystemExit を発生させることによってプログラムの実行を終了させますので、 必要に応じて begin 節(引用註:begin; 〜; exit; rescue SystemExit => err; err〜)で捕捉することができます。
module function Kernel.#exit (Ruby 1.9.3)

仲間にKernel.#exit!Kernel.#abortがある。仲間は両方とも異常終了。

終了処理を行いたい場合

Kernel.#exit!以外で終了した場合には、Kernel.#at_exitやENDブロックで登録した終了処理を実施してから終了する。

module function Kernel.#at_exit


at_exit { ... } -> Proc
与えられたブロックをインタプリタ終了時に実行します。
at_exitがメソッドである点を除けば、END ブロックによる終了処理の登録と同等です。登録した処理を取り消すことはできません。 終了処理も参照してください。
module function Kernel.#at_exit (Ruby 1.9.3)

終了処理(るりま)

Rubyスクリプトの終端に達した場合や捕捉していない例外が発生した場 合に終了します(関数 Kernel.#exit や Kernel.#abort 、メインスレッドに対する Thread.kill などは SystemExit 例外を発生させます)。終了時には以下 の処理が順に実行されます。

  1. すべてのスレッドを Thread.kill する。
  2. Ruby の疑似シグナル SIGEXIT のハンドラが登録されていればそれを実 行する(Kernel.#trap を参照)。
  3. 制御構造/END ブロック(END { ... } または関数 Kernel.#at_exit で指定したブロック)が登録されていれば、 そのブロックを登録とは逆順に実行する。このブロックの実行中に発生 した大域脱出はそのブロックの処理を中断するが。スクリプトはまだ終 了しない。
  4. ObjectSpace.#define_finalizer により、ファイナ ライザが登録されていればそれらを実行する。実行順序は不定。 ファイナライザ実行中に発生した大域脱出はそのファイナライザの処理 を中断するが、スクリプトはまだ終了しない。
  5. exit(3) により終了する。 このとき渡される終了ステータス値は終了方法によります。 例えば、

スクリプトの終端に達した場合は 0
・Kernel.#exit に渡した引数
・SystemExit による例外以外は 1
関数 Kernel.#exit! による終了は、_exit(2) を実行するだけで、上記の処理はいずれも行われません
終了処理 (Ruby 1.9.3)

スクリプトに埋め込んだ binding.pry でデバッグに入ったpryで、スクリプトごと終了する場合にも exit! は有効ですね。