Ruby初心者でも安心、rescueの活用法10選 – Japanシーモア

Ruby初心者でも安心、rescueの活用法10選

Rubyプログラミングのためのコード画面Ruby
この記事は約12分で読めます。

 

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

このサービスは複数のSSPによる協力の下、運営されています。

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

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

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

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

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

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

はじめに

この記事を読むと、プログラミング言語Rubyにおける例外処理、特に「rescue」の活用法について理解することができます。

例外処理は、プログラム実行中に起こりうるエラーに対して、事前に予測し対策を打つための重要な手段です。

Rubyのrescueを活用すれば、より堅牢なコードを書くことが可能になります。

●Rubyとは

Rubyは、まつもとゆきひろ氏によって開発された高水準のプログラミング言語です。

シンプルでありながらもパワフル、それでいて読みやすく書きやすいという特徴を持っています。

そのため、Web開発やシステム開発の現場で幅広く活用されています。

●例外処理とは

例外処理とは、プログラム実行中に想定外の事象(例外)が発生したときの対処法をあらかじめ定義しておくことを指します。

これにより、エラーによるプログラムの中断を防ぎ、適切な処理を行うことが可能となります。

●rescueの基本的な使い方

Rubyで例外処理を行うには、beginとrescueを使用します。

具体的なコードを見ていきましょう。

○サンプルコード1:基本的なrescueの使用法

begin
  # 例外が発生する可能性がある処理
  1 / 0
rescue
  # 例外が発生したときの処理
  puts "エラーが発生しました!"
end

このコードでは、0で除算しようとすると通常エラーが発生します。

しかし、このエラーをrescueでキャッチし、エラーメッセージを表示することでプログラムの途中終了を防いでいます。

このコードを実行すると、次の結果が出力されます。

エラーが発生しました!

このように、rescueは発生した例外を捉えてエラー処理を行うことができます。

初心者の方でも容易に使うことができるため、Rubyを学び始めたばかりの方でも安心です。

●rescueの応用

Rubyのrescueは基本的な例外処理だけでなく、より具体的なエラーハンドリングにも対応しています。

具体的な応用方法をいくつか見ていきましょう。

○サンプルコード2:begin-rescue-endを用いた例外処理

def divide(x, y)
  begin
    x / y
  rescue ZeroDivisionError
    puts "ゼロで割ることはできません!"
  end
end

divide(1, 0)

このコードでは、ゼロでの割り算を試みるとZeroDivisionErrorが発生します。

このZeroDivisionErrorをrescueでキャッチし、エラーメッセージを表示しています。

ここでは、begin-rescue-endの構文をメソッド内で使用している点がポイントです。

このコードを実行すると、次の結果が出力されます。

ゼロで割ることはできません!

○サンプルコード3:rescueによる特定のエラーハンドリング

def divide(x, y)
  x / y
rescue ZeroDivisionError => e
  puts "#{e.class} : #{e.message}"
end

divide(1, 0)

このコードでは、例外オブジェクトを捕捉し、そのクラス名とメッセージを出力しています。

このように、rescueを使用すれば特定のエラー情報を得ることも可能です。

このコードを実行すると、次の結果が出力されます。

ZeroDivisionError : divided by 0

このように、rescueを使って特定のエラー情報を得ることで、エラーの原因をより詳しく把握しやすくなります。

○サンプルコード4:rescueとretryを組み合わせた使い方

def divide(x, y)
  begin
    x / y
  rescue ZeroDivisionError
    puts "ゼロで割ることはできません! yの値を1に設定し再計算します。"
    y = 1
    retry
  end
end

divide(1, 0)

このコードでは、ゼロでの割り算が試みられたときにZeroDivisionErrorが発生します。

この例外を捕捉し、yの値を1に変更した後、再度計算を行うようにretryしています。

このコードを実行すると、次の結果が出力されます。

ゼロで割ることはできません! yの値を1に設定し再計算します。

そして再計算が行われます。

このように、rescueとretryを組み合わせることで、エラーが発生した場合に特定の処理を行い、再度試行することが可能となります。

●rescueと他の例外処理キーワード

rescueはRubyの例外処理の基本ですが、他のキーワードと組み合わせることでより柔軟なエラーハンドリングが可能になります。

それではelseやensureといったキーワードとどのように組み合わせるのか、具体的なサンプルコードを見ていきましょう。

○サンプルコード5:rescueとelseを組み合わせた使い方

def divide(x, y)
  begin
    result = x / y
  rescue ZeroDivisionError
    puts "ゼロで割ることはできません!"
  else
    puts "計算結果は #{result} です。"
  end
end

divide(4, 2)

このコードでは、begin節で正常に処理が行われればelse節が実行されます。

ここでは、例外が発生しない場合に計算結果を表示するようにしています。

このコードを実行すると、次の結果が出力されます。

計算結果は 2 です。

このように、rescueとelseを組み合わせることで、エラーが発生しなかった場合の処理も設定することが可能です。

○サンプルコード6:rescueとensureを組み合わせた使い方

def divide(x, y)
  begin
    x / y
  rescue ZeroDivisionError
    puts "ゼロで割ることはできません!"
  ensure
    puts "計算を終了します。"
  end
end

divide(1, 0)

このコードでは、begin節の中でエラーが発生しようとしなかろうと、必ずensure節の中身が実行されます。

ここでは、計算終了のメッセージを出力しています。

このコードを実行すると、次の結果が出力されます。

ゼロで割ることはできません!
計算を終了します。

このように、rescueとensureを組み合わせることで、例外発生の有無に関わらず、特定の処理を必ず実行させることが可能となります。

この特性は、例えばファイルのクローズやリソースの解放など、例外が発生しても確実に行いたい処理に対して有効に活用できます。

●rescueを活用したエラーハンドリングのテクニック

Rubyのrescueを活用すれば、繊細なエラーハンドリングが可能です。

複数の例外をキャッチしたり、エラーメッセージをロギングしたり、独自の例外クラスを定義したり、さらには例外発生時にメール通知を行う等、多彩な手法があります。

○サンプルコード7:複数の例外をrescueする方法

def divide(x, y)
  begin
    x / y
  rescue ZeroDivisionError, TypeError
    puts "ゼロで割ることはできません、または不正な型が入力されました。"
  end
end

divide('4', 2)

このコードでは、ZeroDivisionErrorとTypeErrorの2つの例外を同時にrescueしています。

具体的には、引数がゼロによる割り算、あるいは文字列と数値の割り算など、予期せぬ入力による例外をキャッチします。

このコードを実行すると、次の結果が出力されます。

ゼロで割ることはできません、または不正な型が入力されました。

○サンプルコード8:例外オブジェクトを取得し、詳細情報をログに出力する方法

def divide(x, y)
  begin
    x / y
  rescue => e
    puts "エラーが発生しました: #{e.class}、メッセージ: #{e.message}"
  end
end

divide(1, 0)

このコードではrescue節の右側に変数eを置くことで、発生した例外オブジェクトをキャプチャします。

その例外オブジェクトからエラーの詳細情報(エラーのクラス名やエラーメッセージ)を取得して表示します。

このコードを実行すると、次の結果が出力されます。

エラーが発生しました: ZeroDivisionError、メッセージ: divided by 0

これにより、エラーの詳細な原因を確認することができます。

この手法はデバッグ時に特に役立ちます。

○サンプルコード9:独自の例外クラスを定義し、rescueする方法

class MyError < StandardError; end

def divide(x, y)
  begin
    raise MyError, "独自エラーが発生しました" if y.zero?
    x / y
  rescue MyError => e
    puts e.message
  end
end

divide(1, 0)

このコードでは、StandardErrorクラスを継承して独自の例外クラスMyErrorを定義しています。

yがゼロの場合、MyErrorを発生させています。

このコードを実行すると、次の結果が出力されます。

独自エラーが発生しました

○サンプルコード10:例外が発生した場合にメール通知を行う方法

require 'net/smtp'
require 'mail'

Mail.defaults do
  delivery_method :smtp, { 
    :address              => 'smtp.gmail.com',
    :port                 => 587,
    :domain               => 'your_host.com',
    :user_name            => 'your_email@gmail.com',
    :password             => 'your_password',
    :authentication       => 'plain',
    :enable_starttls_auto => true
  }
end

def notify_error(exception)
  Mail.deliver do
    to      'your_boss@gmail.com'
    from    'no-reply@your_host.com'
    subject 'エラー通知'
    body    "エラーが発生しました: #{exception.class}、メッセージ: #{exception.message}"
  end
end

def divide(x, y)
  begin
    x / y
  rescue => e
    notify_error(e)
  end
end

divide(1, 0)

このコードでは、例外が発生した場合にメール通知を行う方法を紹介しています。

まず、net/smtpとmailというライブラリを利用しています。そしてnotify_errorというメソッドを定義しています。

これは、エラーが発生した場合に例外の詳細情報をメールで通知する役割を持っています。

注意点として、実際にこのコードを動かすには、自身のメールアドレスやパスワードを設定する必要があります。

このコードを実行すると、エラーが発生した際に登録したメールアドレスに次のようなメールが届きます。

エラーが発生しました: ZeroDivisionError、メッセージ: divided by 0

これらのテクニックを活用すれば、Rubyでのエラーハンドリングがより楽に、かつ効率的に行えるようになります。

これらのコードはあくまで一例ですので、状況に応じて適切な例外処理を実装してください。

●rescueの注意点

rescueを使用する上で注意すべき点はいくつかあります。

①例外クラスの指定

例外クラスを指定しない場合、StandardErrorクラスとそのサブクラスの例外だけがキャッチされます。

しかし、これにはSystemExitやInterruptといった例外は含まれません。

これらの例外をキャッチしたい場合は、明示的に指定する必要があります。

begin
  exit
rescue => e
  puts "例外が発生しました: #{e.class}"
end

このコードを実行すると、プログラムは何も出力せずに終了します。

exitメソッドはSystemExit例外を発生させますが、rescue節で指定した例外クラスはStandardErrorのみなので、SystemExit例外はキャッチされません。

②rescueの順序

複数のrescue節を使う場合、上から順にマッチするものが実行されます。

そのため、より具体的な例外クラスを先に記述することが重要です。

begin
  raise "エラー発生!"
rescue StandardError => e
  puts "StandardErrorです: #{e.message}"
rescue RuntimeError => e
  puts "RuntimeErrorです: #{e.message}"
end

このコードを実行すると、「StandardErrorです: エラー発生!」と出力されます。

RuntimeErrorはStandardErrorのサブクラスであり、rescue節が上から順に評価されるため、RuntimeErrorのrescue節は実行されません。

まとめ

これらを学ぶことで、エラーハンドリングの技術が向上し、より安全で信頼性の高いコードを書くことが可能となります。

どの例外を捕捉するか、どのようにエラー情報を利用するか、どのように例外を通知するか等、状況に応じて適切なエラーハンドリングを行うことが重要です。

特にrescueの注意点を押さえ、予期せぬ挙動を防ぎましょう。

これらの技術を学びながら、Rubyにおけるエラーハンドリングに対する理解を深めていくことをおすすめします。

また、今後のプログラミング学習に役立てていただければ幸いです。