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

ruby-changes:26871

From: marcandre <ko1@a...>
Date: Thu, 24 Jan 2013 15:24:31 +0900 (JST)
Subject: [ruby-changes:26871] marcandRe: r38923 (trunk): * enumerator.c: Fix state handling for Lazy#zip

marcandre	2013-01-24 15:24:22 +0900 (Thu, 24 Jan 2013)

  New Revision: 38923

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38923

  Log:
    * enumerator.c: Fix state handling for Lazy#zip
      [bug #7696] [bug #7691]
    
    * test/ruby/test_lazy_enumerator.rb: test for above

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

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38922)
+++ ChangeLog	(revision 38923)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Jan 24 15:21:17 2013  Marc-Andre Lafortune  <ruby-core@m...>
+
+	* enumerator.c: Fix state handling for Lazy#zip,{drop_take}{_while}
+	  [bug #7696] [bug #7691]
+
 Thu Jan 24 11:43:47 2013  Narihiro Nakamura  <authornari@g...>
 
 	* eval.c (f_current_dirname): Add documentation about "__dir__
Index: enumerator.c
===================================================================
--- enumerator.c	(revision 38922)
+++ enumerator.c	(revision 38923)
@@ -104,7 +104,7 @@ https://github.com/ruby/ruby/blob/trunk/enumerator.c#L104
  */
 VALUE rb_cEnumerator;
 VALUE rb_cLazy;
-static ID id_rewind, id_each, id_new, id_initialize, id_yield, id_call, id_size;
+static ID id_rewind, id_each, id_new, id_initialize, id_yield, id_call, id_size, id_to_enum;
 static ID id_eqq, id_next, id_result, id_lazy, id_receiver, id_arguments, id_memo, id_method, id_force;
 static VALUE sym_each, sym_cycle;
 
@@ -1602,12 +1602,21 @@ next_stopped(VALUE obj) https://github.com/ruby/ruby/blob/trunk/enumerator.c#L1602
 }
 
 static VALUE
-lazy_zip_func(VALUE val, VALUE arg, int argc, VALUE *argv)
+lazy_zip_func(VALUE val, VALUE zip_args, int argc, VALUE *argv)
 {
-    VALUE yielder, ary, v;
+    VALUE yielder, ary, arg, v;
     long i;
 
     yielder = argv[0];
+    arg = rb_ivar_get(yielder, id_memo);
+    if (NIL_P(arg)) {
+	arg = rb_ary_new2(RARRAY_LEN(zip_args));
+	for (i = 0; i < RARRAY_LEN(zip_args); i++) {
+	    rb_ary_push(arg, rb_funcall(RARRAY_PTR(zip_args)[i], id_to_enum, 0));
+	}
+	rb_ivar_set(yielder, id_memo, arg);
+    }
+
     ary = rb_ary_new2(RARRAY_LEN(arg) + 1);
     rb_ary_push(ary, argv[1]);
     for (i = 0; i < RARRAY_LEN(arg); i++) {
@@ -1623,19 +1632,15 @@ static VALUE https://github.com/ruby/ruby/blob/trunk/enumerator.c#L1632
 lazy_zip(int argc, VALUE *argv, VALUE obj)
 {
     VALUE ary;
-    int i;
 
     if (rb_block_given_p()) {
 	return rb_call_super(argc, argv);
     }
-    ary = rb_ary_new2(argc);
-    for (i = 0; i < argc; i++) {
-	rb_ary_push(ary, rb_funcall(argv[i], id_lazy, 0));
-    }
+    ary = rb_ary_new4(argc, argv);
 
     return lazy_set_method(rb_block_call(rb_cLazy, id_new, 1, &obj,
 					 lazy_zip_func, ary),
-			   rb_ary_new4(argc, argv), lazy_receiver_size);
+			   ary, lazy_receiver_size);
 }
 
 static VALUE
@@ -1957,6 +1962,7 @@ Init_Enumerator(void) https://github.com/ruby/ruby/blob/trunk/enumerator.c#L1962
     id_memo = rb_intern("memo");
     id_method = rb_intern("method");
     id_force = rb_intern("force");
+    id_to_enum = rb_intern("to_enum");
     sym_each = ID2SYM(id_each);
     sym_cycle = ID2SYM(rb_intern("cycle"));
 
Index: test/ruby/test_lazy_enumerator.rb
===================================================================
--- test/ruby/test_lazy_enumerator.rb	(revision 38922)
+++ test/ruby/test_lazy_enumerator.rb	(revision 38923)
@@ -264,6 +264,14 @@ class TestLazyEnumerator < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/test/ruby/test_lazy_enumerator.rb#L264
     assert_equal([*(6..10)]*5, drop5.flat_map{drop5}.force, bug7696)
   end
 
+  def test_zip_nested
+    bug7696 = '[ruby-core:51470]'
+    enum = ('a'..'z').each
+    enum.next
+    zip = (1..3).lazy.zip(enum, enum)
+    assert_equal([[1, 'a', 'a'], [2, 'b', 'b'], [3, 'c', 'c']]*3, zip.flat_map{zip}.force, bug7696)
+  end
+
   def test_take_rewound
     bug7696 = '[ruby-core:51470]'
     e=(1..42).lazy.take(2)

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

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