Ruby初心者必見!例外処理の全手順を5つのステップで理解しよう

Ruby例外処理入門ガイドの表紙Ruby
この記事は約11分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればサンプルコードを活用して機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

プログラミングの世界では、思わぬところでエラーや問題が発生することがしばしばあります。

それらを適切に扱うためには、例外処理という技術が必要不可欠です。

この記事では、プログラミング言語Rubyにおける例外処理の基本から応用まで、5つのステップで詳しく解説します。

具体的なコードを交えながら、初心者でも理解しやすいように各ステップを展開していきます。

●Rubyでの例外処理とは

例外処理とは、プログラム中で予期せぬエラーが発生したときに、そのエラーをキャッチし、適切な処置を行うための処理のことを指します。

Rubyでは、この例外処理を行うために、begin、rescue、ensure、retry、raiseといったキーワードが用意されています。

○基本的な例外の種類

Rubyには多くの組み込み例外クラスがあります。

例えば、ZeroDivisionError(ゼロでの除算)、NoMethodError(存在しないメソッドの呼び出し)、TypeError(データ型の不一致)などがそれにあたります。

●例外処理の基本的な手順

Rubyでの例外処理は、主にbeginとrescueを用いて行います。

具体的な手順は次のようになります。

  1. beginの直後に例外が発生する可能性のあるコードを書きます。
  2. rescueの直後には、例外が発生したときに実行するコードを書きます。

この2つの手順により、例外が発生したときの適切な処置を行うことができます。

○サンプルコード1:基本的な例外処理

begin
  # 例外が発生する可能性があるコード
  number = 10 / 0
rescue
  # 例外が発生したときの処理
  puts "ゼロ除算エラーが発生しました。"
end

このコードでは、ゼロでの除算という例外(ZeroDivisionError)を発生させています。

通常、このような操作を行うとプログラムは停止しますが、このコードではrescue以下の処理が実行され、「ゼロ除算エラーが発生しました。」と表示されます。

これにより、例外が発生してもプログラムが停止することなく、適切な処理を行いつつ処理を続行することができます。

●例外の発生と捕捉

プログラムの実行中に発生した例外を適切に捕捉することで、その後の処理を適切にコントロールすることが可能になります。

Rubyでは、rescueを使って特定の例外を捕捉することができます。

また、一つのbegin-rescue-end構文で複数の例外を捕捉することも可能です。

○サンプルコード2:特定の例外の捕捉

begin
  # 例外が発生する可能性があるコード
  number = 10 / 0
rescue ZeroDivisionError
  # ZeroDivisionErrorが発生したときの処理
  puts "ゼロ除算エラーが発生しました。"
end

このコードでは、rescueの後ろにZeroDivisionErrorと指定することで、ゼロでの除算が発生したときに限り、例外を捕捉しています。

つまり、このコードではゼロ除算のエラーのみを捕捉し、その他のエラーについては対応していません。

○サンプルコード3:複数の例外の捕捉

それでは、複数の例外を捕捉するコード例を見てみましょう。

begin
  # 例外が発生する可能性があるコード
  array = [1, 2, 3]
  number = array[5] / 0
rescue ZeroDivisionError
  # ZeroDivisionErrorが発生したときの処理
  puts "ゼロ除算エラーが発生しました。"
rescue NoMethodError
  # NoMethodErrorが発生したときの処理
  puts "存在しないメソッドを呼び出しました。"
rescue IndexError
  # IndexErrorが発生したときの処理
  puts "存在しないインデックスを参照しました。"
end

このコードでは、複数のrescueを用いることで、ZeroDivisionError、NoMethodError、IndexErrorという3種類の例外を捕捉しています。

各例外が発生したときには、それぞれのrescue以下の処理が実行されます。

●例外の発生とその後の処理

Rubyでは、例外が発生したときにその後どのような処理を行うかを制御することが可能です。

再試行(retry)、確実な処理の実行(ensure)、例外の発生(raise)といった手法を用いることで、さまざまな状況に対応することができます。

○サンプルコード4:例外の発生とリトライ

Rubyでは、例外が発生したときに再試行する機能が提供されています。

これはretryというキーワードを使って行います。

retryを使うと、beginからの処理を再度行うことができます。

次に、その動きを体験できるサンプルコードをご紹介します。

begin
  # 例外が発生する可能性があるコード
  number = 10 / 0
rescue ZeroDivisionError
  # ZeroDivisionErrorが発生したときの処理
  puts "ゼロ除算エラーが発生しました。リトライします。"
  number = 10 / 1
  retry
end

このコードでは、ゼロ除算エラーが発生すると、rescue節内でエラーメッセージを表示した後、numberの値を1に修正して再試行を行います。

retryを用いることで、例外が発生した場合でもプログラムの実行を続け、条件を満たすまで何度でも試行を繰り返すことが可能になります。

ただし、このコードをそのまま実行すると無限ループに陥る可能性があるため、通常は再試行回数に制限を設けるなど、リトライの制御が必要となります。

○サンプルコード5:ensureを使用した例外処理

例外が発生しても発生しなくても、必ず実行したい処理がある場合、ensure節を使うことが推奨されます。

ensure節に記述されたコードは、例外の有無に関わらず必ず実行されます。

begin
  # 例外が発生する可能性があるコード
  file = File.open("some_file.txt", "r")
  # ファイルの読み込み処理
rescue
  # 例外が発生したときの処理
  puts "ファイルの読み込みに失敗しました。"
ensure
  # 例外の有無に関わらず実行する処理
  file.close unless file.nil?
  puts "ファイルは確実に閉じられました。"
end

このコードでは、ファイルを開く処理が行われ、その後で例外が発生する可能性があります。

例外が発生した場合でもしない場合でも、ensure節内のファイルクローズ処理が必ず行われることを保証します。

このように、ensureはリソースの開放や後処理など、例外の有無に関わらず確実に実行すべき処理に対して用いられます。

●例外処理の応用例

Rubyの例外処理は非常に柔軟で、独自の例外クラスを作成したり、ファイル操作を安全に行うために利用できます。

ここでは、それらの応用例を具体的なサンプルコードを交えながら解説します。

○サンプルコード6:独自の例外クラスの作成

Rubyでは、標準の例外クラス以外にも、自分でカスタマイズした例外クラスを作成することができます。

独自の例外クラスを作成することで、プログラム内で発生する特定の状況に対して適切に対応することができます。

独自の例外クラスを作成し、それを利用するサンプルコードを紹介します。

# 独自の例外クラスを定義
class MyCustomError < StandardError; end

begin
  # エラーを強制的に発生させる
  raise MyCustomError, "これはカスタムエラーです"
rescue MyCustomError => e
  # 独自の例外クラスが捕捉されたときの処理
  puts "カスタムエラーが捕捉されました: #{e.message}"
end

このコードでは、まずMyCustomErrorという名前の独自の例外クラスを定義しています。

そして、raiseを使用してこの独自の例外を意図的に発生させ、rescue節で捕捉してエラーメッセージを表示しています。

このコードを実行すると、”カスタムエラーが捕捉されました: これはカスタムエラーです”というメッセージが表示されます。

○サンプルコード7:例外処理を活用したファイル操作

ファイル操作は、例外が発生しやすい操作の一つです。

ファイルが存在しない、パーミッションがないなど、さまざまな理由でエラーが発生する可能性があります。

これを例外処理で適切にハンドルすることが重要です。

次のサンプルコードでは、ファイルを読み込む際に例外処理を使用しています。

begin
  # ファイルを開く
  file = File.open("存在しないファイル.txt", "r")
rescue Errno::ENOENT => e
  # ファイルが存在しない場合の処理
  puts "ファイルが見つかりません: #{e.message}"
rescue => e
  # その他のエラーの

処理
  puts "予期しないエラーが発生しました: #{e.message}"
ensure
  # ファイルが開かれていれば、必ず閉じる
  file.close if file
end

このコードでは、存在しないファイルを開こうとしたときにErrno::ENOENTという例外が発生し、そのメッセージが表示されます。

また、ファイルを開いた後は、ensure節を使用して必ずファイルを閉じるようにしています。

これにより、リソースのリークを防ぐことができます。

このコードを実行すると、”ファイルが見つかりません: No such file or directory @ rb_sysopen – 存在しないファイル.txt”というメッセージが表示されます。

●注意点と対処法

例外処理を適切に行うためには、いくつかの重要な注意点と対処法を理解する必要があります。

ここでは、それらを詳しく説明します。

1つ目の注意点は、rescue節で捕捉する例外の範囲です。

rescue節では、何も指定しなければStandardErrorクラスとそのサブクラスの例外を捕捉します。

しかし、あまり広範囲な例外を捕捉すると、意図しないエラーも捕捉してしまう可能性があります。

そのため、可能な限り具体的な例外クラスを指定することが推奨されます。

次に、例外が発生した際にはその情報を適切にログに残すことが重要です。

エラーの原因を追求する際に、エラーメッセージやバックトレース情報が非常に有益です。

下記のサンプルコードは、例外のログ出力の方法を表しています。

begin
  # エラーを強制的に発生させる
  raise "エラーが発生しました"
rescue => e
  # エラーメッセージとバックトレースをログに出力
  puts "エラーが発生しました: #{e.message}"
  puts e.backtrace
end

このコードでは、例外が発生した際にそのエラーメッセージとバックトレースをログに出力しています。

これにより、エラーの詳細な情報を得ることができます。

このコードを実行すると、エラーメッセージとエラーが発生した場所を表すバックトレースが出力されます。

また、例外が発生した場合でも、リソースの解放や後処理は確実に行う必要があります。

Rubyでは、ensure節を使用して、例外の発生に関係なく最後に必ず実行される処理を記述することができます。

最後に、retryを使って例外が発生した処理を再度実行することもできますが、無限ループに陥る可能性があるため注意が必要です。

retryは必要最小限の使用に留め、可能ならばエラーの原因を解消するための適切な処理を行った上で使用するべきです。

まとめ

今回の記事では、Rubyでの例外処理の基本的な概念から応用的な活用方法まで、具体的なコード例を交えながら詳しく解説しました。

例外処理はプログラムの安定性を保つために重要な概念であり、その扱い方を理解することでより良いコードを書くことができます。

まずは、beginとrescueを使って基本的な例外処理を行い、プログラムが予期せぬエラーで停止することなく安定して動作するようにしましょう。

次に、raiseを用いて意図的に例外を発生させ、問題が発生した時に適切な対応を行えるようにします。

さらに、ensureやretryを利用してより高度なエラーハンドリングを行うことが可能です。

また、例外処理の中には独自の例外クラスを作成したり、ファイル操作時に適切に例外処理を行うなど、特定のシーンで有効な応用例も多数存在します。

具体的なコード例を見ながら、その使い方を理解しましょう。

例外処理を行う際の注意点としては、rescue節で捕捉する例外の範囲を適切に設定し、例外が発生した際の情報をログに残すこと、そして、例外の発生に関わらず必ず行われる処理をensure節で記述することが挙げられます。

また、retryを用いて処理を再試行する際には無限ループにならないよう注意が必要です。

これらの基本的な概念から応用的なテクニックまでを理解し、活用することで、Rubyのプログラミングスキルを一段と高めることができるでしょう。

これからも、継続的に学び続け、プログラミングの世界を探求していきましょう。