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

ruby-changes:14687

From: matz <ko1@a...>
Date: Tue, 2 Feb 2010 17:58:51 +0900 (JST)
Subject: [ruby-changes:14687] Ruby:r26540 (trunk): * enum.c (enum_each_entry): new method #each_entry to pack values

matz	2010-02-02 17:54:52 +0900 (Tue, 02 Feb 2010)

  New Revision: 26540

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

  Log:
    * 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.

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

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 26539)
+++ ChangeLog	(revision 26540)
@@ -1,3 +1,15 @@
+Tue Feb  2 14:30:27 2010  Yukihiro Matsumoto  <matz@r...>
+
+	* 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.
 Tue Feb  2 11:13:56 2010  Nobuyoshi Nakada  <nobu@r...>
 
 	* lib/delegate.rb (Delegator#marshal_dump): exclude
Index: enum.c
===================================================================
--- enum.c	(revision 26539)
+++ enum.c	(revision 26540)
@@ -1618,6 +1618,46 @@
 
 
 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 <i>block</i> once for each element in <i>self</i>, 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)
 {
     volatile VALUE result = memo->u1.value;
@@ -2435,6 +2475,7 @@
     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);
Index: lib/set.rb
===================================================================
--- lib/set.rb	(revision 26539)
+++ lib/set.rb	(revision 26540)
@@ -70,8 +70,8 @@
     enum.nil? and return
 
     if block
-      enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
-      enum.each { |o| add(block[o]) }
+      enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
+      enum.each_entry { |o| add(block[o]) }
     else
       merge(enum)
     end
@@ -123,9 +123,9 @@
     if enum.class == self.class
       @hash.replace(enum.instance_eval { @hash })
     else
-      enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
+      enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
       clear
-      enum.each { |o| add(o) }
+      enum.each_entry { |o| add(o) }
     end
 
     self
@@ -281,8 +281,8 @@
     if enum.instance_of?(self.class)
       @hash.update(enum.instance_variable_get(:@hash))
     else
-      enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
-      enum.each { |o| add(o) }
+      enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
+      enum.each_entry { |o| add(o) }
     end
 
     self
@@ -291,8 +291,8 @@
   # Deletes every element that appears in the given enumerable object
   # and returns self.
   def subtract(enum)
-    enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
-    enum.each { |o| delete(o) }
+    enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
+    enum.each_entry { |o| delete(o) }
     self
   end
 
@@ -314,9 +314,9 @@
   # Returns a new set containing elements common to the set and the
   # given enumerable object.
   def &(enum)
-    enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
+    enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
     n = self.class.new
-    enum.each { |o| n.add(o) if include?(o) }
+    enum.each_entry { |o| n.add(o) if include?(o) }
     n
   end
   alias intersection &	##
@@ -514,7 +514,7 @@
 	  end
 	  
 	  def add(o)
-	    o.respond_to?(:<=>) or raise ArgumentError, "value must repond to <=>"
+	    o.respond_to?(:<=>) or raise ArgumentError, "value must respond to <=>"
 	    super
 	  end
 	  alias << add
@@ -642,16 +642,16 @@
 # 	end
 #
 # 	def replace(enum)
-# 	  enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
+# 	  enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
 # 	  clear
-# 	  enum.each { |o| add(o) }
+# 	  enum.each_entry { |o| add(o) }
 #
 # 	  self
 # 	end
 #
 # 	def merge(enum)
-# 	  enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
-# 	  enum.each { |o| add(o) }
+# 	  enum.respond_to?(:each) or raise ArgumentError, "value must be enumerable"
+# 	  enum.each_entry { |o| add(o) }
 #
 # 	  self
 # 	end
Index: test/ruby/test_enum.rb
===================================================================
--- test/ruby/test_enum.rb	(revision 26539)
+++ test/ruby/test_enum.rb	(revision 26540)
@@ -219,6 +219,18 @@
     assert_equal([55, 3628800], ret)
   end
 
+  class Foo
+    include Enumerable
+    def each
+      yield 1
+      yield 1,2
+    end
+  end
+
+  def test_each_entry
+    assert_equal([1, [1, 2]], Foo.new.each_entry.to_a)
+  end
+
   def test_zip
     assert_equal([[1,1],[2,2],[3,3],[1,1],[2,2]], @obj.zip(@obj))
     a = []

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

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