Unexpected behavior of Ruby array

I was going through the exercises at http://rubykoans.com/ and got
struck with the following problem:

array = [:peanut, :butter, :and, :jelly]

array[0] => :peanut
array[0,1] => [:peanut]
array[0,2] => [:peanut, :butter]
array[0,0] => []
array[2] => :and
array[2,2] => [:and, :jelly]
array[2,20] => [:and, :jelly]
array[4] => nil # This is OK
array[4,0] => [] # why is this an empty array and not
nil?
array[4,100] => [] # why is this an empty array and not
nil?
array[5] => nil # as expected
array[5,0] => nil # as expected

I have gone through the Ruby doc to get an explanation of this behavior,
but there it is marked as ‘# special cases’ but there is no explanation
of this behavior. I being a newb, it would be of immense help if you can
give me some pointers where I can find a correct explanation of this
behaviour.

The python slices seem to behave similarly

arr = [1, 2, 3]

arr[3] # Gives IndexError: list index out of range

arr[3:3] # gives []
arr[3:4] # gives []

But I could not find an explanation in the python docs either.

Thanks

On Thu, Sep 8, 2011 at 9:08 AM, Adam P. [email protected]
wrote:

There’s discussion about this at String/array slices - Ruby - Ruby-Forum

Oh, and Feature #4541: Inconsistent Array.slice() - Ruby master - Ruby Issue Tracking System

There’s discussion about this at String/array slices - Ruby - Ruby-Forum

On Sep 8, 2011, at 2:08 AM, Adam P. wrote:

There’s discussion about this at String/array slices - Ruby - Ruby-Forum
Oh, and Feature #4541: Inconsistent Array.slice() - Ruby master - Ruby Issue Tracking System

Also discussed here:

and here:

On Sep 8, 2011, at 4:08 AM, Adam P. wrote:

There’s discussion about this at String/array slices - Ruby - Ruby-Forum

Gary W.'s explanation in the thread linked above is very complete
and clear.
Strongly recommended if you are at all foggy on this topic.

I will add one terminology/memory tidbit -

The difference in the one-arg/two-arg indexing is ruby’s way of dealing
with
the classic fence post problem. (i.e. A fence with 3 sections has 4
posts.)

One-arg (e.g. a[1]) – The argument addresses “fence sections”.
Two-arg (e.g. a[1,2]) – The first argument addresses “fence posts”.

(As others have pointed out already, there are reasons for doing both
things from time to time.)

So, to answer the original question using “fence” terminology -

array = [:peanut, :butter, :and, :jelly]

array[4,0] => [] # why is this an empty array and not nil?
and
array[5,0] => nil # as expected

because there is a “post” at 4 and not at 5.

Dan N.

On Thu, Sep 8, 2011 at 10:15 PM, Gary W. [email protected] wrote:

On Sep 8, 2011, at 6:05 AM, Dan N. wrote:

The difference in the one-arg/two-arg indexing is ruby’s way of dealing with
the classic fence post problem. (i.e. A fence with 3 sections has 4 posts.)

I really like this analogy.

Yeah, but what about the grass on the other side? It’s still greener.
Darn.
:wink:

Cheers

robert

On Sep 8, 2011, at 6:05 AM, Dan N. wrote:

On Sep 8, 2011, at 4:08 AM, Adam P. wrote:

There’s discussion about this at String/array slices - Ruby - Ruby-Forum

Gary W.'s explanation in the thread linked above is very complete and clear.
Strongly recommended if you are at all foggy on this topic.

Thanks for the compliment. I thought I would also point out that while
my discussion
in that thread talks about string indexing it is equally applicable to
array
indexing. Good thing too because I would hate for the behavior to be
different.

I will add one terminology/memory tidbit -

The difference in the one-arg/two-arg indexing is ruby’s way of dealing with
the classic fence post problem. (i.e. A fence with 3 sections has 4 posts.)

I really like this analogy.

Gary W.

On Thu, Sep 8, 2011 at 2:00 PM, Gavin K. [email protected] wrote:

On Sep 8, 2011, at 2:08 AM, Adam P. wrote:

There’s discussion about this at String/array slices - Ruby - Ruby-Forum
Oh, and Feature #4541: Inconsistent Array.slice() - Ruby master - Ruby Issue Tracking System

Also discussed here:

and here:

And discussed in these threads:

[Which I think is useful in remembering the behaviour.]
Full thread in one piece is here:
http://www.ruby-forum.com/topic/215481
and here
http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/f09c65251c72ab6/9a125107e3186534?pli=1

On Sun, Sep 11, 2011 at 3:05 AM, Colin B.
[email protected] wrote:

Yeah, but what about the grass on the other side? It’s still greener. Darn.
I like that!

OffTopic, but vaguely relevant: Have you seen Norman MacLaren’s short
film Neighbours?
Neighbours by Norman McLaren - NFB
Fenceposts first appear at just after 3m50s into the 8m5s film.

No, I haven’t. Apparently there’s a technical issue - at least I
cannot view the movie.

Kind regards

robert

On Sun, Sep 11, 2011 at 5:10 PM, Robert K.
[email protected] wrote:

I really like this analogy.
cannot view the movie.

Kind regards
robert

OT: I tried last night and seemed to have problems viewing it then,
and also tried just now, and it seems OK. Curious.

On Fri, Sep 9, 2011 at 1:36 PM, Robert K.
[email protected] wrote:

On Thu, Sep 8, 2011 at 10:15 PM, Gary W. [email protected] wrote:

On Sep 8, 2011, at 6:05 AM, Dan N. wrote:

The difference in the one-arg/two-arg indexing is ruby’s way of dealing with
the classic fence post problem. (i.e. A fence with 3 sections has 4 posts.)

I really like this analogy.

Yeah, but what about the grass on the other side? It’s still greener. Darn.
I like that!

OffTopic, but vaguely relevant: Have you seen Norman MacLaren’s short
film Neighbours?

Fenceposts first appear at just after 3m50s into the 8m5s film.