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

ruby-changes:64446

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Tue, 22 Dec 2020 13:52:23 +0900 (JST)
Subject: [ruby-changes:64446] fa356a798a (master): Enumerator.new: raise unless block given

https://git.ruby-lang.org/ruby.git/commit/?id=fa356a798a

From fa356a798aefc20725467d4fad02df8325d63e71 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Thu, 13 Aug 2020 11:44:15 +0900
Subject: Enumerator.new: raise unless block given

Has been deprecated since c73b6bd7ebd01133538c645566944132dbde4d13.
[Feature #17116] [ruby-dev:50945]

diff --git a/enumerator.c b/enumerator.c
index fe5f054..b4a7cb5 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -420,15 +420,31 @@ enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *ar https://github.com/ruby/ruby/blob/trunk/enumerator.c#L420
     return enum_obj;
 }
 
+static VALUE
+convert_to_feasible_size_value(VALUE obj)
+{
+    if (NIL_P(obj)) {
+        return obj;
+    }
+    else if (rb_respond_to(obj, id_call)) {
+        return obj;
+    }
+    else if (RB_FLOAT_TYPE_P(obj) && RFLOAT_VALUE(obj) == HUGE_VAL) {
+        return obj;
+    }
+    else {
+        return rb_to_int(obj);
+    }
+}
+
 /*
  * call-seq:
  *   Enumerator.new(size = nil) { |yielder| ... }
- *   Enumerator.new(obj, method = :each, *args)
  *
  * Creates a new Enumerator object, which can be used as an
  * Enumerable.
  *
- * In the first form, iteration is defined by the given block, in
+ * Iteration is defined by the given block, in
  * which a "yielder" object, given as block parameter, can be used to
  * yield a value by calling the +yield+ method (aliased as <code><<</code>):
  *
@@ -445,52 +461,16 @@ enumerator_init(VALUE enum_obj, VALUE obj, VALUE meth, int argc, const VALUE *ar https://github.com/ruby/ruby/blob/trunk/enumerator.c#L461
  * The optional parameter can be used to specify how to calculate the size
  * in a lazy fashion (see Enumerator#size). It can either be a value or
  * a callable object.
- *
- * In the deprecated second form, a generated Enumerator iterates over the
- * given object using the given method with the given arguments passed.
- *
- * Use of this form is discouraged.  Use Object#enum_for or Object#to_enum
- * instead.
- *
- *   e = Enumerator.new(ObjectSpace, :each_object)
- *       #-> ObjectSpace.enum_for(:each_object)
- *
- *   e.select { |obj| obj.is_a?(Class) }  # => array of all classes
- *
  */
 static VALUE
 enumerator_initialize(int argc, VALUE *argv, VALUE obj)
 {
-    VALUE recv, meth = sym_each;
-    VALUE size = Qnil;
-    int kw_splat = 0;
-
-    if (rb_block_given_p()) {
-	rb_check_arity(argc, 0, 1);
-	recv = generator_init(generator_allocate(rb_cGenerator), rb_block_proc());
-	if (argc) {
-            if (NIL_P(argv[0]) || rb_respond_to(argv[0], id_call) ||
-                (RB_TYPE_P(argv[0], T_FLOAT) && RFLOAT_VALUE(argv[0]) == HUGE_VAL)) {
-                size = argv[0];
-            }
-            else {
-                size = rb_to_int(argv[0]);
-            }
-            argc = 0;
-        }
-    }
-    else {
-	rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
-	rb_warn_deprecated("Enumerator.new without a block", "Object#to_enum");
-	recv = *argv++;
-	if (--argc) {
-	    meth = *argv++;
-	    --argc;
-	}
-        kw_splat = rb_keyword_given_p();
-    }
+    VALUE iter = rb_block_proc();
+    VALUE recv = generator_init(generator_allocate(rb_cGenerator), iter);
+    VALUE arg0 = rb_check_arity(argc, 0, 1) ? argv[0] : Qnil;
+    VALUE size = convert_to_feasible_size_value(arg0);
 
-    return enumerator_init(obj, recv, meth, argc, argv, 0, size, kw_splat);
+    return enumerator_init(obj, recv, sym_each, 0, 0, 0, size, false);
 }
 
 /* :nodoc: */
diff --git a/spec/ruby/core/enumerator/initialize_spec.rb b/spec/ruby/core/enumerator/initialize_spec.rb
index 45bd650..113bbf9 100644
--- a/spec/ruby/core/enumerator/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/initialize_spec.rb
@@ -11,8 +11,10 @@ describe "Enumerator#initialize" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/enumerator/initialize_spec.rb#L11
     Enumerator.should have_private_instance_method(:initialize, false)
   end
 
-  it "returns self when given an object" do
-    @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
+  ruby_version_is ''...'3.0' do
+    it "returns self when given an object" do
+      @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
+    end
   end
 
   it "returns self when given a block" do
diff --git a/spec/ruby/core/enumerator/new_spec.rb b/spec/ruby/core/enumerator/new_spec.rb
index 100edc8..9aea9fd 100644
--- a/spec/ruby/core/enumerator/new_spec.rb
+++ b/spec/ruby/core/enumerator/new_spec.rb
@@ -1,42 +1,52 @@ https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/enumerator/new_spec.rb#L1
 require_relative '../../spec_helper'
 
 describe "Enumerator.new" do
-  it "creates a new custom enumerator with the given object, iterator and arguments" do
-    enum = Enumerator.new(1, :upto, 3)
-    enum.should be_an_instance_of(Enumerator)
-  end
+  context "no block given" do
+    ruby_version_is '3.0' do
+      it "raises" do
+        -> { Enumerator.new(1, :upto, 3) }.should raise_error(ArgumentError)
+      end
+    end
 
-  it "creates a new custom enumerator that responds to #each" do
-    enum = Enumerator.new(1, :upto, 3)
-    enum.respond_to?(:each).should == true
-  end
+    ruby_version_is ''...'3.0' do
+      it "creates a new custom enumerator with the given object, iterator and arguments" do
+        enum = Enumerator.new(1, :upto, 3)
+        enum.should be_an_instance_of(Enumerator)
+      end
 
-  it "creates a new custom enumerator that runs correctly" do
-    Enumerator.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
-  end
+      it "creates a new custom enumerator that responds to #each" do
+        enum = Enumerator.new(1, :upto, 3)
+        enum.respond_to?(:each).should == true
+      end
 
-  it "aliases the second argument to :each" do
-    Enumerator.new(1..2).to_a.should == Enumerator.new(1..2, :each).to_a
-  end
+      it "creates a new custom enumerator that runs correctly" do
+        Enumerator.new(1, :upto, 3).map{|x|x}.should == [1,2,3]
+      end
 
-  it "doesn't check for the presence of the iterator method" do
-    Enumerator.new(nil).should be_an_instance_of(Enumerator)
-  end
+      it "aliases the second argument to :each" do
+        Enumerator.new(1..2).to_a.should == Enumerator.new(1..2, :each).to_a
+      end
 
-  it "uses the latest define iterator method" do
-    class StrangeEach
-      def each
-        yield :foo
+      it "doesn't check for the presence of the iterator method" do
+        Enumerator.new(nil).should be_an_instance_of(Enumerator)
       end
-    end
-    enum = Enumerator.new(StrangeEach.new)
-    enum.to_a.should == [:foo]
-    class StrangeEach
-      def each
-        yield :bar
+
+      it "uses the latest define iterator method" do
+        class StrangeEach
+          def each
+            yield :foo
+          end
+        end
+        enum = Enumerator.new(StrangeEach.new)
+        enum.to_a.should == [:foo]
+        class StrangeEach
+          def each
+            yield :bar
+          end
+        end
+        enum.to_a.should == [:bar]
       end
     end
-    enum.to_a.should == [:bar]
   end
 
   context "when passed a block" do
diff --git a/test/ruby/test_enumerator.rb b/test/ruby/test_enumerator.rb
index 5b634ef..eb15d4b 100644
--- a/test/ruby/test_enumerator.rb
+++ b/test/ruby/test_enumerator.rb
@@ -69,22 +69,16 @@ class TestEnumerator < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_enumerator.rb#L69
 
   def test_initialize
     assert_equal([1, 2, 3], @obj.to_enum(:foo, 1, 2, 3).to_a)
-    begin
-      deprecated_bak, Warning[:deprecated] = Warning[:deprecated], true
-      _, err = capture_io do
-        assert_equal([1, 2, 3], Enumerator.new(@obj, :foo, 1, 2, 3).to_a)
-      end
-      assert_match 'Enumerator.new without a block is deprecated', err
-    ensure
-      Warning[:deprecated] = deprecated_bak
-    end
+    assert_raise(ArgumentError) {
+      Enumerator.new(@obj, :foo, 1, 2, 3)
+    }
     assert_equal([1, 2, 3], Enumerator.new { |y| i = 0; loop { y << (i += 1) } }.take(3))
     assert_raise(ArgumentError) { Enumerator.new }
 
     enum = @obj.to_enum
     assert_raise(NoMethodError) { enum.each {} }
     enum.freeze
-    assert_raise(FrozenError) {
+    assert_raise(ArgumentError) {
       capture_io do
         # warning: Enumerator.new without a block is deprecated; use Object#to_enum
         enum.__send__(:initialize, @obj, :foo)
-- 
cgit v0.10.2


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

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