Inconsistent Array#slice behavior?

Given x = [],

x[0, 2] => []
x[0…2] => []
x[-3,2] => nil

Documentation says that out-of-range indices produce a nil result, but 0
s/b out-of-range for an empty array, shouldn’t it? And 2 is definitely
out-of-range.

On Tue, Mar 5, 2013 at 1:01 AM, Jack R. [email protected] wrote:

Given x = [],

x[0, 2] => []
x[-3,2] => nil

Documentation says that out-of-range indices produce a nil result, but 0
s/b out-of-range for an empty array, shouldn’t it?

Hmm, docs I usually use say “Additionally, an empty array is returned
when
the starting index for an element range is at the end of the array.
Returns
nil if the index (or starting index) are out of range.” (
http://rdoc.info/stdlib/core/Array:slice)

In this case, all elements other than 0 are past the end of the array.
It
might be easier to see if you had an element in there:

[:element][-2,1] # => nil
[:element][-1,1] # => [:element]
[:element][ 0,1] # => [:element]
[:element][ 1,1] # => []
[:element][ 2,1] # => nil

Am 05.03.2013 08:01, schrieb Jack R.:

Given x = [],

x[0, 2] => []
x[-3,2] => nil

Documentation says that out-of-range indices produce a nil result, but 0
s/b out-of-range for an empty array, shouldn’t it?

No. Take a closer look at the documentation, especially
the “special” cases.

Note: the 2.0 docs apply also to 1.9.3, the crucial part
concerning this “inconsistency” has been added only recently.

You’re right, I missed the subtlety that 0 is “at the end” of an empty
array. But wouldn’t -1 be “at the end” of an empty array also (since it
is defined as being “the last element of the array”)? And while the
documentation may be technically accurate, it certainly falls short of
being “clear”, since one would have to guess that 0 is “at the end” of
an empty string. Least surprise, anyone?

Am 05.03.2013 08:16, schrieb Josh C.:

Hmm, docs I usually use say “Additionally, an empty array is returned
when the starting index for an element range is at the end of the array.
Returnsnilif the index (or starting index) are out of range.”
(http://rdoc.info/stdlib/core/Array:slice)

This part of the Array#slice documentation is rather new and didn’t
make it into the 1.9.3 docs :slight_smile:

(Bug #6680: Unclear rdoc for Array and String slicing - Ruby master - Ruby Issue Tracking System)

I agree that if you take “at the end” to mean “the index following the
last valid element” that the behavior becomes consistent. Then I guess
that should be stated, since that is one of many possible
interpretations of “at the end” (the most obvious one to me would “the
index of the last valid element”).

In the end, examples should help solve all this, and I did not look
closely enough at the examples, so shame on me.

Am 05.03.2013 08:36, schrieb Jack R.:

You’re right, I missed the subtlety that 0 is “at the end” of an empty
array. But wouldn’t -1 be “at the end” of an empty array also (since it
is defined as being “the last element of the array”)? And while the

“At the end” is not the same as “the last element”:

2.0.0-p0 :001 > a = [0,1,2]
=> [0, 1, 2]
2.0.0-p0 :002 > a[2,1]
=> [2]
2.0.0-p0 :003 > a[-1,1]
=> [2]
2.0.0-p0 :004 > a[3,1]
=> []

“At the end” here means the index following the last valid element,
and -1 is the index of the last element.

is defined as being “the last element of the array”)? And while the
documentation may be technically accurate, it certainly falls short of
being “clear”, since one would have to guess that 0 is “at the end” of
an empty string. Least surprise, anyone?

I think this is consistent and clear (what would be the alternatives?).

Another way to view this (i.e. slicing with a range) is to think about
the index denoting the position between the elements, starting with
position 0 before the first element. This IMO leads to a very consistent
description of the observed behaviour.

Am 05.03.2013 18:07, schrieb Jack R.:

I agree that if you take “at the end” to mean “the index following the
last valid element” that the behavior becomes consistent. Then I guess
that should be stated, since that is one of many possible
interpretations of “at the end” (the most obvious one to me would “the
index of the last valid element”).

Well, when “at the end” would mean here the last valid index,
then it would not make any sense to return an empty array…

And you have to see “end of the array” in the context of the
previous sentence:
“For start and range cases the starting index is just before an
element. Additionally, an empty array is returned when the starting
index for an element range is at the end of the array.”

The same principle is used for element assignment, to enable
insertion before the first or after the last element:

2.0.0-p0 :001 > a = [0, 1, 2]
=> [0, 1, 2]
2.0.0-p0 :002 > a[3,0] = “B”; a
=> [0, 1, 2, “B”]
2.0.0-p0 :003 > a[0,0] = “A”; a
=> [“A”, 0, 1, 2, “B”]