/* * call-seq: * array.fetch(index) -> obj * array.fetch(index, default ) -> obj * array.fetch(index) {|index| block } -> obj * * Tries to return the element at position <i>index</i>. If the index * lies outside the array, the first form throws an * <code>IndexError</code> exception, the second form returns * <i>default</i>, and the third form returns the value of invoking * the block, passing in the index. Negative values of <i>index</i> * count from the end of the array. * * a = [ 11, 22, 33, 44 ] * a.fetch(1) #=> 22 * a.fetch(-1) #=> 44 * a.fetch(4, 'cat') #=> "cat" * a.fetch(4) { |i| i*i } #=> 16 */ static VALUE rb_ary_fetch(argc, argv, ary) int argc; VALUE *argv; VALUE ary; { VALUE pos, ifnone; long block_given; long idx; rb_scan_args(argc, argv, "11", &pos, &ifnone); block_given = rb_block_given_p(); if (block_given && argc == 2) { rb_warn("block supersedes default value argument"); } idx = NUM2LONG(pos); if (idx < 0) { idx += RARRAY(ary)->len; } if (idx < 0 || RARRAY(ary)->len <= idx) { if (block_given) return rb_yield(pos); if (argc == 1) { rb_raise(rb_eIndexError, "index %ld out of array", idx); } return ifnone; } return RARRAY(ary)->ptr[idx]; }