Array#index to take block; fix #2968 close #2970
authorYukihiro "Matz" Matsumoto <[email protected]>
Thu, 1 Oct 2015 13:35:06 +0000 (1 22:35 +0900)
committerYukihiro "Matz" Matsumoto <[email protected]>
Thu, 1 Oct 2015 13:35:06 +0000 (1 22:35 +0900)
mrbgems/mruby-array-ext/mrblib/array.rb
mrbgems/mruby-array-ext/test/array.rb
src/array.c

index 1f1d973..35be793 100644 (file)
@@ -681,4 +681,32 @@ class Array
     return nil if self.size == result.size
     self.replace(result)
   end
+
+  ##
+  #  call-seq:
+  #     ary.index(val)            -> int or nil
+  #     ary.index {|item| block } ->  int or nil
+  #
+  #  Returns the _index_ of the first object in +ary+ such that the object is
+  #  <code>==</code> to +obj+.
+  #
+  #  If a block is given instead of an argument, returns the _index_ of the
+  #  first object for which the block returns +true+.  Returns +nil+ if no
+  #  match is found.
+  #
+  # ISO 15.2.12.5.14
+  def index(val=NONE, &block)
+    return to_enum(:find_index, val) if !block && val == NONE
+
+    if block
+      idx = 0
+      self.each do |*e|
+        return idx if block.call(*e)
+        idx += 1
+      end
+    else
+      return self.__ary_index(val)
+    end
+    nil
+  end
 end
index 8c919f7..6c2f523 100644 (file)
@@ -293,3 +293,8 @@ assert('Array#to_h') do
   assert_raise(TypeError)     { [1].to_h }
   assert_raise(ArgumentError) { [[1]].to_h }
 end
+
+assert("Array#index (block)") do
+  assert_nil (1..10).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
+  assert_equal 34, (1..100).to_a.index { |i| i % 5 == 0 and i % 7 == 0 }
+end
index 2622ee5..aa91495 100644 (file)
@@ -1101,4 +1101,5 @@ mrb_init_array(mrb_state *mrb)
 
   mrb_define_method(mrb, a, "__ary_eq",        mrb_ary_eq,           MRB_ARGS_REQ(1));
   mrb_define_method(mrb, a, "__ary_cmp",       mrb_ary_cmp,          MRB_ARGS_REQ(1));
+  mrb_define_method(mrb, a, "__ary_index",     mrb_ary_index_m,      MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */
 }