diff options
| author | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-12-11 10:16:59 +0000 |
|---|---|---|
| committer | knu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-12-11 10:16:59 +0000 |
| commit | f4b13fabe618a5747dee135c5caf1795a73a77c5 (patch) | |
| tree | 15feeadf3da16864cfadb37ca00a46ae1bdb872d | |
| parent | 14df5ba882e1dd411da0beb7d3cc2fdf8e5fb7a8 (diff) | |
* 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
| -rw-r--r-- | ChangeLog | 5 | ||||
| -rw-r--r-- | NEWS | 8 | ||||
| -rw-r--r-- | enumerator.c | 74 |
3 files changed, 87 insertions, 0 deletions
@@ -1,3 +1,8 @@ +Thu Dec 11 19:08:38 2008 Akinori MUSHA <knu@iDaemons.org> + + * enumerator.c (enum_each_with_object): Add + Enumerable#each_with_object and Enumerator#with_object. + Wed Dec 10 21:35:12 2008 Kouhei Sutou <kou@cozmixng.org> * lib/rss/maker.rb (RSS::Maker.[]): add. @@ -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); |
