The ruby array docs say:
a = [ "a", "b", "c", "d", "e" ]
...
# special cases
   a[5]                   #=> nil
   a[5, 1]                #=> []
   a[5..10]               #=> []

As one would expect, slice behavior for an array and a string are
consistent, even if not consistently documented.
I wish the docs would have also expressed the language designer's
intent, rather than just enumerate special cases.

An abstraction of half-steps (brings me back to my days of
computational fluid dynamics research -- pressure/density on whole
steps, velocity/flow on half steps) somewhat explains the slice
behavior -- n elements have n+1 fenceposts.

Though this explains the behavior, it doesn't explain why it is *good*
behavior.  In fact, I find it highly annoying because you need to
compare against two possible values (nil and empty?, unless I monkey-
patch nil.empty? #=> true) to see if you have valid elements or not,
and that an empty array/string evaluates successfully with <=> rather
than raising a nil ptr exception.

The software engineer in me thinks [-1] s similarly dangerous because
it doesn't catch an off-by-one bug, but I do find the negative indices
to be elegant enough to more than offset the detraction.

I would love to see someone cogently defend the behavior of slice
here.  I think returning nil is safer from the software engg
perspective.  Do you have a good use case where something can be done
elegantly using the special cases documented by array?