Hacker News new | ask | show | jobs
by saghm 62 days ago
Interesting! From playing around with it, seems like if the start index is exactly the same as the length, it returns empty array, but if it's further than that it returns nil. That's certainly not something I would have been able to predict, so I'd also be curious if anyone happens to know the explanation for it. My instinct is that it does seem like the type of edge case that might come up with a way to implement it tersely, but that's not a particularly good reason to leak that in the form of user-facing behavior, so hopefully there's a better explanation.

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 nil
1 comments

the docs say... if index is out of range return nil. the edge case is that if you specify the exact end index of the array and want a slice of that index to 100 it will return an empty array. if you go out of bounds it informs you that you are out of bounds with nil. not sure it's the best api but probably is mimicking some C api somewhere as a lot of ruby does that. that said it will never error on this alone but it will almost certainly error if you chain it with something not expecting nil.

The 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.

Indeed. I had heard that it was a carryover from C; but for an "implicit is better than explicit" and "magic ducktyping, it just works, I promise" language, like Ruby, this feels like a direct contradiction to its intended behavior and this specific example has always stood out to me in a "... but why?" sort of way.
Yeah, I'd argue that it would be less confusing to return the same thing even if it's inconsistent with some C API that plenty of Ruby programmers might never have encountered. I'm honestly not sure I even understand what the C API is that's being referred to; slices and bounds checks aren't things I typically associate with being built into C.