Credit: Steve Arneil
An error has occurred and your code can keep running. You want to indicate the error and let some other piece of code handle it.
Raise an exception by calling the Kernel#raise method with a description of the error. Calling the raise method interrupts the flow of execution.
The following method raises an exception whenever its called. Its second message will never be printed:
def raise_exception puts I am before the raise. raise An error has occurred. puts I am after the raise. end raise_exception # I am before the raise. # RuntimeError: An error has occurred
Heres a method, inverse, that returns the inverse of a number x. It does some basic error checking by raising an exception unless x is a number:
def inverse(x) raise "Argument is not numeric" unless x.is_a? Numeric 1.0 / x end
When you pass in a reasonable value of x, all is well:
inverse(2) # => 0.5
When x is not a number, the method raises an exception:
inverse( ot a number) # RuntimeError: Argument is not numeric
An exception is an object, and the Kernel#raise method creates an instance of an exception class. By default, Kernel#raise creates an exception of RuntimeError class, which is a subclass of StandardError. This in turn is a subclass of Exception, the superclass of all exception classes. You can list all the standard exception classes by starting a Ruby session and executing code like this:
ObjectSpace.each_object(Class) do |x| puts x if x.ancestors.member? Exception end
This variant lists only the better-known exception classes:
ObjectSpace.each_object(Class) { |x| puts x if x.name =~ /Error$/ } # SystemStackError # LocalJumpError # EOFError # IOError # RegexpError # …
To raise an exception of a specific class, you can pass in the class name as an argument to raise. RuntimeError is kind of generic for the inverse methods check against x. The problem is there is actually a problem with one of the arguments passed into the method. A more aptly named exception class for that check would be ArgumentError:
def inverse(x) raise ArgumentError, Argument is not numeric unless x.is_a? Numeric 1.0 / x end
To be even more specific about an error, you can define your own Exception subclass:
class NotInvertibleError < StandardError end
The implementation of inverse method would then become:
def inverse(x) raise NotInvertibleError, Argument is not numeric unless x.is_a? Numeric 1.0 / x end inverse( ot a number) # NotInvertibleError: Argument is not numeric
In some other programming languages, exceptions are "thrown." In Ruby, they are not thrown but "raised." Ruby does have a Kernel#throw method, but it has nothing to do with exceptions. See Recipe 7.8 for an example of tHRow, as opposed to raise.
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration