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

ruby-changes:69811

From: Jeremy <ko1@a...>
Date: Fri, 19 Nov 2021 02:48:01 +0900 (JST)
Subject: [ruby-changes:69811] 75ecbda438 (master): Make Module#{public, private, protected, module_function} return arguments

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

From 75ecbda438670ec12641d1324d0e81a52ee02e0a Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Wed, 27 Oct 2021 10:35:54 -0700
Subject: Make Module#{public,private,protected,module_function} return
 arguments

Previously, each of these methods returned self, but it is
more useful to return arguments, to allow for simpler method
decorators, such as:

```ruby
cached private def foo; some_long_calculation; end
```

Where cached sets up caching for the method.

For each of these methods, the following behavior is used:

1) No arguments returns nil
2) Single argument is returned
3) Multiple arguments are returned as an array

The single argument case is really the case we are trying to
optimize for, for the same reason that def was changed to return
a symbol for the method.

Idea and initial patch from Herwin Quarantainenet.

Implements [Feature #12495]
---
 spec/ruby/core/main/private_spec.rb           | 12 ++++++--
 spec/ruby/core/main/public_spec.rb            | 13 +++++++--
 spec/ruby/core/module/module_function_spec.rb | 40 +++++++++++++++++++--------
 spec/ruby/core/module/private_spec.rb         | 24 ++++++++++++----
 spec/ruby/core/module/protected_spec.rb       | 24 ++++++++++++----
 spec/ruby/core/module/public_spec.rb          | 25 +++++++++++++----
 test/ruby/test_module.rb                      | 22 +++++++++++++++
 vm_method.c                                   | 16 +++++++----
 8 files changed, 139 insertions(+), 37 deletions(-)

diff --git a/spec/ruby/core/main/private_spec.rb b/spec/ruby/core/main/private_spec.rb
index 78c5d287d4d..cac0645b404 100644
--- a/spec/ruby/core/main/private_spec.rb
+++ b/spec/ruby/core/main/private_spec.rb
@@ -32,8 +32,16 @@ describe "main#private" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/main/private_spec.rb#L32
     end
   end
 
-  it "returns Object" do
-    eval("private :main_public_method", TOPLEVEL_BINDING).should equal(Object)
+  ruby_version_is ''...'3.1' do
+    it "returns Object" do
+      eval("private :main_public_method", TOPLEVEL_BINDING).should equal(Object)
+    end
+  end
+
+  ruby_version_is '3.1' do
+    it "returns argument" do
+      eval("private :main_public_method", TOPLEVEL_BINDING).should equal(:main_public_method)
+    end
   end
 
   it "raises a NameError when at least one of given method names is undefined" do
diff --git a/spec/ruby/core/main/public_spec.rb b/spec/ruby/core/main/public_spec.rb
index bfc27a9e804..91f045dbab1 100644
--- a/spec/ruby/core/main/public_spec.rb
+++ b/spec/ruby/core/main/public_spec.rb
@@ -32,10 +32,19 @@ describe "main#public" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/main/public_spec.rb#L32
     end
   end
 
-  it "returns Object" do
-    eval("public :main_private_method", TOPLEVEL_BINDING).should equal(Object)
+  ruby_version_is ''...'3.1' do
+    it "returns Object" do
+      eval("public :main_private_method", TOPLEVEL_BINDING).should equal(Object)
+    end
   end
 
+  ruby_version_is '3.1' do
+    it "returns argument" do
+      eval("public :main_private_method", TOPLEVEL_BINDING).should equal(:main_private_method)
+    end
+  end
+
+
   it "raises a NameError when given an undefined name" do
     -> do
       eval "public :main_undefined_method", TOPLEVEL_BINDING
diff --git a/spec/ruby/core/module/module_function_spec.rb b/spec/ruby/core/module/module_function_spec.rb
index 407237d48fb..0602e95ca9c 100644
--- a/spec/ruby/core/module/module_function_spec.rb
+++ b/spec/ruby/core/module/module_function_spec.rb
@@ -38,14 +38,23 @@ describe "Module#module_function with specific method names" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/module/module_function_spec.rb#L38
     m.respond_to?(:test3).should == false
   end
 
-  it "returns the current module" do
-    x = nil
-    m = Module.new do
-      def test()  end
-      x = module_function :test
+  ruby_version_is ""..."3.1" do
+    it "returns self" do
+      Module.new do
+        def foo; end
+        module_function(:foo).should equal(self)
+      end
     end
+  end
 
-    x.should == m
+  ruby_version_is "3.1" do
+    it "returns argument or arguments if given" do
+      Module.new do
+        def foo; end
+        module_function(:foo).should equal(:foo)
+        module_function(:foo, :foo).should == [:foo, :foo]
+      end
+    end
   end
 
   it "creates an independent copy of the method, not a redirect" do
@@ -160,13 +169,20 @@ describe "Module#module_function as a toggle (no arguments) in a Module body" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/module/module_function_spec.rb#L169
     m.respond_to?(:test2).should == true
   end
 
-  it "returns the current module" do
-    x = nil
-    m = Module.new {
-      x = module_function
-    }
+  ruby_version_is ""..."3.1" do
+    it "returns self" do
+      Module.new do
+        module_function.should equal(self)
+      end
+    end
+  end
 
-    x.should == m
+  ruby_version_is "3.1" do
+    it "returns nil" do
+      Module.new do
+        module_function.should equal(nil)
+      end
+    end
   end
 
   it "stops creating module functions if the body encounters another toggle " \
diff --git a/spec/ruby/core/module/private_spec.rb b/spec/ruby/core/module/private_spec.rb
index e893c24f38b..ead806637c9 100644
--- a/spec/ruby/core/module/private_spec.rb
+++ b/spec/ruby/core/module/private_spec.rb
@@ -38,11 +38,25 @@ describe "Module#private" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/module/private_spec.rb#L38
                   :module_specs_public_method_on_object_for_kernel_private)
   end
 
-  it "returns self" do
-    (class << Object.new; self; end).class_eval do
-      def foo; end
-      private(:foo).should equal(self)
-      private.should equal(self)
+  ruby_version_is ""..."3.1" do
+    it "returns self" do
+      (class << Object.new; self; end).class_eval do
+        def foo; end
+        private(:foo).should equal(self)
+        private.should equal(self)
+      end
+    end
+  end
+
+  ruby_version_is "3.1" do
+    it "returns argument or arguments if given" do
+      (class << Object.new; self; end).class_eval do
+        def foo; end
+        private(:foo).should equal(:foo)
+        private([:foo, :foo]).should == [:foo, :foo]
+        private(:foo, :foo).should == [:foo, :foo]
+        private.should equal(nil)
+      end
     end
   end
 
diff --git a/spec/ruby/core/module/protected_spec.rb b/spec/ruby/core/module/protected_spec.rb
index aa04a42fb8e..058d49d751e 100644
--- a/spec/ruby/core/module/protected_spec.rb
+++ b/spec/ruby/core/module/protected_spec.rb
@@ -39,11 +39,25 @@ describe "Module#protected" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/module/protected_spec.rb#L39
                   :module_specs_public_method_on_object_for_kernel_protected)
   end
 
-  it "returns self" do
-    (class << Object.new; self; end).class_eval do
-      def foo; end
-      protected(:foo).should equal(self)
-      protected.should equal(self)
+  ruby_version_is ""..."3.1" do
+    it "returns self" do
+      (class << Object.new; self; end).class_eval do
+        def foo; end
+        protected(:foo).should equal(self)
+        protected.should equal(self)
+      end
+    end
+  end
+
+  ruby_version_is "3.1" do
+    it "returns argument or arguments if given" do
+      (class << Object.new; self; end).class_eval do
+        def foo; end
+        protected(:foo).should equal(:foo)
+        protected([:foo, :foo]).should == [:foo, :foo]
+        protected(:foo, :foo).should == [:foo, :foo]
+        protected.should equal(nil)
+      end
     end
   end
 
diff --git a/spec/ruby/core/module/public_spec.rb b/spec/ruby/core/module/public_spec.rb
index e7059f6aa63..e3b183f228a 100644
--- a/spec/ruby/core/module/public_spec.rb
+++ b/spec/ruby/core/module/public_spec.rb
@@ -27,12 +27,25 @@ describe "Module#public" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/module/public_spec.rb#L27
                   :module_specs_private_method_on_object_for_kernel_public)
   end
 
-  it "returns self" do
-    (class << Object.new; self; end).class_eval do
-      def foo; end
-      private :foo
-      public(:foo).should equal(self)
-      public.should equal(self)
+  ruby_version_is ""..."3.1" do
+    it "returns self" do
+      (class << Object.new; self; end).class_eval do
+        def foo; end
+        public(:foo).should equal(self)
+        public.should equal(self)
+      end
+    end
+  end
+
+  ruby_version_is "3.1" do
+    it "returns argument or arguments if given" do
+      (class << Object.new; self; end).class_eval do
+        def foo; end
+        public(:foo).should equal(:foo)
+        public([:foo, :foo]).should == [:foo, :foo]
+        public(:foo, :foo).should == [:foo, :foo]
+        public.should equal(nil)
+      end
     end
   end
 
diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb
index be23b84c462..e1524a5d815 100644
--- a/test/ruby/test_module.rb
+++ b/test/ruby/test_module.rb
@@ -1014,6 +1014,28 @@ class TestModule < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_module.rb#L1014
     assert_raise(NoMethodError, /protected method/) {o.aClass2}
   end
 
+  def test_visibility_method_return_value
+    no_arg_results = nil
+    c = Module.new do
+      singleton_class.send(:public, :public, :private, :protected, :module_function)
+      def foo; end
+      def bar; end
+      no_arg_results = [public, private, protected, module_function]
+    end
+
+    assert_equal([nil]*4, no_arg_results)
+
+    assert_equal(:foo, c.private(:foo))
+    assert_equal(:foo, c.public(:foo))
+    assert_equal(:foo, c.protected(:foo))
+    assert_equal(:foo, c.module_function(:foo))
+
+    assert_equal([:foo, :bar], c.private(:foo, :bar))
+    assert_equal([:foo, :bar], c.public(:foo, :bar))
+    assert_equal([:foo, :bar], c.protected(:foo, :bar))
+    assert_equal([:foo, :bar], c.module_function(:foo, :bar))
+  end
+
   def test_s_constants
 (... truncated)

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

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