新井です。

ruby-dev に行ってみます。

In message "[ruby-list:34301] Re: Enumerable#inject (Re:しぶらぐっ議事録。)"
  on 11 Mar 2002 12:58:59 +0900,
  matz / ruby-lang.org (Yukihiro Matsumoto) wrote:
> まつもと ゆきひろです
> 
> In message "[ruby-list:34276] Re: Enumerable#inject (Re: しぶらぐっ議事録。)"
>     on 02/03/10, Koji Arai <JCA02266 / nifty.ne.jp> writes:
> 
> |Python ではそうですね。しかし、やっぱり名前問題になるんです
> |ねえ。
> 
> それがすべての問題の本質だからです。

あっ、別に否定的な気持ちで言ったわけではないです。念のため。

知らなかったんですが、Python の reduce は、初期値を指定でき
ますね。で、ruby でどうするか?ですが

1. Enumerable#inject を Enumerable#reduce にし、初期値を省略可にする
2. Enumerable#inject が初期値を省略できるようにする
3. 現状維持

私的には名前はそのままでもいいのではないかと、ですから 2 で
良いように思います。

取り込まれやすさを狙ってパッチをつけてみます。

Index: enum.c
===================================================================
RCS file: /usr/local/cvsup/ruby/ruby/enum.c,v
retrieving revision 1.22
diff -u -p -r1.22 enum.c
--- enum.c	11 Mar 2002 08:02:02 -0000	1.22
+++ enum.c	15 Mar 2002 23:57:41 -0000
@@ -180,21 +180,37 @@ enum_collect(obj)
 }
 
 static VALUE
-inject_i(i, np)
+inject_i(i, memo)
     VALUE i;
-    VALUE *np;
+    NODE *memo;
 {
-    *np = rb_yield(rb_assoc_new(*np, i));
+    if (memo->u2.value) {
+        memo->u2.value = Qfalse;
+        memo->u1.value = i;
+    }
+    else
+        memo->u1.value = rb_yield(rb_assoc_new(memo->u1.value, i));
+
     return Qnil;
 }
 
 static VALUE
-enum_inject(obj, n)
-    VALUE obj, n;
+enum_inject(argc, argv, obj)
+    int argc;
+    VALUE *argv, obj;
 {
-    rb_iterate(rb_each, obj, inject_i, (VALUE)&n);
+    NODE *memo;
+    VALUE n;
 
-    return n;
+    if (rb_scan_args(argc, argv, "01", &n) == 1)
+        memo = rb_node_newnode(NODE_MEMO, n, Qfalse, 0);
+    else
+        memo = rb_node_newnode(NODE_MEMO, Qnil, Qtrue, 0);
+
+    rb_iterate(rb_each, obj, inject_i, (VALUE)memo);
+
+    rb_gc_force_recycle((VALUE)memo);
+    return memo->u1.value;
 }
 
 static VALUE
@@ -448,7 +464,7 @@ Init_Enumerable()
     rb_define_method(rb_mEnumerable,"reject", enum_reject, 0);
     rb_define_method(rb_mEnumerable,"collect", enum_collect, 0);
     rb_define_method(rb_mEnumerable,"map", enum_collect, 0);
-    rb_define_method(rb_mEnumerable,"inject", enum_inject, 1);
+    rb_define_method(rb_mEnumerable,"inject", enum_inject, -1);
     rb_define_method(rb_mEnumerable,"all?", enum_all, 0);
     rb_define_method(rb_mEnumerable,"any?", enum_any, 0);
     rb_define_method(rb_mEnumerable,"min", enum_min, 0);

--
新井康司 (Koji Arai)