Raising an Exception

Credit: Steve Arneil

Problem

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.

Solution

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

Discussion

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.

See Also

  • Recipe 7.8, "Stopping an Iteration"
  • Recipe 17.2, " Raising an Exception"
  • Recipe 17.3, "Handling an Exception"


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



Ruby Cookbook
Ruby Cookbook (Cookbooks (OReilly))
ISBN: 0596523696
EAN: 2147483647
Year: N/A
Pages: 399

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net