Rubyの例外は、多くの言語と同じく、予期しない出来事に対処するための仕組みです。プログラムがクラッシュするのを防ぐには、例外を適切に扱うことが大切です。
例外は、自分で明示的に発生させることも、Rubyのインタプリターが発生させることもあります。例外が発生すると、プログラムは通常の動作を中断し、最終的にはエラーメッセージを出して終了します。
raise ArgumentError.new("Something went wrong!")
=> Traceback (most recent call last):
.
.
ArgumentError (Something went wrong!)
1/0
=> Traceback (most recent call last):
.
.
ZeroDivisionError (divided by 0)
このようにプログラムが終了してしまうのを止めたいときは、例外に反応する必要があります。これを例外の「捕捉」と呼びます。
begin
# ...any code that raises an exception
rescue
puts 'Got an exception'
end
このプログラムはクラッシュせず、"Got an exception"と出力します。終了する代わりに、Rubyはrescueブロックのコードを実行し、そこがメッセージを出力します。
Rubyのすべてがそうであるように、例外もオブジェクトで、通常はその例外に関するデータを持っています。例外オブジェクトを取得するには、次のようにします。
begin
# ...any code that raises an exception
rescue => e
puts "Exception class: #{ e.class.name }"
puts "Exception Message:#{e.message}"
end
Rubyでは、自分で例外を発生させることもできます。たとえば次のとおりです。
begin
raise ArgumentError.new("Invalid argument")
rescue ArgumentError => e
puts e.message
end
先ほどの例外はRubyに組み込みの例外のひとつですが、独自の例外を定義して発生させることもできます。
class CustomError < StandardError
end
raise CustomError.new("Something went wrong")
この演習では、簡単な電卓のエラー処理を実装します。
目標は、引数として16、51、+を受け取ったときに、16 + 51 = 67のようなパターンの文字列を返す、動作する電卓を作ることです。
SimpleCalculator.calculate(16, 51, "+")
# => "16 + 51 = 67"
SimpleCalculator.calculate(32, 6, "*")
# => "32 * 6 = 192"
SimpleCalculator.calculate(512, 4, "/")
# => "512 / 4 = 128"
calculateメソッド内でエラーが発生する可能性のあるコードを処理するこのタスクで実装する中心となるのは、クラスメソッドSimpleCalculator.calculate()です。
このメソッドは3つの引数を取ります。
最初の2つの引数は、演算の対象となる数値です。
3番目の引数は文字列で、この演習では次の演算を実装する必要があります。
+という文字列を使った足し算*という文字列を使った掛け算/という文字列を使った割り算未知の演算子記号に対してUnsupportedOperation例外を発生させるように、SimpleCalculator.calculate()メソッドを更新します。
SimpleCalculator.calculate(1, 2, '-')
# => Raises an UnsupportedOperation
この演習では、特定のスコープに対してUnsupportedOperation例外を定義することが求められます。
無効な引数の型に対してArgumentError例外を発生させるように、SimpleCalculator.calculate()メソッドを更新します。
SimpleCalculator.calculate(1, '2', '*')
# => Raises an ArgumentError
ZeroDivisionError例外を処理するように、SimpleCalculator.calculate()を更新します。
処理するコードは、Division by zero is not allowed.という内容の文字列を返す必要があります。
その他の例外は、SimpleCalculator.calculate()メソッドで処理してはいけません。
SimpleCalculator.calculate(512, 0, "/")
# => returns "Division by zero is not allowed."