From cecb9cae01206d069b4d19ad12850d57b1b7ba7a Mon Sep 17 00:00:00 2001 From: nobu Date: Mon, 18 Mar 2002 01:46:33 +0000 Subject: * enum.c (enum_inject): use the first iterated element as the initial value when omitted. * enum.c (inject_i): ditto. * enum.c (Init_Enumerable): Enumerable#inject now takes variable count arguments. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2215 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- enum.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'enum.c') diff --git a/enum.c b/enum.c index 82219e78d6..8a4f5bc4d0 100644 --- a/enum.c +++ b/enum.c @@ -180,20 +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; + + 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); + n = memo->u1.value; + + rb_gc_force_recycle((VALUE)memo); return n; } @@ -448,7 +465,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); -- cgit v1.2.3