Feature #6824 ยป stop.patch
| 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
|
||