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.
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
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.
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.)
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.
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.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.