From f4b13fabe618a5747dee135c5caf1795a73a77c5 Mon Sep 17 00:00:00 2001 From: knu Date: Thu, 11 Dec 2008 10:16:59 +0000 Subject: * enumerator.c (enum_each_with_object): Add Enumerable#each_with_object and Enumerator#with_object. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@20627 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 ++++ NEWS | 8 +++++++ enumerator.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9eb2302b46..88e9e4236b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Dec 11 19:08:38 2008 Akinori MUSHA + + * enumerator.c (enum_each_with_object): Add + Enumerable#each_with_object and Enumerator#with_object. + Wed Dec 10 21:35:12 2008 Kouhei Sutou * lib/rss/maker.rb (RSS::Maker.[]): add. diff --git a/NEWS b/NEWS index cd721ed5c6..64623b3f4d 100644 --- a/NEWS +++ b/NEWS @@ -26,6 +26,14 @@ with all sufficient information, see the ChangeLog file. New method with which replaces #choice. + * Enumerable#each_with_object + + New method. + + * Enumerator#with_object + + New method. + * Hash#default_proc= New method. diff --git a/enumerator.c b/enumerator.c index 896863a78a..71362c168c 100644 --- a/enumerator.c +++ b/enumerator.c @@ -208,6 +208,39 @@ enum_each_cons(obj, n) return Qnil; } +static VALUE +each_with_object_i(val, memo) + VALUE val, 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(obj, memo) + VALUE obj, 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)); static VALUE enumerator_allocate(klass) @@ -380,6 +413,44 @@ enumerator_with_index(obj) enumerator_with_index_i, (VALUE)&memo); } +static VALUE +enumerator_with_object_i(val, memo) + VALUE val, memo; +{ + return rb_yield_values(2, val, memo); +} + +/* + * call-seq: + * e.with_object(obj) {|(*args), memo_obj| ... } + * e.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. + * + */ +static VALUE +enumerator_with_object(obj, memo) + VALUE obj, memo; +{ + struct enumerator *e; + int argc = 0; + VALUE *argv = 0; + + RETURN_ENUMERATOR(obj, 1, &memo); + e = enumerator_ptr(obj); + if (e->args) { + argc = RARRAY_LEN(e->args); + argv = RARRAY_PTR(e->args); + } + rb_block_call(e->obj, e->meth, argc, argv, + enumerator_with_object_i, memo); + + return memo; +} + /* * call-seq: * e.next => object @@ -429,6 +500,7 @@ Init_Enumerator() rb_define_method(rb_mEnumerable, "enum_slice", enum_each_slice, 1); rb_define_method(rb_mEnumerable, "each_cons", enum_each_cons, 1); rb_define_method(rb_mEnumerable, "enum_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); @@ -438,7 +510,9 @@ Init_Enumerator() 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); + rb_define_method(rb_cEnumerator, "with_object", enumerator_with_object, 1); rb_define_method(rb_cEnumerator, "next", enumerator_next, 0); rb_define_method(rb_cEnumerator, "rewind", enumerator_rewind, 0); -- cgit v1.2.3