throw y catch son Sentencias de Control

throw and catch are Kernel methods that define a control structure that can be thought of as a multilevel break.

throw doesn’t just break out of the current loop or block but can actually transfer out any number of levels, causing the block defined with a catch to exit.

The catch need not even be in the same method as the throw. It can be in the calling method, or somewhere even further up the call stack.

Languages like Java and JavaScript allow loops to be named or labeled with an arbitrary prefix. When this is done, a control structure known as a labeled break causes the named loop to exit.

Ruby’s catch method defines a labeled block of code, and Ruby’s throw method causes that block to exit.

But throw and catch are much more general than a labeled break. For one, it can be used with any kind of statement and is not restricted to loops.

More profoundly, a throw can propagate up the call stack to cause a block in an invoking method to exit.

If you are familiar with languages like Java and JavaScript, then you probably recognize throw and catch as the keywords those languages use for raising and handling exceptions.

Ruby does exceptions differently, using raise and rescue, which we’ll learn about later in this chapter.

But the parallel to exceptions is intentional. Calling throw is very much like raising an exception.

And the way a throw propagates out through the lexical scope and then up the call stack is very much the same as the way an exception propagates out and up.

Despite the similarity to exceptions, it is best to consider throw and catch as a general-purpose (if perhaps infrequently used) control structure rather than an exception mechanism.

If you want to signal an error or exceptional condition, use raise instead of throw.

The following code demonstrates how throw and catch can be used to break out of nested loops:

for matrix in data do       # Process a deeply nested data structure. 
  catch :missing_data do    # Label this statement so we can break out.
    for row in matrix do 
      for value in row do
        throw :missing_data unless value # Break out of two loops at once.
        # Otherwise, do some actual data processing here. end
      end 
    end
    # We end up here after the nested loops finish processing each matrix.
    # We also get here if :missing_data is thrown. 
end
Note that the catch method takes a symbol argument and a block.

It executes the block and returns when the block exits or when the specified symbol is thrown.

throw also expects a symbol as its argument and causes the corresponding catch invocation to return.

If no catch call matches the symbol passed to throw, then a NameError exception is raised.

Casiano Rodriguez León 2015-01-07