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

ruby-changes:14692

From: matz <ko1@a...>
Date: Wed, 3 Feb 2010 10:30:01 +0900 (JST)
Subject: [ruby-changes:14692] Ruby:r26546 (trunk): * enumerator.c: move implementation of each_slice, each_cons,

matz	2010-02-03 10:29:44 +0900 (Wed, 03 Feb 2010)

  New Revision: 26546

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26546

  Log:
    * enumerator.c: move implementation of each_slice, each_cons,
      each_with_object to enum.c.
    
    * enum.c (each_slice_i): convert multiple values from yield into
      an array.
    
    * enum.c (each_cons_i): ditto.
    
    * enum.c (each_with_object_i): ditto.

  Modified files:
    trunk/ChangeLog
    trunk/enum.c
    trunk/enumerator.c
    trunk/test/ruby/test_enum.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 26545)
+++ ChangeLog	(revision 26546)
@@ -31,6 +31,18 @@
 	  which has been reverted in r9880 probably unintentionally,
 	  according to matz.  [ruby-core:24530]
 
+Tue Feb  2 14:46:06 2010  Yukihiro Matsumoto  <matz@r...>
+
+	* enumerator.c: move implementation of each_slice, each_cons,
+	  each_with_object to enum.c.
+
+	* enum.c (each_slice_i): convert multiple values from yield into
+	  an array.
+
+	* enum.c (each_cons_i): ditto.
+
+	* enum.c (each_with_object_i): ditto.
+
 Tue Feb  2 14:30:27 2010  Yukihiro Matsumoto  <matz@r...>
 
 	* enum.c (enum_each_entry): new method #each_entry to pack values
Index: enumerator.c
===================================================================
--- enumerator.c	(revision 26545)
+++ enumerator.c	(revision 26546)
@@ -180,144 +180,6 @@
 }
 
 static VALUE
-each_slice_i(VALUE val, VALUE *memo)
-{
-    VALUE ary = memo[0];
-    VALUE v = Qnil;
-    long size = (long)memo[1];
-
-    rb_ary_push(ary, val);
-
-    if (RARRAY_LEN(ary) == size) {
-	v = rb_yield(ary);
-	memo[0] = rb_ary_new2(size);
-    }
-
-    return v;
-}
-
-/*
- *  call-seq:
- *    e.each_slice(n) {...}
- *    e.each_slice(n)
- *
- *  Iterates the given block for each slice of <n> elements.  If no
- *  block is given, returns an enumerator.
- *
- *  e.g.:
- *      (1..10).each_slice(3) {|a| p a}
- *      # outputs below
- *      [1, 2, 3]
- *      [4, 5, 6]
- *      [7, 8, 9]
- *      [10]
- *
- */
-static VALUE
-enum_each_slice(VALUE obj, VALUE n)
-{
-    long size = NUM2LONG(n);
-    VALUE args[2], ary;
-
-    if (size <= 0) rb_raise(rb_eArgError, "invalid slice size");
-    RETURN_ENUMERATOR(obj, 1, &n);
-    args[0] = rb_ary_new2(size);
-    args[1] = (VALUE)size;
-
-    rb_block_call(obj, id_each, 0, 0, each_slice_i, (VALUE)args);
-
-    ary = args[0];
-    if (RARRAY_LEN(ary) > 0) rb_yield(ary);
-
-    return Qnil;
-}
-
-static VALUE
-each_cons_i(VALUE val, VALUE *memo)
-{
-    VALUE ary = memo[0];
-    VALUE v = Qnil;
-    long size = (long)memo[1];
-
-    if (RARRAY_LEN(ary) == size) {
-	rb_ary_shift(ary);
-    }
-    rb_ary_push(ary, val);
-    if (RARRAY_LEN(ary) == size) {
-	v = rb_yield(rb_ary_dup(ary));
-    }
-    return v;
-}
-
-/*
- *  call-seq:
- *    each_cons(n) {...}
- *    each_cons(n)
- *
- *  Iterates the given block for each array of consecutive <n>
- *  elements.  If no block is given, returns an enumerator.
- *
- *  e.g.:
- *      (1..10).each_cons(3) {|a| p a}
- *      # outputs below
- *      [1, 2, 3]
- *      [2, 3, 4]
- *      [3, 4, 5]
- *      [4, 5, 6]
- *      [5, 6, 7]
- *      [6, 7, 8]
- *      [7, 8, 9]
- *      [8, 9, 10]
- *
- */
-static VALUE
-enum_each_cons(VALUE obj, VALUE n)
-{
-    long size = NUM2LONG(n);
-    VALUE args[2];
-
-    if (size <= 0) rb_raise(rb_eArgError, "invalid size");
-    RETURN_ENUMERATOR(obj, 1, &n);
-    args[0] = rb_ary_new2(size);
-    args[1] = (VALUE)size;
-
-    rb_block_call(obj, id_each, 0, 0, each_cons_i, (VALUE)args);
-
-    return Qnil;
-}
-
-static VALUE
-each_with_object_i(VALUE val, VALUE 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(VALUE obj, VALUE memo)
-{
-    RETURN_ENUMERATOR(obj, 1, &memo);
-
-    rb_block_call(obj, id_each, 0, 0, each_with_object_i, memo);
-
-    return memo;
-}
-
-static VALUE
 enumerator_allocate(VALUE klass)
 {
     struct enumerator *ptr;
@@ -1190,10 +1052,6 @@
     rb_define_method(rb_mKernel, "to_enum", obj_to_enum, -1);
     rb_define_method(rb_mKernel, "enum_for", obj_to_enum, -1);
 
-    rb_define_method(rb_mEnumerable, "each_slice", enum_each_slice, 1);
-    rb_define_method(rb_mEnumerable, "each_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);
 
Index: enum.c
===================================================================
--- enum.c	(revision 26545)
+++ enum.c	(revision 26546)
@@ -1656,6 +1656,147 @@
 }
 
 static VALUE
+each_slice_i(VALUE i, VALUE *memo, int argc, VALUE *argv)
+{
+    VALUE ary = memo[0];
+    VALUE v = Qnil;
+    long size = (long)memo[1];
+    ENUM_WANT_SVALUE();
+
+    rb_ary_push(ary, i);
+
+    if (RARRAY_LEN(ary) == size) {
+	v = rb_yield(ary);
+	memo[0] = rb_ary_new2(size);
+    }
+
+    return v;
+}
+
+/*
+ *  call-seq:
+ *    e.each_slice(n) {...}
+ *    e.each_slice(n)
+ *
+ *  Iterates the given block for each slice of <n> elements.  If no
+ *  block is given, returns an enumerator.
+ *
+ *  e.g.:
+ *      (1..10).each_slice(3) {|a| p a}
+ *      # outputs below
+ *      [1, 2, 3]
+ *      [4, 5, 6]
+ *      [7, 8, 9]
+ *      [10]
+ *
+ */
+static VALUE
+enum_each_slice(VALUE obj, VALUE n)
+{
+    long size = NUM2LONG(n);
+    VALUE args[2], ary;
+
+    if (size <= 0) rb_raise(rb_eArgError, "invalid slice size");
+    RETURN_ENUMERATOR(obj, 1, &n);
+    args[0] = rb_ary_new2(size);
+    args[1] = (VALUE)size;
+
+    rb_block_call(obj, id_each, 0, 0, each_slice_i, (VALUE)args);
+
+    ary = args[0];
+    if (RARRAY_LEN(ary) > 0) rb_yield(ary);
+
+    return Qnil;
+}
+
+static VALUE
+each_cons_i(VALUE i, VALUE *memo, int argc, VALUE *argv)
+{
+    VALUE ary = memo[0];
+    VALUE v = Qnil;
+    long size = (long)memo[1];
+    ENUM_WANT_SVALUE();
+
+    if (RARRAY_LEN(ary) == size) {
+	rb_ary_shift(ary);
+    }
+    rb_ary_push(ary, i);
+    if (RARRAY_LEN(ary) == size) {
+	v = rb_yield(rb_ary_dup(ary));
+    }
+    return v;
+}
+
+/*
+ *  call-seq:
+ *    each_cons(n) {...}
+ *    each_cons(n)
+ *
+ *  Iterates the given block for each array of consecutive <n>
+ *  elements.  If no block is given, returns an enumerator.
+ *
+ *  e.g.:
+ *      (1..10).each_cons(3) {|a| p a}
+ *      # outputs below
+ *      [1, 2, 3]
+ *      [2, 3, 4]
+ *      [3, 4, 5]
+ *      [4, 5, 6]
+ *      [5, 6, 7]
+ *      [6, 7, 8]
+ *      [7, 8, 9]
+ *      [8, 9, 10]
+ *
+ */
+static VALUE
+enum_each_cons(VALUE obj, VALUE n)
+{
+    long size = NUM2LONG(n);
+    VALUE args[2];
+
+    if (size <= 0) rb_raise(rb_eArgError, "invalid size");
+    RETURN_ENUMERATOR(obj, 1, &n);
+    args[0] = rb_ary_new2(size);
+    args[1] = (VALUE)size;
+
+    rb_block_call(obj, id_each, 0, 0, each_cons_i, (VALUE)args);
+
+    return Qnil;
+}
+
+static VALUE
+each_with_object_i(VALUE i, VALUE memo, int argc, VALUE *argv)
+{
+    ENUM_WANT_SVALUE();
+    return rb_yield_values(2, i, 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(VALUE obj, VALUE memo)
+{
+    RETURN_ENUMERATOR(obj, 1, &memo);
+
+    rb_block_call(obj, id_each, 0, 0, each_with_object_i, memo);
+
+    return memo;
+}
+
+static VALUE
 zip_ary(VALUE val, NODE *memo, int argc, VALUE *argv)
 {
     volatile VALUE result = memo->u1.value;
@@ -2474,6 +2615,9 @@
     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, "each_slice", enum_each_slice, 1);
+    rb_define_method(rb_mEnumerable, "each_cons", enum_each_cons, 1);
+    rb_define_method(rb_mEnumerable, "each_with_object", enum_each_with_object, 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);
Index: test/ruby/test_enum.rb
===================================================================
--- test/ruby/test_enum.rb	(revision 26545)
+++ test/ruby/test_enum.rb	(revision 26546)
@@ -197,6 +197,14 @@
     assert(!([1,2,3].member?(4)))
   end
 
+  class Foo
+    include Enumerable
+    def each
+      yield 1
+      yield 1,2
+    end
+  end
+
   def test_each_with_index
     a = []
     @obj.each_with_index {|x, i| a << [x, i] }
@@ -207,6 +215,7 @@
       hash[item] = index
     end
     assert_equal({"cat"=>0, "wombat"=>2, "dog"=>1}, hash)
+    assert_equal([[1, 0], [[1, 2], 1]], Foo.new.each_with_index.to_a)
   end
 
   def test_each_with_object
@@ -217,17 +226,11 @@
     }
     assert_same(obj, ret)
     assert_equal([55, 3628800], ret)
+    assert_equal([[1, nil], [[1, 2], nil]], Foo.new.each_with_object(nil).to_a)
   end
 
-  class Foo
-    include Enumerable
-    def each
-      yield 1
-      yield 1,2
-    end
-  end
-
   def test_each_entry
+    assert_equal([1, 2, 3], [1, 2, 3].each_entry.to_a)
     assert_equal([1, [1, 2]], Foo.new.each_entry.to_a)
   end
 

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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