Ruby module_function that calls the private method of the module is called in the style of the method method on the module, shows an error

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 

Calling a module function from a class

  c = MyClass.new c.test_module 

Output 1:

 $ ruby test_module.rb module_func_a invoked private_b invoked 

Calling a module function on a module in the style of a class method

 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 Output 1 and Output 2 when a module is included in a class, the problem does not arise when a private module method is called from a module function, while in the case of a direct call to a module function in a module in a class class method, a private module method called from a module function , not found.

Can someone make me understand the reason for the above behavior and is it possible to use a module function (which, in turn, calls a private module method) on a module in the style of a class method or not? If possible, what corrections are required in my code to do the same?

+7
source share
2 answers

This works when you include a module in a class, because then all the module methods are included in this class ( self in module_func_a points to MyClass , which also has a private_b method),

In another situation, self points to MyModule , which does not have a private_b method. If you want it to work in both directions, you need to either declare private_b as a module method, or simply add the extend self line to MyModule so that all its methods become modular methods.

+6
source

module_function copies your module_func_a to the metaclass, but not its dependencies.

Therefore, when you call module_func_a from the object, you get another private_b method. But calling it to the module itself fails, because private_b not a module function.

You should also use module_function for private_b , and it should work.

+3
source

All Articles