Project

General

Profile

Feature #6824 ยป stop.patch

jasiek (Jan Szumiec), 08/02/2012 06:45 PM

View differences:

enumerator.c (working copy)
VALUE rb_cEnumerator;
VALUE rb_cLazy;
static ID id_rewind, id_each, id_new, id_initialize, id_yield, id_call;
static ID id_eqq, id_next, id_result, id_lazy, id_receiver, id_arguments, id_method;
static ID id_eqq, id_next, id_result, id_lazy, id_receiver, id_arguments, id_method, id_source;
static VALUE sym_each, sym_cycle;
VALUE rb_eStopIteration;
......
result = rb_block_call(obj, id_each, 0, 0, next_ii, obj);
e->stop_exc = rb_exc_new2(rb_eStopIteration, "iteration reached an end");
rb_ivar_set(e->stop_exc, id_result, result);
rb_ivar_set(e->stop_exc, id_source, obj);
return rb_fiber_yield(1, &nil);
}
......
return rb_attr_get(self, id_result);
}
/*
* call-seq:
* source -> value
*
* Returns the enumerator responsible for raising this instance.
*
* e = [].each
*
* begin
* e.next
* rescue StopIteration => ex
* puts ex.source
* end
*
*/
static VALUE
stop_source(VALUE self)
{
return rb_attr_get(self, id_source);
}
void
InitVM_Enumerator(void)
{
......
rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
rb_define_method(rb_eStopIteration, "result", stop_result, 0);
rb_define_method(rb_eStopIteration, "source", stop_source, 0);
/* Generator */
rb_cGenerator = rb_define_class_under(rb_cEnumerator, "Generator", rb_cObject);
......
id_receiver = rb_intern("receiver");
id_arguments = rb_intern("arguments");
id_method = rb_intern("method");
id_source = rb_intern("source");
sym_each = ID2SYM(id_each);
sym_cycle = ID2SYM(rb_intern("cycle"));
test/ruby/test_enumerator.rb (working copy)
assert_equal(res, exc.result)
end
def test_stop_source
e = [].each
begin
e.next
fail
rescue StopIteration => ex
assert_equal(e, ex.source)
end
end
def test_next_values
o = Object.new
def o.each
    (1-1/1)