diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-20 18:58:32 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-08-20 18:58:32 +0000 |
commit | ad56f8c6110bd8233a4f2224ccdd1cc7ef645dc1 (patch) | |
tree | 274ff252edc7e4aba38c03752ebba1e3000bfebe /enumerator.c | |
parent | 009debfd02f5024b85b5c325f42533b40f4028e9 (diff) | |
download | ruby-ad56f8c6110bd8233a4f2224ccdd1cc7ef645dc1.tar.gz |
* enumerator.c (next_i): fix to return with Fiber#yield at
the end of each block. [ruby-dev:31470]
* enumerator.c (enumerator_next_p): call init_next if not
initialized. [ruby-dev:31514]
* test/ruby/test_enumerator.rb: add tests for Enumerator.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13120 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'enumerator.c')
-rw-r--r-- | enumerator.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/enumerator.c b/enumerator.c index 766d13758c..e2be0e2e85 100644 --- a/enumerator.c +++ b/enumerator.c @@ -13,6 +13,7 @@ ************************************************/ #include "ruby/ruby.h" +#include "debug.h" /* * Document-class: Enumerable::Enumerator @@ -42,6 +43,7 @@ struct enumerator { VALUE fib; VALUE next; VALUE dst; + VALUE has_next; }; static void @@ -237,6 +239,7 @@ enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, VALUE *argv) if (argc) ptr->args = rb_ary_new4(argc, argv); ptr->fib = 0; ptr->next = ptr->dst = Qnil; + ptr->has_next = Qnil; return enum_obj; } @@ -381,19 +384,20 @@ static VALUE next_i(VALUE curr, VALUE obj) { struct enumerator *e = enumerator_ptr(obj); - e->dst = curr; + rb_block_call(obj, rb_intern("each"), 0, 0, next_ii, obj); - return e->next; + e->has_next = Qfalse; + rb_fiber_yield(e->dst, 1, &e->next); } static void next_init(VALUE obj, struct enumerator *e) { VALUE curr = rb_fiber_current(); - e->dst = curr; e->fib = rb_block_call(rb_cFiber, rb_intern("new"), 0, 0, next_i, obj); + e->has_next = Qtrue; rb_fiber_yield(e->fib, 1, &curr); } @@ -416,16 +420,18 @@ enumerator_next(VALUE obj) { struct enumerator *e = enumerator_ptr(obj); VALUE curr, v; - curr = rb_fiber_current(); + if (!e->fib) { next_init(obj, e); } - if (!rb_fiber_alive_p(e->fib)) { + + if (!e->has_next) { e->fib = 0; e->next = e->dst = Qnil; rb_raise(rb_eStopIteration, "Enumerator#each reached at end"); } + v = rb_fiber_yield(e->fib, 1, &curr); return v; } @@ -441,11 +447,10 @@ static VALUE enumerator_next_p(VALUE obj) { struct enumerator *e = enumerator_ptr(obj); - if (!e->fib) { next_init(obj, e); } - return rb_fiber_alive_p(e->fib); + return e->has_next; } /* |