ruby-changes:25450
From: marcandre <ko1@a...>
Date: Wed, 7 Nov 2012 02:12:47 +0900 (JST)
Subject: [ruby-changes:25450] marcandRe: r37507 (trunk): * enum.c: Support for enumerators created by Enumerable with forwarding:
marcandre 2012-11-07 02:12:35 +0900 (Wed, 07 Nov 2012) New Revision: 37507 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=37507 Log: * enum.c: Support for enumerators created by Enumerable with forwarding: find_all, reject, ... [Feature #6636] Modified files: trunk/enum.c trunk/test/ruby/test_enumerator.rb Index: enum.c =================================================================== --- enum.c (revision 37506) +++ enum.c (revision 37507) @@ -305,6 +305,14 @@ return Qnil; } +static VALUE +enum_size(VALUE self, VALUE args) +{ + VALUE r; + r = rb_check_funcall(self, id_size, 0, 0); + return (r == Qundef) ? Qnil : r; +} + /* * call-seq: * enum.find_all { |obj| block } -> array @@ -330,7 +338,7 @@ { VALUE ary; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); ary = rb_ary_new(); rb_block_call(obj, id_each, 0, 0, find_all_i, ary); @@ -371,7 +379,7 @@ { VALUE ary; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); ary = rb_ary_new(); rb_block_call(obj, id_each, 0, 0, reject_i, ary); @@ -418,7 +426,7 @@ { VALUE ary; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); ary = rb_ary_new(); rb_block_call(obj, id_each, 0, 0, collect_i, ary); @@ -465,7 +473,7 @@ { VALUE ary; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); ary = rb_ary_new(); rb_block_call(obj, id_each, 0, 0, flat_map_i, ary); @@ -640,7 +648,7 @@ { NODE *memo; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); memo = NEW_MEMO(rb_ary_new(), rb_ary_new(), 0); rb_block_call(obj, id_each, 0, 0, partition_i, (VALUE)memo); @@ -688,7 +696,7 @@ { VALUE hash; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); hash = rb_hash_new(); rb_block_call(obj, id_each, 0, 0, group_by_i, hash); @@ -897,7 +905,7 @@ long i; struct sort_by_data *data; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); if (RB_TYPE_P(obj, T_ARRAY) && RARRAY_LEN(obj) <= LONG_MAX/2) { ary = rb_ary_new2(RARRAY_LEN(obj)*2); @@ -1437,7 +1445,7 @@ { NODE *memo; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); memo = NEW_MEMO(Qundef, Qnil, 0); rb_block_call(obj, id_each, 0, 0, min_by_i, (VALUE)memo); @@ -1483,7 +1491,7 @@ { NODE *memo; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); memo = NEW_MEMO(Qundef, Qnil, 0); rb_block_call(obj, id_each, 0, 0, max_by_i, (VALUE)memo); @@ -1581,7 +1589,7 @@ VALUE memo; struct minmax_by_t *m = NEW_MEMO_FOR(struct minmax_by_t, memo); - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_SIZED_ENUMERATOR(obj, 0, 0, enum_size); m->min_bv = Qundef; m->max_bv = Qundef; @@ -1662,7 +1670,7 @@ { NODE *memo; - RETURN_ENUMERATOR(obj, argc, argv); + RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size); memo = NEW_MEMO(0, 0, 0); rb_block_call(obj, id_each, argc, argv, each_with_index_i, (VALUE)memo); @@ -1694,7 +1702,7 @@ VALUE ary; long i; - RETURN_ENUMERATOR(obj, argc, argv); + RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size); ary = enum_to_a(argc, argv, obj); @@ -1746,7 +1754,7 @@ static VALUE enum_each_entry(int argc, VALUE *argv, VALUE obj) { - RETURN_ENUMERATOR(obj, argc, argv); + RETURN_SIZED_ENUMERATOR(obj, argc, argv, enum_size); rb_block_call(obj, id_each, argc, argv, each_val_i, 0); return obj; } @@ -1882,7 +1890,7 @@ static VALUE enum_each_with_object(VALUE obj, VALUE memo) { - RETURN_ENUMERATOR(obj, 1, &memo); + RETURN_SIZED_ENUMERATOR(obj, 1, &memo, enum_size); rb_block_call(obj, id_each, 0, 0, each_with_object_i, memo); Index: test/ruby/test_enumerator.rb =================================================================== --- test/ruby/test_enumerator.rb (revision 37506) +++ test/ruby/test_enumerator.rb (revision 37507) @@ -10,6 +10,10 @@ a.each {|x| yield x } end end + @sized = @obj.clone + def @sized.size + 42 + end end def enum_test obj @@ -429,6 +433,16 @@ end end + def test_size_for_enum_created_from_enumerable + %i[find_all reject map flat_map partition group_by sort_by min_by max_by + minmax_by each_with_index reverse_each each_entry].each do |method| + assert_equal nil, @obj.send(method).size + assert_equal 42, @sized.send(method).size + end + assert_equal nil, @obj.each_with_object(nil).size + assert_equal 42, @sized.each_with_object(nil).size + end + def check_consistency_for_combinatorics(method) [ [], [:a, :b, :c, :d, :e] ].product([-2, 0, 2, 5, 6]) do |array, arg| assert_equal array.send(method, arg).to_a.size, array.send(method, arg).size, -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/