[前][次][番号順一覧][スレッド一覧]

ruby-changes:1754

From: ko1@a...
Date: 24 Aug 2007 19:48:55 +0900
Subject: [ruby-changes:1754] matz - Ruby:r13245 (trunk): * enumerator.c (enumerator_next): stop pre-fetching.

matz	2007-08-24 19:48:43 +0900 (Fri, 24 Aug 2007)

  New Revision: 13245

  Modified files:
    trunk/ChangeLog
    trunk/enumerator.c
    trunk/eval.c
    trunk/test/ruby/test_iterator.rb

  Log:
    * enumerator.c (enumerator_next): stop pre-fetching.
    
    * enumerator.c (Init_Enumerator): remove next? method.
    
    * eval.c (rb_f_loop): now handles StopIteration exception.

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/test/ruby/test_iterator.rb?r1=13245&r2=13244
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=13245&r2=13244
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval.c?r1=13245&r2=13244
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/enumerator.c?r1=13245&r2=13244

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 13244)
+++ ChangeLog	(revision 13245)
@@ -15,6 +15,16 @@
 	* eval.c (rb_f_send_bang): abandon the name funcall for private
 	  aware method call.
 
+Fri Aug 24 15:27:12 2007  Yukihiro Matsumoto  <matz@r...>
+
+	* enumerator.c (enumerator_next): stop pre-fetching.
+
+	* enumerator.c (Init_Enumerator): remove next? method.
+
+Fri Aug 24 15:14:57 2007  Yukihiro Matsumoto  <matz@r...>
+
+	* eval.c (rb_f_loop): now handles StopIteration exception.
+
 Thu Aug 23 20:31:31 2007  Koichi Sasada  <ko1@a...>
 
 	* compile.c: optimize simple massign.
Index: enumerator.c
===================================================================
--- enumerator.c	(revision 13244)
+++ enumerator.c	(revision 13245)
@@ -44,9 +44,8 @@
     VALUE args;
     enum_iter *iter;
     VALUE fib;
-    VALUE next;
     VALUE dst;
-    VALUE has_next;
+    VALUE no_next;
 };
 
 static void
@@ -57,7 +56,6 @@
     rb_gc_mark(ptr->proc);
     rb_gc_mark(ptr->args);
     rb_gc_mark(ptr->fib);
-    rb_gc_mark(ptr->next);
     rb_gc_mark(ptr->dst);
 }
 
@@ -241,8 +239,8 @@
     }
     if (argc) ptr->args = rb_ary_new4(argc, argv);
     ptr->fib = 0;
-    ptr->next = ptr->dst = Qnil;
-    ptr->has_next = Qnil;
+    ptr->dst = Qnil;
+    ptr->no_next = Qfalse;
 
     return enum_obj;
 }
@@ -373,13 +371,7 @@
 next_ii(VALUE i, VALUE obj)
 {
     struct enumerator *e = enumerator_ptr(obj);
-    VALUE tmp = e->next;
-
-    e->next = i;
-    tmp = rb_fiber_yield(1, &tmp);
-    if (tmp != Qnil) {
-	e->dst = tmp;
-    }
+    rb_fiber_yield(1, &i);
     return Qnil;
 }
 
@@ -387,11 +379,11 @@
 next_i(VALUE curr, VALUE obj)
 {
     struct enumerator *e = enumerator_ptr(obj);
-    e->dst = curr;
+    VALUE nil = Qnil;
 
     rb_block_call(obj, rb_intern("each"), 0, 0, next_ii, obj);
-    e->has_next = Qfalse;
-    return rb_fiber_yield(1, &e->next);
+    e->no_next = Qtrue;
+    return rb_fiber_yield(1, &nil);
 }
 
 static void
@@ -400,8 +392,6 @@
     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_resume(e->fib, 1, &curr);
 }
 
 /*
@@ -429,35 +419,18 @@
 	next_init(obj, e);
     }
 
-    if (!e->has_next) {
+    v = rb_fiber_resume(e->fib, 1, &curr);
+    if (e->no_next) {
 	e->fib = 0;
-	e->next = e->dst = Qnil;
+	e->dst = Qnil;
+	e->no_next = Qfalse;
 	rb_raise(rb_eStopIteration, "Enumerator#each reached at end");
     }
-
-    v = rb_fiber_resume(e->fib, 1, &curr);
     return v;
 }
 
 /*
  * call-seq:
- *   e.next?   => bool
- *
- * Returns true if this enumerator object has not reached the end yet.
- */
-
-static VALUE
-enumerator_next_p(VALUE obj)
-{
-    struct enumerator *e = enumerator_ptr(obj);
-    if (!e->fib) {
-	next_init(obj, e);
-    }
-    return e->has_next;
-}
-
-/*
- * call-seq:
  *   e.next?   => e
  *
  * Rewinds the enumeration sequence by the next method.
@@ -469,7 +442,8 @@
     struct enumerator *e = enumerator_ptr(obj);
 
     e->fib = 0;
-    e->next = e->dst = Qnil;
+    e->dst = Qnil;
+    e->no_next = Qfalse;
     return obj;
 }
 
@@ -492,7 +466,6 @@
     rb_define_method(rb_cEnumerator, "with_index", enumerator_with_index, 0);
     rb_define_method(rb_cEnumerator, "to_splat", enumerator_to_splat, 0);
     rb_define_method(rb_cEnumerator, "next", enumerator_next, 0);
-    rb_define_method(rb_cEnumerator, "next?", enumerator_next_p, 0);
     rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);
 
     rb_eStopIteration   = rb_define_class("StopIteration", rb_eIndexError);
Index: eval.c
===================================================================
--- eval.c	(revision 13244)
+++ eval.c	(revision 13245)
@@ -951,6 +951,14 @@
     return v;
 }
 
+static VALUE
+loop_i()
+{
+    for (;;) {
+	rb_yield_0(0, 0);
+    }
+}
+
 /*
  *  call-seq:
  *     loop {|| block }
@@ -968,9 +976,7 @@
 static VALUE
 rb_f_loop(void)
 {
-    for (;;) {
-	rb_yield_0(0, 0);
-    }
+    rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
     return Qnil;		/* dummy */
 }
 
Index: test/ruby/test_iterator.rb
===================================================================
--- test/ruby/test_iterator.rb	(revision 13244)
+++ test/ruby/test_iterator.rb	(revision 13245)
@@ -496,13 +496,15 @@
 
     e = [1,2,3].each
     assert_equal(1, e.next)
-    assert_equal(true, e.next?)
     assert_equal(2, e.next)
     assert_equal(3, e.next)
     assert_raises(StopIteration){e.next}
     e.rewind
-    assert_equal(true, e.next?)
     assert_equal(1, e.next)
+    e.rewind
+    a = []
+    loop{a.push e.next}
+    assert_equal([1,2,3], a)
 
     assert_equal([[1, 8, 10], [2, 6, 11], [3, 4, 12]],
                  (1..10).zip([8,6,4],(10..100)).to_a)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧]