From 3e8c3897abe511678b1c8455b5441f95151089c9 Mon Sep 17 00:00:00 2001 From: knu Date: Tue, 26 Aug 2008 05:45:18 +0000 Subject: [PATCH] * enumerator.c: Activate Enumerator#with_object and add Enumerable#each_with_object. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18864 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ doc/NEWS | 2 ++ enumerator.c | 41 +++++++++++++++++++++++++++++++++++------ 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4479dc7139..2602d73fed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Tue Aug 26 14:43:10 2008 Akinori MUSHA + + * enumerator.c: Activate Enumerator#with_object and add + Enumerable#each_with_object. + Tue Aug 26 14:38:32 2008 Akinori MUSHA * enumerator.c (enumerator_initialize), diff --git a/doc/NEWS b/doc/NEWS index ca5d511ebe..77ecf74178 100644 --- a/doc/NEWS +++ b/doc/NEWS @@ -111,6 +111,8 @@ Compatible * Enumerable and Enumerator o Enumerable#map,collect_all called without a block returns an enumerator. + o Enumerable#each_with_object [experimental] + o Enumerator#with_object [experimental] o Enumerator.new { ... } [experimental] * Regexp#match, String#match o Regexp#match, String#match diff --git a/enumerator.c b/enumerator.c index 240641d909..f7fbd7218c 100644 --- a/enumerator.c +++ b/enumerator.c @@ -216,6 +216,37 @@ enum_each_cons(VALUE obj, VALUE n) return Qnil; } +static VALUE +each_with_object_i(VALUE val, VALUE memo) +{ + return rb_yield_values(2, val, memo); +} + +/* + * call-seq: + * each_with_object(obj) {|(*args), memo_obj| ... } + * each_with_object(obj) + * + * Iterates the given block for each element with an arbitrary + * object given, and returns the initially given object. + + * If no block is given, returns an enumerator. + * + * e.g.: + * evens = (1..10).each_with_object([]) {|i, a| a << i*2 } + * # => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] + * + */ +static VALUE +enum_each_with_object(VALUE obj, VALUE memo) +{ + RETURN_ENUMERATOR(obj, 1, &memo); + + rb_block_call(obj, SYM2ID(sym_each), 0, 0, each_with_object_i, memo); + + return memo; +} + static VALUE enumerator_allocate(VALUE klass) { @@ -412,7 +443,7 @@ enumerator_with_object_i(VALUE val, VALUE memo) * e.with_object(obj) * * Iterates the given block for each element with an arbitrary - * object given, and returns memo object. + * object given, and returns the initially given object. * * If no block is given, returns an enumerator. * @@ -424,7 +455,7 @@ enumerator_with_object(VALUE obj, VALUE memo) int argc = 0; VALUE *argv = 0; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_ENUMERATOR(obj, 1, &memo); e = enumerator_ptr(obj); if (e->args) { argc = RARRAY_LEN(e->args); @@ -734,6 +765,7 @@ Init_Enumerator(void) rb_define_method(rb_mEnumerable, "each_slice", enum_each_slice, 1); rb_define_method(rb_mEnumerable, "each_cons", enum_each_cons, 1); + rb_define_method(rb_mEnumerable, "each_with_object", enum_each_with_object, 1); rb_cEnumerator = rb_define_class("Enumerator", rb_cObject); rb_include_module(rb_cEnumerator, rb_mEnumerable); @@ -743,12 +775,9 @@ Init_Enumerator(void) rb_define_method(rb_cEnumerator, "initialize_copy", enumerator_init_copy, 1); rb_define_method(rb_cEnumerator, "each", enumerator_each, 0); rb_define_method(rb_cEnumerator, "each_with_index", enumerator_with_index, 0); + rb_define_method(rb_cEnumerator, "each_with_object", enumerator_with_object, 1); rb_define_method(rb_cEnumerator, "with_index", enumerator_with_index, 0); -#if 0 rb_define_method(rb_cEnumerator, "with_object", enumerator_with_object, 1); -#else - (void)enumerator_with_object; -#endif rb_define_method(rb_cEnumerator, "next", enumerator_next, 0); rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0);