Skip to content

Instantly share code, notes, and snippets.

@afcapel
Created April 14, 2011 21:02
Show Gist options
  • Save afcapel/920541 to your computer and use it in GitHub Desktop.
Save afcapel/920541 to your computer and use it in GitHub Desktop.
Snippet from array.c in ruby-1.9.2-p136
/*
* 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