Project

General

Profile

Bug #18247

Updated by Eregon (Benoit Daloze) over 2 years ago

There are weird results for `Array#slice` or `Array#[]` with argument of type `Enumerator::ArithmeticSequence`. 

 Particularly most results with negative steps are weird. For example: 

 ```ruby 
 @array = [0, 1, 2, 3, 4, 5] 

 @array.slice((2..).step(-1))            # =>    [2, 1, 0] 
 @array.slice((2..).step(-2))            # =>    [2, 0] 
 @array.slice((2..).step(-3))            # =>    [2] 
 @array.slice((2..).step(-4))            # =>    [0]             # ???    I'd have expected [2] 

 @array.slice((-3..).step(-1))           # =>    [3, 2, 1, 0] 
 @array.slice((-3..).step(-2))           # =>    [3, 1] 
 @array.slice((-3..).step(-3))           # =>    [3, 0] 
 @array.slice((-3..).step(-4))           # =>    [3] 
 @array.slice((-3..).step(-5))           # =>    [0]             # ???    I'd have expected [3] 
 ``` 

 Have a look at these examples with "beginless" ranges and negative steps. 
 Particularly the ones exluding the end value (`...`) seem wrong: 


 ```ruby 
 @array = [0, 1, 2, 3, 4, 5] 

 ## end with zero index 
 @array.slice((..0).step(-1))          # =>    [5, 4, 3, 2, 1, 0] 
 @array.slice((...0).step(-1))         # =>    [5, 4, 3, 2, 1, 0] 

 @array.slice((..0).step(-2))          # =>    [5, 3, 1] 
 @array.slice((...0).step(-2))         # =>    [5, 3, 1] 

 @array.slice((..0).step(-10))         # =>    [0] 
 @array.slice((...0).step(-10))        # =>    [0] 

 ## end with positive index 
 @array.slice((..3).step(-1))          # =>    [5, 4, 3] 
 @array.slice((...3).step(-1))         # =>    [5, 4, 3] 

 @array.slice((..3).step(-2))          # =>    [5, 3] 
 @array.slice((...3).step(-2))         # =>    [5, 3] 

 @array.slice((..3).step(-10))         # =>    [3] 
 @array.slice((...3).step(-10))        # =>    [3] 

 ## end with negative index 
 @array.slice((..-2).step(-1))         # =>    [5, 4] 
 @array.slice((...-2).step(-1))        # =>    [5, 4] 

 @array.slice((..-2).step(-2))         # =>    [5] 
 @array.slice((...-2).step(-2))        # =>    [5] 

 @array.slice((..-2).step(-10))        # =>    [4] 
 @array.slice((...-2).step(-10))       # =>    [4] 
 ``` 

 Finally, some examples where the range is "inverted". 
 Particularly, the results for the ones excluding the end value (`...`) look strange. 
 But all examples seem weird, but I might not understand the concept of arithmetic sequence in depth. 

 ```ruby 
 @array = [0, 1, 2, 3, 4, 5] 

 # start and end with positive index 
 @array.slice((3..1).step(-1))         # =>    [3, 2, 1] 
 @array.slice((3...1).step(-1))        # =>    [2, 1] 

 @array.slice((3..1).step(-2))         # =>    [3, 1] 
 @array.slice((3...1).step(-2))        # =>    [2] 

 @array.slice((3..1).step(-10))        # =>    [1] 
 @array.slice((3...1).step(-10))       # =>    [1] 

 # start with negative index, end with positive index 
 @array.slice((-2..1).step(-1))        # =>    [4, 3, 2, 1] 
 @array.slice((-2...1).step(-1))       # =>    [3, 2, 1] 

 @array.slice((-2..1).step(-2))        # =>    [4, 2] 
 @array.slice((-2...1).step(-2))       # =>    [3, 1] 

 @array.slice((-2..1).step(-10))       # =>    [1] 
 @array.slice((-2...1).step(-10))      # =>    [1] 

 # start with positive index, end with negative index 
 @array.slice((4..-4).step(-1))        # =>    [4, 3, 2] 
 @array.slice((4...-4).step(-1))       # =>    [3, 2] 

 @array.slice((4..-4).step(-2))        # =>    [4, 2] 
 @array.slice((4...-4).step(-2))       # =>    [3] 

 @array.slice((4..-4).step(-10))       # =>    [2] 
 @array.slice((4...-4).step(-10))      # =>    [2] 

 # start with negative index, end with negative index 
 @array.slice((-2..-4).step(-1))       # =>    [4, 3, 2] 
 @array.slice((-2...-4).step(-1))      # =>    [3, 2] 

 @array.slice((-2..-4).step(-2))       # =>    [4, 2] 
 @array.slice((-2...-4).step(-2))      # =>    [3] 

 @array.slice((-2..-4).step(-10))      # =>    [2] 
 @array.slice((-2...-4).step(-10))     # =>    [2] 
 ``` 

 Found while writing specs for this method in https://github.com/ruby/spec/pull/857

Back