[#3228] Core support for Gems, and namespace — "Luke A. Kanies" <luke@...>

Hi all,

21 messages 2004/07/27
[#3230] Re: Core support for Gems, and namespace — Austin Ziegler <halostatue@...> 2004/07/27

On Tue, 27 Jul 2004 11:39:08 +0900, Luke A. Kanies <luke@madstop.com> wrote:

[#3234] Re: Core support for Gems, and namespace — "Luke A. Kanies" <luke@...> 2004/07/27

On Tue, 27 Jul 2004, Austin Ziegler wrote:

[#3238] Re: Core support for Gems, and namespace — Austin Ziegler <halostatue@...> 2004/07/27

On Wed, 28 Jul 2004 00:14:29 +0900, Luke A. Kanies <luke@madstop.com> wrote:

[PATCH] Array#index with block

From: George Ogata <g_ogata@...>
Date: 2004-07-07 12:31:41 UTC
List: ruby-core #3150
Hi,

there was discussion on ruby-talk[1] about letting Array#index (and
#rindex) take a block.  There was mild support for it, and no
opposition, so I was wondering if you would consider this patch.

Giving #index/#rindex a block would now return the first/last index
for which the block returns true (the block is given each array
element in turn).  Giving both an argument and a block causes an
ArgumentError.

Cheers.

[1] http://ruby-talk.org/cgi-bin/vframe.rb/ruby/ruby-talk/105314?105240-105468



diff -Naur ruby/array.c ruby.mod/array.c
--- ruby/array.c	2004-06-16 22:52:59.000000000 +1000
+++ ruby.mod/array.c	2004-07-07 20:47:55.000000000 +1000
@@ -967,54 +967,86 @@
 
 /*
  *  call-seq:
- *     array.index(obj)   =>  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.
- *     
+ *     array.index(obj)         =>  int or nil
+ *     array.index {|obj| ...}  =>  int or nil
+ *
+ *  Returns the index of the first object in <i>array</i> which is
+ *  <code>==</code> to <i>obj</i> (arg form) or for which the block
+ *  returns true (block form). 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 {|x| x == "b"}   #=> 1
+ *     a.index("z")             #=> nil
  */
 
 static VALUE
-rb_ary_index(ary, val)
+rb_ary_index(argc, argv, ary)
+    int argc;
+    VALUE *argv;
     VALUE ary;
-    VALUE val;
 {
     long i;
+    VALUE val;
 
-    for (i=0; i<RARRAY(ary)->len; i++) {
-	if (rb_equal(RARRAY(ary)->ptr[i], val))
-	    return LONG2NUM(i);
+    if (rb_block_given_p()) {
+	if (argc != 0)
+	    rb_raise(rb_eArgError, "no argument allowed if block is given");
+	for (i=0; i<RARRAY(ary)->len; i++) {
+	    if (rb_yield(RARRAY(ary)->ptr[i]))
+		return LONG2NUM(i);
+	}
+    }
+    else {
+	rb_scan_args(argc, argv, "10", &val);
+	for (i=0; i<RARRAY(ary)->len; i++) {
+	    if (rb_equal(RARRAY(ary)->ptr[i], val))
+		return LONG2NUM(i);
+	}
     }
     return Qnil;
 }
 
 /*
  *  call-seq:
- *     array.rindex(obj)    =>  int or nil
- *  
- *  Returns the index of the last object in <i>arr</i> 
- *  <code>==</code> to <i>obj</i>. Returns <code>nil</code> if
- *  no match is found.
- *     
+ *     array.rindex(obj)         =>  int or nil
+ *     array.rindex {|obj| ...}  =>  int or nil
+ *
+ *  Returns the index of the last object in <i>array</i> which is
+ *  <code>==</code> to <i>obj</i> (arg form) or for which the block
+ *  returns true (block form). 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 {|x| x == "b"}   #=> 3
+ *     a.rindex("z")             #=> nil
  */
 
 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;
+    VALUE val;
 
-    while (i--) {
-	if (rb_equal(RARRAY(ary)->ptr[i], val))
-	    return LONG2NUM(i);
+    if (rb_block_given_p()) {
+	if (argc != 0)
+	    rb_raise(rb_eArgError, "no argument allowed if block is given");
+	while (i--) {
+	    if (rb_yield(RARRAY(ary)->ptr[i]))
+		return LONG2NUM(i);
+	}
+    }
+    else {
+	rb_scan_args(argc, argv, "10", &val);
+	while (i--) {
+	    if (rb_equal(RARRAY(ary)->ptr[i], val))
+		return LONG2NUM(i);
+	}
     }
     return Qnil;
 }
@@ -3065,8 +3097,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, "join", rb_ary_join_m, -1);
     rb_define_method(rb_cArray, "reverse", rb_ary_reverse_m, 0);
     rb_define_method(rb_cArray, "reverse!", rb_ary_reverse_bang, 0);


In This Thread

Prev Next