public Method

Kernel.callcc

callcc {|cont| block }     obj

Generates a Continuation object, which it passes to the associated block. Performing a cont.call will cause the callcc to return (as will falling through the end of the block). The value returned by the callcc is the value of the block, or the value passed to cont.call. See class Continuation for more details. Also see Kernel::throw for an alternative mechanism for unwinding a call stack.

Source Code

/*
*  call-seq:
*     callcc {|cont| block }   =>  obj
*  
*  Generates a <code>Continuation</code> object, which it passes to the
*  associated block. Performing a <em>cont</em><code>.call</code> will
*  cause the <code>callcc</code> to return (as will falling through the
*  end of the block). The value returned by the <code>callcc</code> is
*  the value of the block, or the value passed to
*  <em>cont</em><code>.call</code>. See class <code>Continuation</code> 
*  for more details. Also see <code>Kernel::throw</code> for
*  an alternative mechanism for unwinding a call stack.
*/

static VALUE
rb_callcc(self)
   VALUE self;
{
   volatile VALUE cont;
   rb_thread_t th;
   volatile rb_thread_t th_save;
   struct tag *tag;
   struct RVarmap *vars;

   THREAD_ALLOC(th);
   cont = Data_Wrap_Struct(rb_cCont, thread_mark, thread_free, th);

   scope_dup(ruby_scope);
   for (tag=prot_tag; tag; tag=tag->prev) {
       scope_dup(tag->scope);
   }
   th->thread = curr_thread->thread;
   th->thgroup = cont_protect;

   for (vars = ruby_dyna_vars; vars; vars = vars->next) {
       if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
       FL_SET(vars, DVAR_DONT_RECYCLE);
   }
   th_save = th;
   if (THREAD_SAVE_CONTEXT(th)) {
       return th_save->result;
   }
   else {
       return rb_yield(cont);
   }
}
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.