Arup Rakshit
Arup Rakshit

Reputation: 118271

Confusion with `Array#[]` output in IRB

I was playing with Array#[] in my IRB to learn it. All my tries are below:

Below code is understood.

[2,3][0..1]
#=> [2, 3]

Why does the below code giving empty array?

[2,3][-1,0]
#=> []

But why does the code giving nil value?

[2,3][0,-1]
#=> nil

Upvotes: 0

Views: 69

Answers (1)

Sam
Sam

Reputation: 3067

[2,3][1,2] will start at the index 1 and select the next 2 values.

[2,3][-1,0] will start at the index -1 and select the next 0 values. -1 starts from the end of the array and works backwards.

EDIT:

To answer the updated question, [2,3][0,-1] would start at the index 0 but since you can't have a negative number for the length, it will return nil.

If you wanted to select the value before the index, just decrease the index by 1 and have the length as 1.

EDIT2:

Ruby wasn't designed to accept a negative length value but was designed to accept a negative starting value.

Also, in the docs "Additionally, an empty array is returned when the starting index for an element range is at the end of the array." - http://www.ruby-doc.org/core-2.0/Array.html#method-i-5B-5D

After drilling down through the Ruby source code, the rb_ary_subseq function will return nil if either the starting index or length values are less than zero.

But before the rb_ary_subseq is called, the rb_ary_aref function changes the negative starting index value to a positive with start += array.length to give the same effect.

There is no code to make the negative length conversion.

So [2,3][-1,0] will return an empty array because the length isn't less than zero and because of the description in the docs referenced.

[2,3][0,-1] will return nil because the length is less than zero.

Source code links:

rb_ary_aref - http://rxr.whitequark.org/mri/source/array.c#1042

rb_ary_subseq - http://rxr.whitequark.org/mri/source/array.c#989

Upvotes: 3

Related Questions