public Method

Kernel.catch(p1)

catch(symbol) {| | block }  > obj

catch executes its block. If a throw is executed, Ruby searches up its stack for a catch block with a tag corresponding to the throw’s symbol. If found, that block is terminated, and catch returns the value given to throw. If throw is not called, the block terminates normally, and the value of catch is the value of the last expression evaluated. catch expressions may be nested, and the throw call need not be in lexical scope.

def routine(n)
  puts n
  throw :done if n <= 0
  routine(n-1)
end

catch(:done) { routine(3) }

produces:

3
2
1
0

Source Code

/*
*  call-seq:
*     catch(symbol) {| | block }  > obj
*  
*  +catch+ executes its block. If a +throw+ is
*  executed, Ruby searches up its stack for a +catch+ block
*  with a tag corresponding to the +throw+'s
*  _symbol_. If found, that block is terminated, and
*  +catch+ returns the value given to +throw+. If
*  +throw+ is not called, the block terminates normally, and
*  the value of +catch+ is the value of the last expression
*  evaluated. +catch+ expressions may be nested, and the
*  +throw+ call need not be in lexical scope.
*     
*     def routine(n)
*       puts n
*       throw :done if n <= 0
*       routine(n-1)
*     end
*     
*     
*     catch(:done) { routine(3) }
*     
*  <em>produces:</em>
*     
*     3
*     2
*     1
*     0
*/

static VALUE
rb_f_catch(dmy, tag)
   VALUE dmy, tag;
{
   int state;
   VALUE val = Qnil;           /* OK */

   tag = ID2SYM(rb_to_id(tag));
   PUSH_TAG(tag);
   if ((state = EXEC_TAG()) == 0) {
       val = rb_yield_0(tag, 0, 0, 0, Qfalse);
   }
   else if (state == TAG_THROW && tag == prot_tag->dst) {
       val = prot_tag->retval;
       state = 0;
   }
   POP_TAG();
   if (state) JUMP_TAG(state);

   return val;
}
Comments

Have your say
Please use Textile formatting (click here for a cheat sheet). Use <code/> and <pre/> for code samples.
Click here to login with OpenID to to post comments.