Project

General

Profile

Bug #13648

Updated by nobu (Nobuyoshi Nakada) almost 7 years ago

This test case ends up with the following result. 

 ~~~ ruby 
 class Step 
   include Enumerable 
   attr_reader :current, :args 

   def initialize(enum) 
     @enum = enum 
     @current = nil 
     @args = nil 
   end 

   def each(*args) 
     @args = args 
     @enum.each do |v| 
       @current = v 
       
     if v.is_a? Enumerable 
         
       yield *v 
     else 
       else 
         yield v 
       end 
     end 
   end 
 end 

 a = Step.new([[1, 2]]) 
 assert_equal([[[1, 2]]], a.lazy.map {|*args| args}.map {|*args| args}.to_a) 
 ~~~ 

 ~~~ 
 <[[[1, 2]]]> expected but was 
 <[[1, 2]]>. 
 ~~~ 

 Here, `[[[1, 2]]]` is expected because: 

 
 * An array should be created with the first map, which results in `[1, 2]`. 
 * The array should be wrapped in another array with the second map, which results in `[[1, 2]]`. 
 * The array should be wrapped in another array with to_a, which results in `[[[1, 2]]]`. 

 However, it returns `[[1, 2]]` because: 

 
 * An array will be created with the first map, which results in `[1, 2]`. 
 * However, the array will be internally considered as "packed" and the unpacked arguments will be passed to the second map. 
 * The second map wraps them into another array, which results in `[1, 2]`. 
 * The array will be wrapped in another array with to_a, which results in `[[1, 2]]`. 

 I have attached the test case and a fix. The fix marks values returned by blocks are not packed. 

Back