diff --git a/activesupport/lib/active_support/core_ext/module/remove_method.rb b/activesupport/lib/active_support/core_ext/module/remove_method.rb index 287ec477a0..d5ec16d68a 100644 --- a/activesupport/lib/active_support/core_ext/module/remove_method.rb +++ b/activesupport/lib/active_support/core_ext/module/remove_method.rb @@ -16,7 +16,20 @@ def remove_possible_singleton_method(method) # 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 diff --git a/activesupport/test/core_ext/module/remove_method_test.rb b/activesupport/test/core_ext/module/remove_method_test.rb index 77774afb0d..0d684dc70e 100644 --- a/activesupport/test/core_ext/module/remove_method_test.rb +++ b/activesupport/test/core_ext/module/remove_method_test.rb @@ -7,6 +7,16 @@ def do_something 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 @@ def test_remove_singleton_method_from_an_object 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 \ No newline at end of file +end