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

ruby-changes:46941

From: nobu <ko1@a...>
Date: Sat, 10 Jun 2017 19:26:38 +0900 (JST)
Subject: [ruby-changes:46941] nobu:r59056 (trunk): enumerator.c: fix nested maps

nobu	2017-06-10 19:26:32 +0900 (Sat, 10 Jun 2017)

  New Revision: 59056

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59056

  Log:
    enumerator.c: fix nested maps
    
    * enumerator.c (lazy_map_proc, lazy_grep_iter_proc): marks values
      returned by blocks are not packed in the case of nested maps, so
      that the result will be same as non-lazy version.  based on the
      patch by akihikodaki (Akihiko Odaki) at [ruby-core:81638],
      without GCC extension.  [Bug#13648]

  Modified files:
    trunk/enumerator.c
    trunk/test/ruby/test_lazy_enumerator.rb
Index: test/ruby/test_lazy_enumerator.rb
===================================================================
--- test/ruby/test_lazy_enumerator.rb	(revision 59055)
+++ test/ruby/test_lazy_enumerator.rb	(revision 59056)
@@ -14,7 +14,14 @@ class TestLazyEnumerator < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/test/ruby/test_lazy_enumerator.rb#L14
 
     def each(*args)
       @args = args
-      @enum.each {|i| @current = i; yield i}
+      @enum.each do |v|
+        @current = v
+        if v.is_a? Enumerable
+          yield *v
+        else
+          yield v
+        end
+      end
     end
   end
 
@@ -100,6 +107,15 @@ class TestLazyEnumerator < Test::Unit::T https://github.com/ruby/ruby/blob/trunk/test/ruby/test_lazy_enumerator.rb#L107
     assert_equal(1, a.current)
   end
 
+  def test_map_packed_nested
+    bug = '[ruby-core:81638] [Bug#13648]'
+
+    a = Step.new([[1, 2]])
+    expected = [[[1, 2]]]
+    assert_equal(expected, a.map {|*args| args}.map {|*args| args}.to_a)
+    assert_equal(expected, a.lazy.map {|*args| args}.map {|*args| args}.to_a, bug)
+  end
+
   def test_flat_map
     a = Step.new(1..3)
     assert_equal(2, a.flat_map {|x| [x * 2]}.first)
Index: enumerator.c
===================================================================
--- enumerator.c	(revision 59055)
+++ enumerator.c	(revision 59056)
@@ -1448,6 +1448,8 @@ lazy_init_block_i(RB_BLOCK_CALL_FUNC_ARG https://github.com/ruby/ruby/blob/trunk/enumerator.c#L1448
 #define LAZY_MEMO_PACKED_P(memo) ((memo)->memo_flags & LAZY_MEMO_PACKED)
 #define LAZY_MEMO_SET_BREAK(memo) ((memo)->memo_flags |= LAZY_MEMO_BREAK)
 #define LAZY_MEMO_SET_VALUE(memo, value) MEMO_V2_SET(memo, value)
+#define LAZY_MEMO_SET_PACKED(memo) ((memo)->memo_flags |= LAZY_MEMO_PACKED)
+#define LAZY_MEMO_RESET_PACKED(memo) ((memo)->memo_flags &= ~LAZY_MEMO_PACKED)
 
 static VALUE
 lazy_init_yielder(VALUE val, VALUE m, int argc, VALUE *argv)
@@ -1743,6 +1745,7 @@ lazy_map_proc(VALUE proc_entry, struct M https://github.com/ruby/ruby/blob/trunk/enumerator.c#L1745
 {
     VALUE value = lazyenum_yield_values(proc_entry, result);
     LAZY_MEMO_SET_VALUE(result, value);
+    LAZY_MEMO_RESET_PACKED(result);
     return result;
 }
 
@@ -1913,6 +1916,7 @@ lazy_grep_iter_proc(VALUE proc_entry, st https://github.com/ruby/ruby/blob/trunk/enumerator.c#L1916
     if (!RTEST(chain)) return 0;
     value = rb_proc_call_with_block(entry->proc, 1, &(result->memo_value), Qnil);
     LAZY_MEMO_SET_VALUE(result, value);
+    LAZY_MEMO_RESET_PACKED(result);
 
     return result;
 }

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

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