Rubyのプログラムで処理を終了させたい場合「exit」が利用出来ます。
今回はexitの基本的な使い方から似た処理である「return」「exit!」との違いまで、サンプルコードを掲載しながらご紹介していきます。
Rubyのexitって何?
Rubyでは「exit」と記述することで、exit以降に記述されたプログラムを例外処理を除いて終了させることが出来ます。
記述方法
記述方法は処理を終了させたい部分にexitと記述するだけです。
def sample1 puts "サンプル1の出力" exit end def sample2 puts "サンプル2の出力" end def sample3 puts "サンプル3の出力" end sample1 sample2 sample3
実行結果
$ruby sample.rb サンプル1の出力
サンプルではsample1~3の処理を呼び出そうとしていますが、sample1の処理内部でexitが記述されているためsample2と3が呼び出される前に処理が強制終了されてしまっています。
sample1のexitを削除して実行してみると下記のような結果となります。
$ruby sample.rb サンプル1の出力 サンプル2の出力 サンプル3の出力
例外時のサンプル
exitでは「SystemExit」を発生させることにより、プログラムを終了させています。
つまり「rescue」でSystemExitのエラーをキャッチすることで、exit実行後も例外処理に関しては処理が実行されます。
def sample1 puts "サンプル1の出力" exit puts "サンプル1の2つ目の出力" rescue SystemExit puts "サンプル1からエラー時の処理を出力" end sample1
実行結果
$ruby sample.rb サンプル1の出力 サンプル1からエラー時の処理を出力
ただしここで注意しておかなければいけないポイントがあります。
exitに例外処理を記述する際の注意点
もしSystemExitでエラーをキャッチした場合には、exitによるプログラム終了処理自体が中断されることになります。
最初にご紹介したサンプルのように、後続処理が実装されている場合の例を確認してみましょう。
def sample1 puts "サンプル1の出力" exit puts "サンプル1の2つ目の出力" rescue SystemExit puts "サンプル1からエラー時の処理を出力" end def sample2 puts "サンプル2の出力" end def sample3 puts "サンプル3の出力" end sample1 sample2 sample3
実行結果
$ruby sample.rb サンプル1の出力 サンプル1からエラー時の処理を出力 サンプル2の出力 サンプル3の出力
sample1のexitが例外処理として吸収されたことにより、後続処理のsample2、sample3の処理が実行されることになります。
exitとexit!は何が違うの?
exitの使い方についてご紹介してきましたが、「exit」と記述されているプログラムと「exit!」と記述されているプログラムの違いについては把握出来ているでしょうか?
両者の違いは「exit」が上述したように例外処理を実施するのに対し、「exit!」では例外処理が記述されていたとしても強制的にプログラムを終了してしまう点が異なります。
サンプルコードをexit!に書き換えてみよう
exitの動作確認で利用したサンプルコードを「exit!」に書き換えて実行してみましょう。
def sample1 puts "サンプル1の出力" exit! puts "サンプル1の2つ目の出力" rescue SystemExit puts "サンプル1からエラー時の処理を出力" end def sample2 puts "サンプル2の出力" end def sample3 puts "サンプル3の出力" end sample1 sample2 sample3
実行結果
$ruby sample.rb サンプル1の出力
今回は例外処理の記述に関係なく、強制的に「exit!」の処理が実行された時点でプログラムが終了しました。
exitとreturnはどう使い分ける?
もう1つ「exit」似た処理として「return」の存在が挙げられます。
両者の違いはexitがプログラム自体を終了させるのに対し、returnでは実行中の処理を中断し、呼び出し元に特定の値とセットで返却する役割を担う点です。
exitのサンプルをreturnで書き直してみる
exitのサンプルをreturnで記述し直して動作確認してみましょう。
def sample1 puts "サンプル1の出力" return puts "サンプル1の2つ目の出力" rescue SystemExit puts "サンプル1からエラー時の処理を出力" end def sample2 puts "サンプル2の出力" end def sample3 puts "サンプル3の出力" end sample1 sample2 sample3
実行結果
$ruby sample.rb サンプル1の出力 サンプル2の出力 サンプル3の出力
sample1が呼び出され1つ目のputs処理が実行された後、return処理によりsample1の処理を抜け、後続処理のsample2・sample3が実行されています。
returnではSystemExitのエラーを発生させているわけではないため、rescueの例外処理は実施されていません。
returnで返却値を指定する
returnでは返却値を指定することも可能なため、exitのように単純に処理を中断させる以外の使い方も可能です。
def sample1 puts "サンプル1の出力" return "テスト" end def sample2 puts "サンプル2の出力" return end puts sample1 puts sample2
実行結果
$ruby sample.rb サンプル1の出力 テスト サンプル2の出力
sample1とsample2をそれぞれ呼び出した上で、返却値をコンソール出力しています。
sample1ではreturnに設定した「テスト」の値が出力されているのに対し、sample2ではreturnに値を設定していないため「nil」となり空白表示となります。
メイン処理内でreturnを定義する
最後にメイン処理でreturnを定義した場合にはどうなるのか確認してみましょう。
def sample1 puts "サンプル1の出力" end def sample2 puts "サンプル2の出力" end sample1 return sample2
実行結果
$ruby sample.rb サンプル1の出力
メイン処理では呼び出し元となる処理が存在しないため、実質exitのようにプログラムを終了させる挙動と同じ処理結果となります。
さいごに: exitを始めとしたRubyの終了処理をきちんと使い分けよう!
本記事では、Rubyプログラムでの「exit」の使い方と似た処理である「exit!」と「return」との違いについてご紹介してきました。
処理を中断させるという意味では同じですが、各処理内容を把握しておかないと思わぬバグを生み出してしまう危険性があります。
それぞれの役割をしっかりと認識した上で、適切な処理を選択出来るように学習しておきましょう。
例外処理としてキャッチすればプログラムが終了すると思い込んでしまうミスは多いので、注意しておきましょう。