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

ruby-changes:54557

From: nobu <ko1@a...>
Date: Thu, 10 Jan 2019 17:19:21 +0900 (JST)
Subject: [ruby-changes:54557] nobu:r66772 (trunk): proc.c: proc without block

nobu	2019-01-10 17:19:14 +0900 (Thu, 10 Jan 2019)

  New Revision: 66772

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66772

  Log:
    proc.c: proc without block
    
    * proc.c (proc_new): promoted lambda/proc/Proc.new with no block
      in a method called with a block to a warning/error.

  Modified files:
    trunk/NEWS
    trunk/lib/matrix.rb
    trunk/lib/prime.rb
    trunk/proc.c
    trunk/spec/ruby/core/kernel/proc_spec.rb
    trunk/spec/ruby/core/proc/block_pass_spec.rb
    trunk/spec/ruby/core/proc/new_spec.rb
    trunk/spec/ruby/language/lambda_spec.rb
    trunk/spec/ruby/optional/capi/proc_spec.rb
    trunk/test/ruby/test_proc.rb
Index: lib/prime.rb
===================================================================
--- lib/prime.rb	(revision 66771)
+++ lib/prime.rb	(revision 66772)
@@ -283,9 +283,9 @@ class Prime https://github.com/ruby/ruby/blob/trunk/lib/prime.rb#L283
     end
 
     # see +Enumerator+#with_index.
-    def with_index(offset = 0)
-      return enum_for(:with_index, offset) { Float::INFINITY } unless block_given?
-      return each_with_index(&proc) if offset == 0
+    def with_index(offset = 0, &block)
+      return enum_for(:with_index, offset) { Float::INFINITY } unless block
+      return each_with_index(&block) if offset == 0
 
       each do |prime|
         yield prime, offset
Index: lib/matrix.rb
===================================================================
--- lib/matrix.rb	(revision 66771)
+++ lib/matrix.rb	(revision 66772)
@@ -514,12 +514,11 @@ class Matrix https://github.com/ruby/ruby/blob/trunk/lib/matrix.rb#L514
   #     # => prints the numbers 1 to 4
   #   Matrix[ [1,2], [3,4] ].each(:strict_lower).to_a # => [3]
   #
-  def each(which = :all) # :yield: e
+  def each(which = :all, &block) # :yield: e
     return to_enum :each, which unless block_given?
     last = column_count - 1
     case which
     when :all
-      block = Proc.new
       @rows.each do |row|
         row.each(&block)
       end
Index: proc.c
===================================================================
--- proc.c	(revision 66771)
+++ proc.c	(revision 66772)
@@ -707,6 +707,9 @@ proc_new(VALUE klass, int8_t is_lambda) https://github.com/ruby/ruby/blob/trunk/proc.c#L707
 
 	if ((block_handler = rb_vm_frame_block_handler(cfp)) != VM_BLOCK_HANDLER_NONE) {
 	    if (is_lambda) {
+                rb_raise(rb_eArgError, proc_without_block);
+            }
+            else {
 		rb_warn(proc_without_block);
 	    }
 	}
Index: spec/ruby/language/lambda_spec.rb
===================================================================
--- spec/ruby/language/lambda_spec.rb	(revision 66771)
+++ spec/ruby/language/lambda_spec.rb	(revision 66772)
@@ -310,14 +310,25 @@ describe "A lambda expression 'lambda { https://github.com/ruby/ruby/blob/trunk/spec/ruby/language/lambda_spec.rb#L310
       def meth; lambda; end
     end
 
-    it "can be created" do
-      implicit_lambda = nil
-      -> {
-        implicit_lambda = meth { 1 }
-      }.should complain(/tried to create Proc object without a block/)
+    ruby_version_is ""..."2.7" do
+      it "can be created" do
+        implicit_lambda = nil
+        -> {
+          implicit_lambda = meth { 1 }
+        }.should complain(/tried to create Proc object without a block/)
 
-      implicit_lambda.lambda?.should be_true
-      implicit_lambda.call.should == 1
+        implicit_lambda.lambda?.should be_true
+        implicit_lambda.call.should == 1
+      end
+    end
+
+    ruby_version_is "2.7" do
+      it "raises ArgumentError" do
+        implicit_lambda = nil
+        -> {
+          meth { 1 }
+        }.should raise_error(ArgumentError, /tried to create Proc object without a block/)
+      end
     end
   end
 
Index: spec/ruby/optional/capi/proc_spec.rb
===================================================================
--- spec/ruby/optional/capi/proc_spec.rb	(revision 66771)
+++ spec/ruby/optional/capi/proc_spec.rb	(revision 66772)
@@ -69,16 +69,18 @@ describe "C-API when calling Proc.new fr https://github.com/ruby/ruby/blob/trunk/spec/ruby/optional/capi/proc_spec.rb#L69
   # For example: C -> Ruby <- C -> Ruby means a C function called into Ruby
   # code which returned to C, then C called into Ruby code again.
 
-  #   Ruby -> C -> rb_funcall(Proc.new)
-  it "returns the Proc passed by the Ruby code calling the C function" do
-    prc = @p.rb_Proc_new(0) { :called }
-    prc.call.should == :called
-  end
-
-  #   Ruby -> C -> Ruby <- C -> rb_funcall(Proc.new)
-  it "returns the Proc passed to the Ruby method when the C function calls other Ruby methods before calling Proc.new" do
-    prc = @p.rb_Proc_new(1) { :called }
-    prc.call.should == :called
+  ruby_version_is ""..."2.7" do
+    #   Ruby -> C -> rb_funcall(Proc.new)
+    it "returns the Proc passed by the Ruby code calling the C function" do
+      prc = @p.rb_Proc_new(0) { :called }
+      prc.call.should == :called
+    end
+
+    #   Ruby -> C -> Ruby <- C -> rb_funcall(Proc.new)
+    it "returns the Proc passed to the Ruby method when the C function calls other Ruby methods before calling Proc.new" do
+      prc = @p.rb_Proc_new(1) { :called }
+      prc.call.should == :called
+    end
   end
 
   # Ruby -> C -> Ruby -> Proc.new
@@ -93,16 +95,18 @@ describe "C-API when calling Proc.new fr https://github.com/ruby/ruby/blob/trunk/spec/ruby/optional/capi/proc_spec.rb#L95
     lambda { @p.rb_Proc_new(3) { :called } }.should raise_error(ArgumentError)
   end
 
-  # Ruby -> C -> Ruby -> C (with new block) -> rb_funcall(Proc.new)
-  it "returns the most recent Proc passed when the Ruby method called the C function" do
-    prc = @p.rb_Proc_new(4) { :called }
-    prc.call.should == :calling_with_block
-  end
-
-  # Ruby -> C -> Ruby -> C (with new block) <- Ruby <- C -> # rb_funcall(Proc.new)
-  it "returns the Proc passed from the original Ruby call to the C function" do
-    prc = @p.rb_Proc_new(5) { :called }
-    prc.call.should == :called
+  ruby_version_is ""..."2.7" do
+    # Ruby -> C -> Ruby -> C (with new block) -> rb_funcall(Proc.new)
+    it "returns the most recent Proc passed when the Ruby method called the C function" do
+      prc = @p.rb_Proc_new(4) { :called }
+      prc.call.should == :calling_with_block
+    end
+
+    # Ruby -> C -> Ruby -> C (with new block) <- Ruby <- C -> # rb_funcall(Proc.new)
+    it "returns the Proc passed from the original Ruby call to the C function" do
+      prc = @p.rb_Proc_new(5) { :called }
+      prc.call.should == :called
+    end
   end
 
   # Ruby -> C -> Ruby -> block_given?
Index: spec/ruby/core/kernel/proc_spec.rb
===================================================================
--- spec/ruby/core/kernel/proc_spec.rb	(revision 66771)
+++ spec/ruby/core/kernel/proc_spec.rb	(revision 66772)
@@ -36,14 +36,28 @@ describe "Kernel.proc" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/kernel/proc_spec.rb#L36
 end
 
 describe "Kernel#proc" do
-  it "uses the implicit block from an enclosing method" do
-    def some_method
-      proc
+  ruby_version_is ""..."2.7" do
+    it "uses the implicit block from an enclosing method" do
+      def some_method
+        proc
+      end
+
+      prc = some_method { "hello" }
+
+      prc.call.should == "hello"
     end
+  end
 
-    prc = some_method { "hello" }
+  ruby_version_is "2.7" do
+    it "can be created when called with no block" do
+      def some_method
+        proc
+      end
 
-    prc.call.should == "hello"
+      -> {
+        some_method { "hello" }
+      }.should complain(/tried to create Proc object without a block/)
+    end
   end
 
   it "needs to be reviewed for spec completeness"
Index: spec/ruby/core/proc/block_pass_spec.rb
===================================================================
--- spec/ruby/core/proc/block_pass_spec.rb	(revision 66771)
+++ spec/ruby/core/proc/block_pass_spec.rb	(revision 66772)
@@ -20,22 +20,39 @@ describe "Proc as a block pass argument" https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/proc/block_pass_spec.rb#L20
   end
 end
 
-describe "Proc as an implicit block pass argument" do
-  def revivify
-    Proc.new
-  end
+ruby_version_is ""..."2.7" do
+  describe "Proc as an implicit block pass argument" do
+    def revivify
+      Proc.new
+    end
+
+    it "remains the same object if re-vivified by the target method" do
+      p = Proc.new {}
+      p2 = revivify(&p)
+      p.should equal p2
+      p.should == p2
+    end
 
-  it "remains the same object if re-vivified by the target method" do
-    p = Proc.new {}
-    p2 = revivify(&p)
-    p.should equal p2
-    p.should == p2
+    it "remains the same object if reconstructed with Proc.new" do
+      p = Proc.new {}
+      p2 = Proc.new(&p)
+      p.should equal p2
+      p.should == p2
+    end
   end
+end
+
+ruby_version_is "2.7" do
+  describe "Proc called with no block" do
+    def revivify
+      Proc.new
+    end
 
-  it "remains the same object if reconstructed with Proc.new" do
-    p = Proc.new {}
-    p2 = Proc.new(&p)
-    p.should equal p2
-    p.should == p2
+    it "raises ArgumentError when called with no block" do
+      p = Proc.new {}
+      -> {
+        revivify(&p)
+      }.should
+    end
   end
 end
Index: spec/ruby/core/proc/new_spec.rb
===================================================================
--- spec/ruby/core/proc/new_spec.rb	(revision 66771)
+++ spec/ruby/core/proc/new_spec.rb	(revision 66772)
@@ -95,16 +95,18 @@ describe "Proc.new with an associated bl https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/proc/new_spec.rb#L95
     obj.second.should == 2
   end
 
-  it "returns a new Proc instance from the block passed to the containing method" do
-    prc = ProcSpecs.new_proc_in_method { "hello" }
-    prc.should be_an_instance_of(Proc)
-    prc.call.should == "hello"
-  end
+  ruby_version_is ""..."2.7" do
+    it "returns a new Proc instance from the block passed to the containing method" do
+      prc = ProcSpecs.new_proc_in_method { "hello" }
+      prc.should be_an_instance_of(Proc)
+      prc.call.should == "hello"
+    end
 
-  it "returns a new Proc instance from the block passed to the containing method" do
-    prc = ProcSpecs.new_proc_subclass_in_method { "hello" }
-    prc.should be_an_instance_of(ProcSpecs::ProcSubclass)
-    prc.call.should == "hello"
+    it "returns a new Proc instance from the block passed to the containing method" do
+      prc = ProcSpecs.new_proc_subclass_in_method { "hello" }
+      prc.should be_an_instance_of(ProcSpecs::ProcSubclass)
+      prc.call.should == "hello"
+    end
   end
 end
 
@@ -178,13 +180,36 @@ describe "Proc.new without a block" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/proc/new_spec.rb#L180
     lambda { ProcSpecs.new_proc_subclass_in_method }.should raise_error(ArgumentError)
   end
 
-  it "uses the implicit block from an enclosing method" do
-    def some_method
-      Proc.new
+  ruby_version_is ""..."2.7" do
+    it "uses the implicit block from an enclosing method" do
+      def some_method
+        Proc.new
+      end
+
+      prc = some_method { "hello" }
+
+      prc.call.should == "hello"
     end
+  end
 
-    prc = some_method { "hello" }
+  ruby_version_is "2.7" do
+    it "can be created if invoked from within a method with a block" do
+      lambda { ProcSpecs.new_proc_in_method { "hello" } }.should complain(/tried to create Proc object without a block/)
+    end
+
+    it "can be created if invoked on a subclass from within a method with a block" do
+      lambda { ProcSpecs.new_proc_subclass_in_method { "hello" } }.should complain(/tried to create Proc object without a block/)
+    end
 
-    prc.call.should == "hello"
+
+    it "can be create when called with no block" do
+      def some_method
+        Proc.new
+      end
+
+      -> {
+        some_method { "hello" }
+      }.should complain(/tried to create Proc object without a block/)
+    end
   end
 end
Index: NEWS
===================================================================
--- NEWS	(revision 66771)
+++ NEWS	(revision 66772)
@@ -17,6 +17,11 @@ sufficient information, see the ChangeLo https://github.com/ruby/ruby/blob/trunk/NEWS#L17
 * Method reference operator, <code>.:</code> is introduced as an
   experimental feature.  [Feature #12125] [Feature #13581]
 
+* Proc.new and proc with no block in a method called with a block is warned
+  now.
+
+* lambda with no block in a method called with a block errs.
+
 === Core classes updates (outstanding ones only)
 
 === Stdlib updates (outstanding ones only)
Index: test/ruby/test_proc.rb
===================================================================
--- test/ruby/test_proc.rb	(revision 66771)
+++ test/ruby/test_proc.rb	(revision 66772)
@@ -424,14 +424,14 @@ class TestProc < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_proc.rb#L424
       1.times { b = lambda }
       b
     end
-    assert_equal(:foo, o.foo { :foo }.call)
+    assert_raise(ArgumentError) {o.foo { :foo }.call}
 
     def o.foo(&b)
       b = nil
       1.times { b = lambda }
       b
     end
-    assert_equal(:foo, o.foo { :foo }.call)
+    assert_raise(ArgumentError) {o.foo { :foo }.call}
   end
 
   def test_arity2

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

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