From 3a81daaf8dc037057d96b8e8cdc6ab1691e7e9d9 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Thu, 24 Dec 2020 00:15:29 +0900 Subject: [PATCH] Module#public_class_method also accepts a symbol array as an argument I'm unsure if this is intentional, but add a document anyway. [Feature #17314] --- NEWS.md | 5 +++-- test/ruby/test_module.rb | 24 +++++++++++++++++++++++- vm_method.c | 11 +++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9b3d8544fc..f273b8b5a3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -264,8 +264,9 @@ Outstanding ones only. p C.ancestors #=> [C, M1, M2, Object, Kernel, BasicObject] ``` - * Module#public, Module#protected and Module#private methods now accept single - array argument with a list of method names. [[Feature #17314]] + * Module#public, Module#protected, Module#private, Module#public_class_method, + Module#private_class_method, toplevel "private" and "public" methods + now accept single array argument with a list of method names. [[Feature #17314]] * Module#attr_accessor, Module#attr_reader, Module#attr_writer and Module#attr methods now return an array of defined methods names as symbols. diff --git a/test/ruby/test_module.rb b/test/ruby/test_module.rb index 5017d9ce19..1ff9befad9 100644 --- a/test/ruby/test_module.rb +++ b/test/ruby/test_module.rb @@ -799,6 +799,11 @@ class TestModule < Test::Unit::TestCase assert_raise(ExpectedException) { AClass.cm1 } assert_raise(ExpectedException) { AClass.cm3 } assert_equal("cm1cm2cm3", AClass.cm2) + + c = Class.new(AClass) + c.class_eval {private_class_method [:cm1, :cm2]} + assert_raise(NoMethodError, /private method/) {c.cm1} + assert_raise(NoMethodError, /private method/) {c.cm2} end def test_private_instance_methods @@ -821,6 +826,11 @@ class TestModule < Test::Unit::TestCase assert_equal("cm1", MyClass.cm1) assert_equal("cm1cm2cm3", MyClass.cm2) assert_raise(ExpectedException) { eval "MyClass.cm3" } + + c = Class.new(AClass) + c.class_eval {public_class_method [:cm1, :cm2]} + assert_equal("cm1", c.cm1) + assert_equal("cm1cm2cm3", c.cm2) end def test_public_instance_methods @@ -1403,13 +1413,25 @@ class TestModule < Test::Unit::TestCase end def test_top_public_private - assert_in_out_err([], <<-INPUT, %w([:foo] [:bar]), []) + assert_in_out_err([], <<-INPUT, %w([:foo] [:bar] [:foo,\ :bar] [] [:foo,\ :bar] []), []) private def foo; :foo; end public def bar; :bar; end p self.private_methods.grep(/^foo$|^bar$/) p self.methods.grep(/^foo$|^bar$/) + + private :foo, :bar + p self.private_methods.grep(/^foo$|^bar$/) + + public :foo, :bar + p self.private_methods.grep(/^foo$|^bar$/) + + private [:foo, :bar] + p self.private_methods.grep(/^foo$|^bar$/) + + public [:foo, :bar] + p self.private_methods.grep(/^foo$|^bar$/) INPUT end diff --git a/vm_method.c b/vm_method.c index a0ccdb8a51..4e1208b4c2 100644 --- a/vm_method.c +++ b/vm_method.c @@ -2035,6 +2035,7 @@ set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_visibility_t * defined methods to public. With arguments, sets the named methods to * have public visibility. * String arguments are converted to symbols. + * An Array of Symbols and/or Strings are also accepted. */ static VALUE @@ -2054,6 +2055,7 @@ rb_mod_public(int argc, VALUE *argv, VALUE module) * defined methods to protected. With arguments, sets the named methods * to have protected visibility. * String arguments are converted to symbols. + * An Array of Symbols and/or Strings are also accepted. * * If a method has protected visibility, it is callable only where * self of the context is the same as the method. @@ -2082,6 +2084,7 @@ rb_mod_protected(int argc, VALUE *argv, VALUE module) * defined methods to private. With arguments, sets the named methods * to have private visibility. * String arguments are converted to symbols. + * An Array of Symbols and/or Strings are also accepted. * * module Mod * def a() end @@ -2214,10 +2217,12 @@ rb_mod_ruby2_keywords(int argc, VALUE *argv, VALUE module) * call-seq: * mod.public_class_method(symbol, ...) -> mod * mod.public_class_method(string, ...) -> mod + * mod.public_class_method(array) -> mod * * Makes a list of existing class methods public. * * String arguments are converted to symbols. + * An Array of Symbols and/or Strings are also accepted. */ static VALUE @@ -2231,11 +2236,13 @@ rb_mod_public_method(int argc, VALUE *argv, VALUE obj) * call-seq: * mod.private_class_method(symbol, ...) -> mod * mod.private_class_method(string, ...) -> mod + * mod.private_class_method(array) -> mod * * Makes existing class methods private. Often used to hide the default * constructor new. * * String arguments are converted to symbols. + * An Array of Symbols and/or Strings are also accepted. * * class SimpleSingleton # Not thread safe * private_class_method :new @@ -2258,12 +2265,14 @@ rb_mod_private_method(int argc, VALUE *argv, VALUE obj) * public * public(symbol, ...) * public(string, ...) + * public(array) * * With no arguments, sets the default visibility for subsequently * defined methods to public. With arguments, sets the named methods to * have public visibility. * * String arguments are converted to symbols. + * An Array of Symbols and/or Strings are also accepted. */ static VALUE @@ -2277,12 +2286,14 @@ top_public(int argc, VALUE *argv, VALUE _) * private * private(symbol, ...) * private(string, ...) + * private(array) * * With no arguments, sets the default visibility for subsequently * defined methods to private. With arguments, sets the named methods to * have private visibility. * * String arguments are converted to symbols. + * An Array of Symbols and/or Strings are also accepted. */ static VALUE top_private(int argc, VALUE *argv, VALUE _)