I believe I've tracked it down.
See this:
https://www.omniref.com/ruby/2.1.2/symbols/Array/[]#line=1261
which calls rb_ary_subseq
http://rxr.whitequark.org/mri/source/array.c#1126
1. In the case where you passed in 5, it's larger than the length of the
array, so you get nil.
2. In the case where you passed in 4, it's the same as the length of the
array. You passed in zero (0) as the 2nd param, which maps to "len" in
the C code.
It goes to this line: http://rxr.whitequark.org/mri/source/array.c#1137
if (len <http://rxr.whitequark.org/mri/ident?i=len> == 0)return ary_new <http://rxr.whitequark.org/mri/ident?i=ary_new>\(klass <http://rxr.whitequark.org/mri/ident?i=klass>, 0);
Then it goes here: http://rxr.whitequark.org/mri/source/array.c#399
ary_new <http://rxr.whitequark.org/mri/ident?i=ary_new>\(VALUE
<http://rxr.whitequark.org/mri/ident?i=VALUE> klass
<http://rxr.whitequark.org/mri/ident?i=klass>, long capa
<http://rxr.whitequark.org/mri/ident?i=capa> )
And then this line:http://rxr.whitequark.org/mri/source/array.c#423
ary <http://rxr.whitequark.org/mri/ident?i=ary> =ary_alloc <http://rxr.whitequark.org/mri/ident?i=ary_alloc>\(klass <http://rxr.whitequark.org/mri/ident?i=klass>\);
which is why you get an array of zero elements.
On Thu, Nov 13, 2014 at 1:42 PM, Rob Biedenharn > <rob.biedenharn@gmail.com <mailto:rob.biedenharn@gmail.com>> wrote:
On 2014-Nov-13, at 12:39 , George Drummond <drummond@rentify.com > <mailto:drummond@rentify.com>> wrote:
It is kind of strange.
If you look at the examples section there is a "special cases"
list and your example appears there.
I don't know the reasons for this.
Here's how *I* think about it:
[ :a, :b, :c, ]
^ ^ ^ ^ ^ ^
0 1 2 3 4
-4 -3 -2 -1
If the index "points" to positions "between" the actual elements,
then you can treat the index 3 (in this case) as still being
"inside" the Array brackets, but 4 is outside. If a slice starts
"inside" the Array, it returns an Array, but if you completely
"miss" the Array, you get nil.
example = [ :a, :b, :c, ]
(-4..4).each do |i|
puts "example[#{i}] \t\#=> #{example[i].inspect}"
puts "example[#{i},2]\t\#=> #{example[i,2].inspect}"
end
example[-4] #=> nil
example[-4,2]#=> nil
example[-3] #=> :a
example[-3,2]#=> [:a, :b]
example[-2] #=> :b
example[-2,2]#=> [:b, :c]
example[-1] #=> :c
example[-1,2]#=> [:c]
example[0] #=> :a
example[0,2]#=> [:a, :b]
example[1] #=> :b
example[1,2]#=> [:b, :c]
example[2] #=> :c
example[2,2]#=> [:c]
example[3] #=> nil
example[3,2]#=>
example[4] #=> nil
example[4,2]#=> nil
Note that [2,2] can't actually give 2 elements because the Array is
exhausted, but it returns what it can. [3,2] is similar: it runs out
of elements before it find even one, but it starts "inside" so it
gives an Array in return.
-Rob
On Thu, Nov 13, 2014 at 5:32 PM, leam hall <leamhall@gmail.com >> <mailto:leamhall@gmail.com>> wrote:
On Thu, Nov 13, 2014 at 12:18 PM, George Drummond >> <drummond@rentify.com <mailto:drummond@rentify.com>> wrote:
Specifically the last line of documentation for this
method: "Returns |nil| if the index (or starting index)
are out of range."
The nil part makes sense. What I don't get is why the first
out of range, "4", didn't also get nil. The indices should be
0..3, right?
--
Mind on a Mission <http://leamhall.blogspot.com/>
--
George Drummond
Software Engineer
+44 (0)333 240 2222 <tel:%2B44%20%280%29333%20240%202222>
Rentify
6-8 Long Lane, London EC1A 9HF
www.rentify.com <https://www.rentify.com/>