зеркало из https://github.com/github/ruby.git
Feature 17314: allow to pass array to public, protected and private methods
This commit is contained in:
Родитель
8148f88b92
Коммит
eb8ea336d3
3
NEWS.md
3
NEWS.md
|
@ -249,6 +249,9 @@ Outstanding ones only.
|
||||||
p C.ancestors #=> [C, M1, M2, Object, Kernel, BasicObject]
|
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#attr_accessor, Module#attr_reader, Module#attr_writer and Module#attr
|
* Module#attr_accessor, Module#attr_reader, Module#attr_writer and Module#attr
|
||||||
methods now return array of defined methods names as symbols.
|
methods now return array of defined methods names as symbols.
|
||||||
[[Feature #17314]]
|
[[Feature #17314]]
|
||||||
|
|
|
@ -13,6 +13,14 @@ def main_public_method
|
||||||
end
|
end
|
||||||
public :main_public_method
|
public :main_public_method
|
||||||
|
|
||||||
|
def main_public_method2
|
||||||
|
end
|
||||||
|
public :main_public_method2
|
||||||
|
|
||||||
def main_private_method
|
def main_private_method
|
||||||
end
|
end
|
||||||
private :main_private_method
|
private :main_private_method
|
||||||
|
|
||||||
|
def main_private_method2
|
||||||
|
end
|
||||||
|
private :main_private_method2
|
||||||
|
|
|
@ -4,20 +4,41 @@ require_relative 'fixtures/classes'
|
||||||
describe "main#private" do
|
describe "main#private" do
|
||||||
after :each do
|
after :each do
|
||||||
Object.send(:public, :main_public_method)
|
Object.send(:public, :main_public_method)
|
||||||
|
Object.send(:public, :main_public_method2)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sets the visibility of the given method to private" do
|
context "when single argument is passed and it is not an array" do
|
||||||
eval "private :main_public_method", TOPLEVEL_BINDING
|
it "sets the visibility of the given methods to private" do
|
||||||
Object.should have_private_method(:main_public_method)
|
eval "private :main_public_method", TOPLEVEL_BINDING
|
||||||
|
Object.should have_private_method(:main_public_method)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when multiple arguments are passed" do
|
||||||
|
it "sets the visibility of the given methods to private" do
|
||||||
|
eval "private :main_public_method, :main_public_method2", TOPLEVEL_BINDING
|
||||||
|
Object.should have_private_method(:main_public_method)
|
||||||
|
Object.should have_private_method(:main_public_method2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ruby_version_is "3.0" do
|
||||||
|
context "when single argument is passed and is an array" do
|
||||||
|
it "sets the visibility of the given methods to private" do
|
||||||
|
eval "private [:main_public_method, :main_public_method2]", TOPLEVEL_BINDING
|
||||||
|
Object.should have_private_method(:main_public_method)
|
||||||
|
Object.should have_private_method(:main_public_method2)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns Object" do
|
it "returns Object" do
|
||||||
eval("private :main_public_method", TOPLEVEL_BINDING).should equal(Object)
|
eval("private :main_public_method", TOPLEVEL_BINDING).should equal(Object)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises a NameError when given an undefined name" do
|
it "raises a NameError when at least one of given method names is undefined" do
|
||||||
-> do
|
-> do
|
||||||
eval "private :main_undefined_method", TOPLEVEL_BINDING
|
eval "private :main_public_method, :main_undefined_method", TOPLEVEL_BINDING
|
||||||
end.should raise_error(NameError)
|
end.should raise_error(NameError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,11 +4,32 @@ require_relative 'fixtures/classes'
|
||||||
describe "main#public" do
|
describe "main#public" do
|
||||||
after :each do
|
after :each do
|
||||||
Object.send(:private, :main_private_method)
|
Object.send(:private, :main_private_method)
|
||||||
|
Object.send(:private, :main_private_method2)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "sets the visibility of the given method to public" do
|
context "when single argument is passed and it is not an array" do
|
||||||
eval "public :main_private_method", TOPLEVEL_BINDING
|
it "sets the visibility of the given methods to public" do
|
||||||
Object.should_not have_private_method(:main_private_method)
|
eval "public :main_private_method", TOPLEVEL_BINDING
|
||||||
|
Object.should_not have_private_method(:main_private_method)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when multiple arguments are passed" do
|
||||||
|
it "sets the visibility of the given methods to public" do
|
||||||
|
eval "public :main_private_method, :main_private_method2", TOPLEVEL_BINDING
|
||||||
|
Object.should_not have_private_method(:main_private_method)
|
||||||
|
Object.should_not have_private_method(:main_private_method2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ruby_version_is "3.0" do
|
||||||
|
context "when single argument is passed and is an array" do
|
||||||
|
it "sets the visibility of the given methods to public" do
|
||||||
|
eval "public [:main_private_method, :main_private_method2]", TOPLEVEL_BINDING
|
||||||
|
Object.should_not have_private_method(:main_private_method)
|
||||||
|
Object.should_not have_private_method(:main_private_method2)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns Object" do
|
it "returns Object" do
|
||||||
|
|
|
@ -6,6 +6,40 @@ describe :set_visibility, shared: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "with argument" do
|
describe "with argument" do
|
||||||
|
describe "one or more arguments" do
|
||||||
|
it "sets visibility of given method names" do
|
||||||
|
visibility = @method
|
||||||
|
old_visibility = [:protected, :private].find {|vis| vis != visibility }
|
||||||
|
|
||||||
|
mod = Module.new {
|
||||||
|
send old_visibility
|
||||||
|
def test1() end
|
||||||
|
def test2() end
|
||||||
|
send visibility, :test1, :test2
|
||||||
|
}
|
||||||
|
mod.should send(:"have_#{visibility}_instance_method", :test1, false)
|
||||||
|
mod.should send(:"have_#{visibility}_instance_method", :test2, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ruby_version_is "3.0" do
|
||||||
|
describe "array as a single argument" do
|
||||||
|
it "sets visibility of given method names" do
|
||||||
|
visibility = @method
|
||||||
|
old_visibility = [:protected, :private].find {|vis| vis != visibility }
|
||||||
|
|
||||||
|
mod = Module.new {
|
||||||
|
send old_visibility
|
||||||
|
def test1() end
|
||||||
|
def test2() end
|
||||||
|
send visibility, [:test1, :test2]
|
||||||
|
}
|
||||||
|
mod.should send(:"have_#{visibility}_instance_method", :test1, false)
|
||||||
|
mod.should send(:"have_#{visibility}_instance_method", :test2, false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
it "does not clone method from the ancestor when setting to the same visibility in a child" do
|
it "does not clone method from the ancestor when setting to the same visibility in a child" do
|
||||||
visibility = @method
|
visibility = @method
|
||||||
parent = Module.new {
|
parent = Module.new {
|
||||||
|
|
31
vm_method.c
31
vm_method.c
|
@ -1973,6 +1973,16 @@ rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
|
||||||
return ID2SYM(id);
|
return ID2SYM(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
check_and_export_method(VALUE self, VALUE name, rb_method_visibility_t visi)
|
||||||
|
{
|
||||||
|
ID id = rb_check_id(&name);
|
||||||
|
if (!id) {
|
||||||
|
rb_print_undef_str(self, name);
|
||||||
|
}
|
||||||
|
rb_export_method(self, id, visi);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_visibility_t visi)
|
set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_visibility_t visi)
|
||||||
{
|
{
|
||||||
|
@ -1985,13 +1995,19 @@ set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_visibil
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < argc; i++) {
|
|
||||||
VALUE v = argv[i];
|
VALUE v;
|
||||||
ID id = rb_check_id(&v);
|
|
||||||
if (!id) {
|
if (argc == 1 && (v = rb_check_array_type(argv[0])) != Qnil) {
|
||||||
rb_print_undef_str(self, v);
|
long j;
|
||||||
|
|
||||||
|
for (j = 0; j < RARRAY_LEN(v); j++) {
|
||||||
|
check_and_export_method(self, RARRAY_AREF(v, j), visi);
|
||||||
}
|
}
|
||||||
rb_export_method(self, id, visi);
|
} else {
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
check_and_export_method(self, argv[i], visi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2013,6 +2029,7 @@ set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_visibility_t
|
||||||
* public -> self
|
* public -> self
|
||||||
* public(symbol, ...) -> self
|
* public(symbol, ...) -> self
|
||||||
* public(string, ...) -> self
|
* public(string, ...) -> self
|
||||||
|
* public(array) -> self
|
||||||
*
|
*
|
||||||
* With no arguments, sets the default visibility for subsequently
|
* With no arguments, sets the default visibility for subsequently
|
||||||
* defined methods to public. With arguments, sets the named methods to
|
* defined methods to public. With arguments, sets the named methods to
|
||||||
|
@ -2031,6 +2048,7 @@ rb_mod_public(int argc, VALUE *argv, VALUE module)
|
||||||
* protected -> self
|
* protected -> self
|
||||||
* protected(symbol, ...) -> self
|
* protected(symbol, ...) -> self
|
||||||
* protected(string, ...) -> self
|
* protected(string, ...) -> self
|
||||||
|
* protected(array) -> self
|
||||||
*
|
*
|
||||||
* With no arguments, sets the default visibility for subsequently
|
* With no arguments, sets the default visibility for subsequently
|
||||||
* defined methods to protected. With arguments, sets the named methods
|
* defined methods to protected. With arguments, sets the named methods
|
||||||
|
@ -2058,6 +2076,7 @@ rb_mod_protected(int argc, VALUE *argv, VALUE module)
|
||||||
* private -> self
|
* private -> self
|
||||||
* private(symbol, ...) -> self
|
* private(symbol, ...) -> self
|
||||||
* private(string, ...) -> self
|
* private(string, ...) -> self
|
||||||
|
* private(array) -> self
|
||||||
*
|
*
|
||||||
* With no arguments, sets the default visibility for subsequently
|
* With no arguments, sets the default visibility for subsequently
|
||||||
* defined methods to private. With arguments, sets the named methods
|
* defined methods to private. With arguments, sets the named methods
|
||||||
|
|
Загрузка…
Ссылка в новой задаче