From 970e90dd1572994d3d9229725e12d47b3674fcbf Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 2 Feb 2010 08:54:52 +0000 Subject: * enum.c (enum_each_entry): new method #each_entry to pack values from yield into an array. * lib/set.rb (Set#merge): use Enumerable#each_entry to implement Set compatible to 1.8 behavior. [ruby-core:27985] * lib/set.rb: replace is_a?(Enumerable) with respond_to?(:each) for duck typing. * lib/set.rb (SortedSet#add): typo fixed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26540 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- enum.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'enum.c') diff --git a/enum.c b/enum.c index 7212279223..3c59449362 100644 --- a/enum.c +++ b/enum.c @@ -1617,6 +1617,46 @@ enum_reverse_each(int argc, VALUE *argv, VALUE obj) } +static VALUE +each_val_i(VALUE i, VALUE p, int argc, VALUE *argv) +{ + VALUE *memo = (VALUE *)p; + + ENUM_WANT_SVALUE(); + rb_yield(i); + return Qnil; +} + +/* + * call-seq: + * enum.each_entry {|obj| block} => enum + * + * Calls block once for each element in self, passing that + * element as a parameter, converting multiple values from yield to an + * array. + * + * class Foo + * include Enumerable + * def each + * yield 1 + * yield 1,2 + * end + * end + * Foo.new.each_entry{|o| print o, " -- "} + * + * produces: + * + * 1 -- [1, 2] -- + */ + +static VALUE +enum_each_entry(int argc, VALUE *argv, VALUE obj) +{ + RETURN_ENUMERATOR(obj, argc, argv); + rb_block_call(obj, id_each, argc, argv, each_val_i, 0); + return obj; +} + static VALUE zip_ary(VALUE val, NODE *memo, int argc, VALUE *argv) { @@ -2435,6 +2475,7 @@ Init_Enumerable(void) rb_define_method(rb_mEnumerable, "include?", enum_member, 1); rb_define_method(rb_mEnumerable, "each_with_index", enum_each_with_index, -1); rb_define_method(rb_mEnumerable, "reverse_each", enum_reverse_each, -1); + rb_define_method(rb_mEnumerable, "each_entry", enum_each_entry, -1); rb_define_method(rb_mEnumerable, "zip", enum_zip, -1); rb_define_method(rb_mEnumerable, "take", enum_take, 1); rb_define_method(rb_mEnumerable, "take_while", enum_take_while, 0); -- cgit v1.2.3