class Continuation
Continuation Objekte werden von Kernel#callcc erzeugt, nachdem continuation +require+d wurde. Sie speichern eine Rücksprungadresse und den Ausführungskontext, was eine nichtlokale Rückkehr zum Ende des callcc-Blocks von überall im Programm ermöglicht. Fortsetzungen sind einigermaßen analog zu einer strukturierten Version von C's setjmp/longjmp (obwohl sie mehr Zustand enthalten, sodass man sie als näher an Threads betrachten könnte).
Zum Beispiel
require "continuation" arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ] callcc{|cc| $cc = cc} puts(message = arr.shift) $cc.call unless message =~ /Max/
ergibt
Freddie Herbie Ron Max
Sie können callcc auch in anderen Methoden aufrufen
require "continuation" def g arr = [ "Freddie", "Herbie", "Ron", "Max", "Ringo" ] cc = callcc { |cc| cc } puts arr.shift return cc, arr.size end def f c, size = g c.call(c) if size > 1 end f
Dieses (etwas konstruierte) Beispiel ermöglicht es der inneren Schleife, die Verarbeitung frühzeitig abzubrechen
require "continuation" callcc {|cont| for i in 0..4 print "#{i}: " for j in i*5...(i+1)*5 cont.call() if j == 17 printf "%3d", j end end } puts
ergibt
0: 0 1 2 3 4 1: 5 6 7 8 9 2: 10 11 12 13 14 3: 15 16
Öffentliche Instanzmethoden
Ruft die Fortsetzung auf. Das Programm wird vom Ende des callcc-Blocks fortgesetzt. Wenn keine Argumente übergeben werden, gibt die ursprüngliche callcc nil zurück. Wenn ein Argument übergeben wird, gibt callcc dieses zurück. Andernfalls wird ein Array zurückgegeben, das args enthält.
callcc {|cont| cont.call } #=> nil callcc {|cont| cont.call 1 } #=> 1 callcc {|cont| cont.call 1, 2, 3 } #=> [1, 2, 3]
Source
static VALUE
rb_cont_call(int argc, VALUE *argv, VALUE contval)
{
rb_context_t *cont = cont_ptr(contval);
rb_thread_t *th = GET_THREAD();
if (cont_thread_value(cont) != th->self) {
rb_raise(rb_eRuntimeError, "continuation called across threads");
}
if (cont->saved_ec.fiber_ptr) {
if (th->ec->fiber_ptr != cont->saved_ec.fiber_ptr) {
rb_raise(rb_eRuntimeError, "continuation called across fiber");
}
}
cont->argc = argc;
cont->value = make_passing_arg(argc, argv);
cont_restore_0(cont, &contval);
UNREACHABLE_RETURN(Qnil);
}
Ruft die Fortsetzung auf. Das Programm wird vom Ende des callcc-Blocks fortgesetzt. Wenn keine Argumente übergeben werden, gibt die ursprüngliche callcc nil zurück. Wenn ein Argument übergeben wird, gibt callcc dieses zurück. Andernfalls wird ein Array zurückgegeben, das args enthält.
callcc {|cont| cont.call } #=> nil callcc {|cont| cont.call 1 } #=> 1 callcc {|cont| cont.call 1, 2, 3 } #=> [1, 2, 3]