[].slice(5, 100)
^-- *THIS* either returns nil or throws an exception.Edit: Longer example:
puts "[1, 2, 3].slice(1, 100) -> #{[1, 2, 3].slice(1, 100).to_s}"
puts "[1, 2, 3].slice(3, 100) -> #{[1, 2, 3].slice(3, 100).to_s}"
puts "[1, 2, 3].slice(4, 100) -> #{[1, 2, 3].slice(4, 100).to_s}"
Yields: [1, 2, 3].slice(1, 100) -> [2, 3]
[1, 2, 3].slice(3, 100) -> []
[1, 2, 3].slice(4, 100) ->
So, there is a behavior difference between "array a little too short" and "array slightly more too short" that creates unexpected behavior.That's not a big surprise in a tiny example like this; but if you expand this out into a larger code base, where you're just being an array and you want the 100 through 110th values for whatever reason - say it's a csv. Suddenly you're having to consider both the nil case and the empty array case; but then why are they different?
Some additional things I discovered when trying to figure out why it might work like that:
* the behavior also seems consistent whether using `array.slice(a, b)` or `array[a..b]`
* `array[array.length]` and `array[array.length + 1]` both return nilThe easiest way to get around that if you are not carefully using the ranges would be to do `Array(array.slice(a, b))` as that will guarantee an array even if it's invalid. you could override slice if you really wanted to but that would be a performance penalty if you are doing it often.
``` If offset == self.size and size >= 0, returns a new empty array.
If size is negative, returns nil. ```
either way if you are doing stuff with arrays and not checking bounds you can throw an `Array(some_array.slice(x, x+100))` and it will always behave.
[0, nil, nil, nil, …x100, nil] is the same as [0] in terms of access.
In both cases, trying to access the 100th element (e.g. [0][100]) will give nil.