SHARE:
Uncategorized

Ruby ‘Exceptional’ Knowledge-

Flatiron School / 23 October 2013

The following is a guest post by Daniel Chang and originally appeared on his blog. Daniel is currently in the Ruby-003 class at The Flatiron School. You can follow him on Twitter here.

Foreward

Most of us have encountered the methods raiserescuecatchthrow, and break in Ruby. We can generally understand what’s going on when we read code that uses it, but what exactly is the difference between them all? Here’s a quick guide plus some fun and useful facts.

If you remember just one thing…

  • raise and rescue are used for handling errors only
  • throw and catch are used in order to terminate execution early when no other work is needed. source

Raise and Rescue

raise and rescue are used exclusively for handling errors. By default, raising an error will exit the program.

This happens unless there is a rescue statement which will run in case of an exception.

The above Ruby code can be rewritten like so:

Ruby has many different types of exceptions (see documentation). Raise takes up to three parameters: * the exception type * an error message * an array of callback information.

All three are optional and Ruby knows that if you only pass in a string that it’s the message. Usually you don’t set the last parameter since Kernel#caller automatically creates that array.

Here are a couple of valid raise statements.

Exceptional Ruby

Exception is the root of Ruby’s exception hierarchy. It’s the class from which all Exceptions descend. It is king. This has a very interesting consequence.

rescue Exception rescues from EVERYTHING, including syntax errors, load errors, and any of the following listed below.

  • Rescuing Interrupt prevents you from being able to CTRL+C out of the program.

  • Rescuing SignalException prevents the program from responding correctly to signals. It will be unkillable, except with kill -9. source

Break, Catch, and Throw

breakcatch and throw are used in order to terminate execution early when no other work is needed.break leaves the current loop while the catch and throw combination can be used to break out of any number of loops at one time.

Notice that the two loops are enclosed in the catch block. This means that once the throw statement is executed, it will store the value of its second argument into :recipe and send it back to the catch statement. By doing so, it exits all the loops after finding the first recipe match. From there, the method finishes executing as normal.

Because my example is a bit contrived, I will post a real-life example from another blog by rubyist Avdi Grimm.

Since loading pages over and over again can be an expensive process, the coder above uses a throwcatchto exit the loop when the first matching result is found.

Throw, Catch and Sinatra

An even more mind-blowing example from the same blog post reveals that Sinatra has a built-in catch for the#last-modified method. You might use this method to check a user’s cache for what version of a certain page the user has on his/her machine. Why would you do this? Simple! In order to cut out any expensive and unnecessary processing. If the page in the cache is old, then you’d update the page. Otherwise, just load from cache.

For your convenience, here’s the simplified code Grimm posted to demonstrate.

When Ruby encounters the throw, it zips back up the call stack looking for a matching symbol, :halt. Where’s the catch block though? It’s clearly not in the same method as the throw. This means that it must be further up the stack. In other words, #last_modified was called within a catch block.

10 Useful to Somewhat Useful Bash Shortcuts: Every second saved is a second earned.com Previous Post Yield! In the Name of Blocks Next Post