From: Koji Arai Date: 2002-03-16T09:04:58+09:00 Subject: [ruby-dev:16423] Re: [ruby-list:34301] Re: Enumerable#inject (Re: しぶらぐっ議事録。) 新井です。 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 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)