[前][次][番号順一覧][スレッド一覧]

ruby-changes:4445

From: ko1@a...
Date: Wed, 9 Apr 2008 20:53:29 +0900 (JST)
Subject: [ruby-changes:4445] knu - Ruby:r15936 (ruby_1_8): * array.c (rb_ary_index, rb_ary_index): Array#index and #rindex

knu	2008-04-09 20:53:15 +0900 (Wed, 09 Apr 2008)

  New Revision: 15936

  Modified files:
    branches/ruby_1_8/ChangeLog
    branches/ruby_1_8/array.c

  Log:
    * array.c (rb_ary_index, rb_ary_index): Array#index and #rindex
      take a block instead of an argument; backported from 1.9.


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/ChangeLog?r1=15936&r2=15935&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/array.c?r1=15936&r2=15935&diff_format=u

Index: ruby_1_8/array.c
===================================================================
--- ruby_1_8/array.c	(revision 15935)
+++ ruby_1_8/array.c	(revision 15936)
@@ -848,26 +848,41 @@
 
 /*
  *  call-seq:
- *     array.index(obj)   ->  int or nil
+ *     array.index(obj)           ->  int or nil
+ *     array.index {|item| block} ->  int or nil
  *  
- *  Returns the index of the first object in <i>self</i> such that is 
- *  <code>==</code> to <i>obj</i>. Returns <code>nil</code> if
- *  no match is found.
+ *  Returns the index of the first object in <i>self</i> such that is
+ *  <code>==</code> to <i>obj</i>. If a block is given instead of an
+ *  argument, returns first object for which <em>block</em> is true.
+ *  Returns <code>nil</code> if no match is found.
  *     
  *     a = [ "a", "b", "c" ]
- *     a.index("b")   #=> 1
- *     a.index("z")   #=> nil
+ *     a.index("b")        #=> 1
+ *     a.index("z")        #=> nil
+ *     a.index{|x|x=="b"}  #=> 1
  */
 
 static VALUE
-rb_ary_index(ary, val)
+rb_ary_index(argc, argv, ary)
+    int argc;
+    VALUE *argv;
     VALUE ary;
+{
     VALUE val;
-{
     long i;
 
-    for (i=0; i<RARRAY(ary)->len; i++) {
-	if (rb_equal(RARRAY(ary)->ptr[i], val))
+    if (argc  == 0) {
+	RETURN_ENUMERATOR(ary, 0, 0);
+	for (i=0; i<RARRAY_LEN(ary); i++) {
+	    if (RTEST(rb_yield(RARRAY_PTR(ary)[i]))) {
+		return LONG2NUM(i);
+	    }
+	}
+	return Qnil;
+    }
+    rb_scan_args(argc, argv, "01", &val);
+    for (i=0; i<RARRAY_LEN(ary); i++) {
+	if (rb_equal(RARRAY_PTR(ary)[i], val))
 	    return LONG2NUM(i);
     }
     return Qnil;
@@ -877,29 +892,44 @@
  *  call-seq:
  *     array.rindex(obj)    ->  int or nil
  *  
- *  Returns the index of the last object in <i>array</i> 
- *  <code>==</code> to <i>obj</i>. Returns <code>nil</code> if
- *  no match is found.
+ *  Returns the index of the last object in <i>array</i>
+ *  <code>==</code> to <i>obj</i>. If a block is given instead of an
+ *  argument, returns first object for which <em>block</em> is
+ *  true. Returns <code>nil</code> if no match is found.
  *     
  *     a = [ "a", "b", "b", "b", "c" ]
- *     a.rindex("b")   #=> 3
- *     a.rindex("z")   #=> nil
+ *     a.rindex("b")        #=> 3
+ *     a.rindex("z")        #=> nil
+ *     a.rindex{|x|x=="b"}  #=> 3
  */
 
 static VALUE
-rb_ary_rindex(ary, val)
+rb_ary_rindex(argc, argv, ary)
+    int argc;
+    VALUE *argv;
     VALUE ary;
+{
     VALUE val;
-{
-    long i = RARRAY(ary)->len;
+    long i = RARRAY_LEN(ary);
 
+    if (argc == 0) {
+	RETURN_ENUMERATOR(ary, 0, 0);
+	while (i--) {
+	    if (RTEST(rb_yield(RARRAY_PTR(ary)[i])))
+		return LONG2NUM(i);
+	    if (i > RARRAY_LEN(ary)) {
+		i = RARRAY_LEN(ary);
+	    }
+	}
+	return Qnil;
+    }
+    rb_scan_args(argc, argv, "01", &val);
     while (i--) {
-	if (i > RARRAY(ary)->len) {
-	    i = RARRAY(ary)->len;
-	    continue;
+	if (rb_equal(RARRAY_PTR(ary)[i], val))
+	    return LONG2NUM(i);
+	if (i > RARRAY_LEN(ary)) {
+	    i = RARRAY_LEN(ary);
 	}
-	if (rb_equal(RARRAY(ary)->ptr[i], val))
-	    return LONG2NUM(i);
     }
     return Qnil;
 }
@@ -3036,8 +3066,8 @@
     rb_define_method(rb_cArray, "length", rb_ary_length, 0);
     rb_define_alias(rb_cArray,  "size", "length");
     rb_define_method(rb_cArray, "empty?", rb_ary_empty_p, 0);
-    rb_define_method(rb_cArray, "index", rb_ary_index, 1);
-    rb_define_method(rb_cArray, "rindex", rb_ary_rindex, 1);
+    rb_define_method(rb_cArray, "index", rb_ary_index, -1);
+    rb_define_method(rb_cArray, "rindex", rb_ary_rindex, -1);
     rb_define_method(rb_cArray, "indexes", rb_ary_indexes, -1);
     rb_define_method(rb_cArray, "indices", rb_ary_indexes, -1);
     rb_define_method(rb_cArray, "join", rb_ary_join_m, -1);
Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog	(revision 15935)
+++ ruby_1_8/ChangeLog	(revision 15936)
@@ -1,3 +1,8 @@
+Wed Apr  9 20:47:16 2008  Akinori MUSHA  <knu@i...>
+
+	* array.c (rb_ary_index, rb_ary_index): Array#index and #rindex
+	  take a block instead of an argument; backported from 1.9.
+
 Wed Apr  9 19:58:31 2008  Akinori MUSHA  <knu@i...>
 
 	* enumerator.c, inits.c (rb_call_inits), ruby.h, intern.h,
@@ -2,3 +7,3 @@
 	  ext/enumerator, common.mk (OBJS, enumerator.$(OBJEXT)): Make the
-	  enumerator module built-in,
+	  enumerator module built-in.
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]