diff --git a/array.c b/array.c index 5a8d8dc..2c8944e 100644 --- a/array.c +++ b/array.c @@ -1490,6 +1490,39 @@ rb_ary_rindex(int argc, VALUE *argv, VALUE ary) return Qnil; } +/* + * call-seq: + * ary.has_index?(idx) -> true or false + * ary.index?(idx) -> true or false + * + * Returns true if the given index is present in ary. + * + * a = [ "a", "b", "c" ] + * h.has_index?(0) #=> true + * h.has_index?(2) #=> true + * h.has_index?(3) #=> false + * h.has_index?(-1) #=> true + * h.has_index?(-4) #=> false + * + */ + +static VALUE +rb_ary_has_index(VALUE ary, VALUE pos) +{ + VALUE val; + long idx; + + idx = NUM2LONG(pos); + + if (idx < 0) { + idx += RARRAY_LEN(ary); + } + if (idx < 0 || RARRAY_LEN(ary) <= idx) { + return Qfalse; + } + return Qtrue; +} + VALUE rb_ary_to_ary(VALUE obj) { @@ -5596,6 +5629,8 @@ Init_Array(void) rb_define_method(rb_cArray, "clear", rb_ary_clear, 0); rb_define_method(rb_cArray, "fill", rb_ary_fill, -1); rb_define_method(rb_cArray, "include?", rb_ary_includes, 1); + rb_define_method(rb_cArray, "has_index?", rb_ary_has_index, 1); + rb_define_method(rb_cArray, "index?", rb_ary_has_index, 1); rb_define_method(rb_cArray, "<=>", rb_ary_cmp, 1); rb_define_method(rb_cArray, "slice", rb_ary_aref, -1); diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index b4f35af..98a0183 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -932,6 +932,16 @@ class TestArray < Test::Unit::TestCase assert_equal(1, a.index(99) {|x| x == 'cat' }) end + def test_has_index + a = @cls[ 'cat', 99, /a/, 99, @cls[ 1, 2, 3] ] + assert( a.has_index?(0)) + assert( a.has_index?(4)) + assert(! a.has_index?(5)) + assert( a.has_index?(-1)) + assert( a.has_index?(-5)) + assert(! a.has_index?(-6)) + end + def test_values_at a = @cls[*('a'..'j').to_a] assert_equal(@cls['a', 'c', 'e'], a.values_at(0, 2, 4))