You could write the following.
module A
def name
"name from A"
end
end
module B
def print_name
"name from B"
end
end
module C
include A
include B
def self.included(klass)
B.instance_methods(false).each { |m| klass.send(:private, m) }
end
end
class Z
include C
def test
print_name
end
end
Then
Z.instance_methods.include?(:name)
#=> true
Z.private_instance_methods.include?(:print_name)
#=> true
z = Z.new
#=> #<Z:0x00007fb0f810ad28>
z.name
#=> "name from A"
z.print_name
#=> NoMethodError: private method 'print_name' called for #<Z:0x00007fb0f810ad28>
z.test
#=> "name from B"
See Module#included. This is one of several so-called "hook methods".
Suppose Z were as follows.
class Z
def print_name
"name from Z"
end
include C
def test
print_name
end
end
Then
z.print_name
#=> NoMethodError: private method 'print_name' called for #<Z:0x00007fb0f810ad28>
z.test
#=> "name from Z"
This demonstrates that it is the original public method Z#print_name has been made private. Note:
C.ancestors
#=> [Z, C, B, A, Object, Kernel, BasicObject]