Project

General

Profile

Feature #16822

Updated by sawa (Tsuyoshi Sawada) 6 months ago

(First of all, (In before, I understand that the change proposed change can break some code, but I empirically expect it not to be not a large amount empirically.) of.) 

 I propose that methods that slice an array slicing (`#slice` and `#[]`) and return a sub-array in the normal case, contexts when it returns sub-array, should **never** _never_ return `nil`. E.g., 

 
 E.g.: 
 ```ruby 
 ary = [1, 2, 3] 
 ``` 

 * # 1. Non-empty slice--how non-empty slice -- that's how it works currently 

 ```ruby 
 a[1..2] # => [2, 3] 
 a[1...-1] # => [2] 
 ``` 

 * # 2. Empty slice--how empty slice -- that's how it works currently 

 ```ruby 
 a[1...1] # => [] 
 a[3...] # => [] 
 a[-1..-2] # => []  
 ``` 

 * # 3. Sudden nil--what sudden nil -- that's what I am proposing to change 

 ```ruby 
 a[4..] # => nil  
 a[-10..-9] # => nil  
 ``` 

 I believe that it would be better because the method would have cleaner "type definition" (If (if there is nothing in the array at the by requested address, address -- you'll have an empty array). 

  
 Most of the time, the empty array doesn't require any special handling; thus, handling, so `ary[start...end].map { ... }` will behave as expected way if the requested range is outside of the array boundary. bounds. 

 It is especially painful with in a form of off-by-one errors; errors, when for an array of three elements, if 3, `ary[3...]` (just outside the boundary) bounds) is `[]` `[]`, while `a[4...]` (one more step outside) is `nil`, it typically results resulting in some nasty `NoMethodError for NilClass`. 

 A Another similar example (and one that just shot my foot just yesterday) is `ary[1..].reduce { }` (everything except the first element--probably element -- probably because the first element was used to construct the initial value for reducing) with `ary` being non-empty reducing), in a context, when 99.9% of the times. times `ary` is non-empty. Then you meet that one of the 0.1% cases, 0.1%, and instead of no-op reducing nothing, `NoMethodError` is fired. 

Back