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
从类
调用模块函数 c = MyClass.new
c.test_module
输出1:
$ ruby test_module.rb
module_func_a invoked
private_b invoked
在类方法样式中调用模块上的模块函数
ma = MyModule.module_func_a
输出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
从输出1和输出2 可以看出,当在模块中包含模块时,从模块函数调用模块的私有方法时不会出现问题 如果在类方法样式中直接调用模块上的模块函数,则找不到模块函数调用的模块私有方法。
任何人都可以让我理解上述行为背后的原因,是否可以在类方法样式中调用模块函数(进而调用模块的私有方法)?如果可能的话,我的代码中需要做哪些修正才能做同样的事情?
答案 0 :(得分:7)
当您将模块包含在类中时,它会起作用,因为所有模块的方法都包含在该类中(self
中的module_func_a
指向MyClass
,这也是private_b
方法)。
在另一种情况下,self指向MyModule
,它没有private_b方法。如果您希望它以两种方式工作,您必须将private_b
声明为模块方法,或者只需将行extend self
添加到MyModule
,以便所有方法都可以将成为模块方法。
答案 1 :(得分:3)
module_function
会将您的module_func_a
复制到元类中,但不会复制到其依赖项中。
因此,当从对象调用module_func_a
时,您将获得另一种方法private_b
。但是在模块上调用它会失败,因为private_b
不是模块函数。
你也应该对private_b
使用module_function,它应该可以工作。