[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]