ruby-changes:9091
From: knu <ko1@a...>
Date: Thu, 11 Dec 2008 19:17:26 +0900 (JST)
Subject: [ruby-changes:9091] Ruby:r20627 (ruby_1_8): * enumerator.c (enum_each_with_object): Add
knu 2008-12-11 19:16:59 +0900 (Thu, 11 Dec 2008) New Revision: 20627 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=20627 Log: * enumerator.c (enum_each_with_object): Add Enumerable#each_with_object and Enumerator#with_object. Modified files: branches/ruby_1_8/ChangeLog branches/ruby_1_8/NEWS branches/ruby_1_8/enumerator.c Index: ruby_1_8/NEWS =================================================================== --- ruby_1_8/NEWS (revision 20626) +++ ruby_1_8/NEWS (revision 20627) @@ -26,6 +26,14 @@ New method with which replaces #choice. + * Enumerable#each_with_object + + New method. + + * Enumerator#with_object + + New method. + * Hash#default_proc= New method. Index: ruby_1_8/ChangeLog =================================================================== --- ruby_1_8/ChangeLog (revision 20626) +++ ruby_1_8/ChangeLog (revision 20627) @@ -1,3 +1,8 @@ +Thu Dec 11 19:08:38 2008 Akinori MUSHA <knu@i...> + + * 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@c...> * lib/rss/maker.rb (RSS::Maker.[]): add. Index: ruby_1_8/enumerator.c =================================================================== --- ruby_1_8/enumerator.c (revision 20626) +++ ruby_1_8/enumerator.c (revision 20627) @@ -208,6 +208,39 @@ 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,7 +413,45 @@ 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 @@ 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 @@ 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); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/