Ruby module_function, invoking module's private method, invoked in class method style on module shows error

module, private-methods, ruby

Solution

It works when you include the module in a class, because then all of the module's methods get included in that class (the `self` in `module_func_a` points to `MyClass`, which has also the `private_b` method).

In the other situation self points to `MyModule`, which does not have private_b method. If you wanted it to work both ways, you'd have to either declare `private_b` as a module method as well, or simply add the line `extend self` to `MyModule`, so that all it's methods would become module methods.

Problem

test_module.rb ``` module MyModule def module_func_a puts "module_func_a invoked" private_b end module_function :module_func_a private def private_b puts "private_b invoked" end end class MyClass include MyModule def test_module module_func_a end end ``` Invoking module function from class ``` c = MyClass.new c.test_module ``` Output 1: ``` $ ruby test_module.rb module_func_a invoked private_b invoked ``` Invoking module function on module in class method style ``` ma = MyModule.module_func_a ``` Output 2: ``` module_func_a invoked test_module.rb:5:in `module_func_a': undefined local variable or method `private_b' for MyModule:Module (NameError) from test_module.rb:31 ``` As can be seen from the Output 1 and Output 2 when including the module in a class, no issue occurs when a module's private method gets invoked from a module function while in case when directly invoking the module function on the module in class method style the module's private method, invoked from module function, is not found. Can anybody make me understand the reason behind above behavior and whether invoking module function (which in turn invokes module's private method) on module in class method style is possible or not? If possible, then what rectifications are required in my code to do the same?

Original source