Ruby – Visibility of private and protected module methods when mixed into a class

Consider you have a module defining a public, a protected and a private method. What happens to this visibility declaration after mixing the module into a class?
Does Ruby ignore visibility information or does Ruby take over the visiblity settings?

The following example demonstrates that Ruby preserves the module’s visibility settings and keeps private methods private and protected methods protected:

module MyMethods
def my_public_method
puts "Public"
end

protected
def my_protected_method
puts "Protected"
end

private
def my_private_method
puts "Private"
end
end

require 'my_methods'

class MyClass
include MyMethods

def invoke_my_protected_method
my_protected_method
end

def invoke_my_private_method
my_private_method
end
end

class MyInheritedClass < MyClass
def invoke_my_protected_method_from_subclass
my_protected_method
end

def invoke_my_private_method_from_subclass
my_private_method
end
end

mc = MyClass.new

mc.my_public_method

begin
mc.my_protected_method
rescue NoMethodError
puts "Unable to call a protected method."
end

begin
mc.my_private_method
rescue NoMethodError
puts "Unable to call a private method."
end

mc.invoke_my_protected_method
mc.invoke_my_private_method

mic = MyInheritedClass.new
mic.invoke_my_protected_method_from_subclass

begin
mic.invoke_my_private_method
rescue NoMethodError
puts "Unable to call a private method of the parent class."
end

Output looks like this:

Public

Unable to call a protected method.

Unable to call a private method.

Protected

Private

Protected

Private

What we see is pretty much the same as declaring the module methods directly in our class. The fact that we use a mix-in didn’t change anything at all.

  • Our protected method may be invoked in MyClass as well as in MyInheritedClass but not outside of our classes.
  • The private method can only be used within MyClass but outside or in the inherited class MyInheritedClass.

So everything is just as expected. Isn’t Ruby a great thing?

Kommentarfunktion ist deaktiviert