1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Make Module#redefine_method to keep method visibility

Before this commit `Module#redefine_method` always changes
visibility of redefined method to `public`.
This commit changes behavior of Module#redefine_method` to
keep method visibility.
This commit is contained in:
yui-knk 2015-10-26 18:12:51 +09:00
parent 0946318386
commit 7189e5554e
2 changed files with 32 additions and 1 deletions

View file

@ -16,7 +16,20 @@ class Module
# Replaces the existing method definition, if there is one, with the passed
# block as its body.
def redefine_method(method, &block)
visibility = method_visibility(method)
remove_possible_method(method)
define_method(method, &block)
send(visibility, method)
end
def method_visibility(method) # :nodoc:
case
when private_method_defined?(method)
:private
when protected_method_defined?(method)
:protected
else
:public
end
end
end

View file

@ -7,6 +7,16 @@ module RemoveMethodTests
return 1
end
def do_something_protected
return 1
end
protected :do_something_protected
def do_something_private
return 1
end
private :do_something_private
class << self
def do_something_else
return 2
@ -34,8 +44,16 @@ class RemoveMethodTest < ActiveSupport::TestCase
def test_redefine_method_in_an_object
RemoveMethodTests::A.class_eval{
self.redefine_method(:do_something) { return 100 }
self.redefine_method(:do_something_protected) { return 100 }
self.redefine_method(:do_something_private) { return 100 }
}
assert_equal 100, RemoveMethodTests::A.new.do_something
assert_equal 100, RemoveMethodTests::A.new.send(:do_something_protected)
assert_equal 100, RemoveMethodTests::A.new.send(:do_something_private)
assert RemoveMethodTests::A.public_method_defined? :do_something
assert RemoveMethodTests::A.protected_method_defined? :do_something_protected
assert RemoveMethodTests::A.private_method_defined? :do_something_private
end
end
end