Feature #16822
Updated by sawa (Tsuyoshi Sawada) over 4 years 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.