Created
April 14, 2011 21:02
-
-
Save afcapel/920541 to your computer and use it in GitHub Desktop.
Snippet from array.c in ruby-1.9.2-p136
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* call-seq: | |
* ary[index] -> obj or nil | |
* ary[start, length] -> new_ary or nil | |
* ary[range] -> new_ary or nil | |
* ary.slice(index) -> obj or nil | |
* ary.slice(start, length) -> new_ary or nil | |
* ary.slice(range) -> new_ary or nil | |
* | |
* Element Reference---Returns the element at _index_, | |
* or returns a subarray starting at _start_ and | |
* continuing for _length_ elements, or returns a subarray | |
* specified by _range_. | |
* Negative indices count backward from the end of the | |
* array (-1 is the last element). Returns +nil+ if the index | |
* (or starting index) are out of range. | |
* | |
* a = [ "a", "b", "c", "d", "e" ] | |
* a[2] + a[0] + a[1] #=> "cab" | |
* a[6] #=> nil | |
* a[1, 2] #=> [ "b", "c" ] | |
* a[1..3] #=> [ "b", "c", "d" ] | |
* a[4..7] #=> [ "e" ] | |
* a[6..10] #=> nil | |
* a[-3, 3] #=> [ "c", "d", "e" ] | |
* # special cases | |
* a[5] #=> nil | |
* a[5, 1] #=> [] | |
* a[5..10] #=> [] | |
* | |
*/ | |
VALUE | |
rb_ary_aref(int argc, VALUE *argv, VALUE ary) | |
{ | |
VALUE arg; | |
long beg, len; | |
if (argc == 2) { | |
beg = NUM2LONG(argv[0]); | |
len = NUM2LONG(argv[1]); | |
if (beg < 0) { | |
beg += RARRAY_LEN(ary); | |
} | |
return rb_ary_subseq(ary, beg, len); | |
} | |
if (argc != 1) { | |
rb_scan_args(argc, argv, "11", 0, 0); | |
} | |
arg = argv[0]; | |
/* special case - speeding up */ | |
if (FIXNUM_P(arg)) { | |
return rb_ary_entry(ary, FIX2LONG(arg)); | |
} | |
/* check if idx is Range */ | |
switch (rb_range_beg_len(arg, &beg, &len, RARRAY_LEN(ary), 0)) { | |
case Qfalse: | |
break; | |
case Qnil: | |
return Qnil; | |
default: | |
return rb_ary_subseq(ary, beg, len); | |
} | |
return rb_ary_entry(ary, NUM2LONG(arg)); | |
} | |
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); | |
return ary_make_partial(ary, klass, beg, len); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment