array[4,0] returns [], but array[5,0] returns nil... why? [duplicate]
Possible Duplicate:
Array slicing in Ruby: looking for explanation for illogical behaviour (taken from Rubykoans.com)
I'm following Ruby Koans and I've gotten to a part that deals with an array that looks like this:
array = [:peanut, :butter, :and, :jelly]
One of the tests focuses on what array[4,0] returns, and another focuses on what array[5,0] returns.
There are only 4 elements in this array, meaning it goes up to array[3], correct? So why is array[4,0] returning a blank array while array[5,0] returns nil?
The two arguments version of the method behaves a little bit different than expected, you can get a full explanation by Gary Wright here.
The [i, n] form is identifying substring boundaries and not characters
The short answer is that you are defining a substring to either return or replace.
There is a zero-length string at the beginning and at the end that needs to be identifiable.
In the two-argument index, the positions are really the individual boundaries between the characters, and there is one such boundary after the last character.
array[4,0]:
len=0 and beg=4
beg > RARRAY_LEN => false
len == 0 => return ary_new(klass, 0) => []
array[5,0]:
len=0 and beg=5
beg > RARRAY_LEN => true => return Qnil => nil
array.c:rb_ary_subseq
VALUE
rb_ary_subseq(VALUE ary, long beg, long len)
{
VALUE klass;
if (beg > RARRAY_LEN(ary)) return Qnil;
if (beg < 0 || len < 0) return Qnil;
if (RARRAY_LEN(ary) < len || RARRAY_LEN(ary) < beg + len) {
len = RARRAY_LEN(ary) - beg;
}
klass = rb_obj_class(ary);
if (len == 0) return ary_new(klass, 0);
精彩评论