1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/spec/ruby/core/module/private_spec.rb
Jeremy Evans 75ecbda438 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]
2021-11-18 09:47:40 -08:00

107 lines
2.5 KiB
Ruby

require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/set_visibility'
describe "Module#private" do
it_behaves_like :set_visibility, :private
it "makes the target method uncallable from other types" do
obj = Object.new
class << obj
def foo; true; end
end
obj.foo.should == true
class << obj
private :foo
end
-> { obj.foo }.should raise_error(NoMethodError)
end
it "makes a public Object instance method private in a new module" do
m = Module.new do
private :module_specs_public_method_on_object
end
m.should have_private_instance_method(:module_specs_public_method_on_object)
# Ensure we did not change Object's method
Object.should_not have_private_instance_method(:module_specs_public_method_on_object)
end
it "makes a public Object instance method private in Kernel" do
Kernel.should have_private_instance_method(
:module_specs_public_method_on_object_for_kernel_private)
Object.should_not have_private_instance_method(
:module_specs_public_method_on_object_for_kernel_private)
end
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
it "raises a NameError when given an undefined name" do
-> do
Module.new.send(:private, :undefined)
end.should raise_error(NameError)
end
it "only makes the method private in the class it is called on" do
base = Class.new do
def wrapped
1
end
end
klass = Class.new(base) do
def wrapped
super + 1
end
private :wrapped
end
base.new.wrapped.should == 1
-> do
klass.new.wrapped
end.should raise_error(NameError)
end
it "continues to allow a prepended module method to call super" do
wrapper = Module.new do
def wrapped
super + 1
end
end
klass = Class.new do
prepend wrapper
def wrapped
1
end
private :wrapped
end
klass.new.wrapped.should == 2
end
end