On Mon, Sep 13, 2010 at 10:47 AM, Colin Bartlett
<> wrote:
> On Mon, Sep 13, 2010 at 3:55 AM, Mikel Lindsaar <> wrot=
e:
>
>> ... Anyway, per http://ruby-doc.org/core/classes/Array.html#M002205 it
>> says: =C2=A0"Returns nil if the index (or starting index) are out of ran=
ge".
>> So given array:
>> =C2=A0array =3D [
eanut, :butter, :and, :jelly]
>> One would expect:
>> =C2=A0array[4] =3D=3D nil #=3D> true
>> =C2=A0array[5] =3D=3D nil #=3D> true
>> Which works, 4 and 5 are both out of range.
>> However:
>> =C2=A0array[4,0] =3D=3D nil #=3D> false
>> =C2=A0array[5,0] =3D=3D nil #=3D> true
>> Huh? =C2=A0In actual fact array[4,0] returns an empty array. =C2=A0This =
seems in
>> conflict with the docs.
>> Can someone more enlightened please explain?
>>
>
> As well as Rob's reply there is this recent thread, which has an explanat=
ion
> from Matz:
>
> http://groups.google.com/group/comp....thread/f09c65=
251c72ab6/9a125107e3186534
>
> extracts:
> http://blade.nagaokaut.ac.jp/cgi-bin...by-talk/368268
> ... So, to summarize, when indexing a position beyond the length of a
> string, ruby returns nil. But when indexing a slice beyond the length
> of a string, ruby returns an empty string "" for the first index
> beyond and then nil.
>
> I don't like that this passes
> assert "foo"[3] !=3D "foo"[3,1] ...
Strings are weird because they act like a container where the
individual contained items look like length 1 slices, which can create
an expectation that indexing and length-1 slices with the same base
index would be the identical. But the behavior makes sense when you
think about slicing (as opposed to simple indexing) as an operation on
a container that returns a container, while indexing is an operation
on a container that returns an element.
There's no reason to expect an equivalency between the element
returned by container[3] indexing and the container returned by
container[3,1] slicing. You should expect that the first element
(index of 0) in the container returned by the slicing would be the
same as the element returned by the indexing, and with Ruby's existing
behavior for both Arrays and Strings where slicing out of range
returns an empty container of the same kind you sliced, that works.
container[3] =3D=3D container[3,1][0]
whether container is "foo", [:f,

,

], "foobar", or [1,2,3,4,5]
If Ruby returned nil rather than an empty container from slicing past
the end of the container, than, for containers with length of 3 or
less, the counter intuitive result would be:
counter[3] !=3D container[3,1][0]