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.
从模块中包含模块的输出1和输出2可以看出,当模块的私有方法从模块函数调用时,如果在类方法样式中直接调用模块上的模块函数,则不会出现问题找不到模块函数调用的模块私有方法。
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?
任何人都可以让我理解上面的行为背后的原因,是否可以在类方法风格的模块上调用模块函数(进而调用模块的私有方法)?如果可能的话,我的代码中需要做哪些修正才能做同样的事情?
2 个解决方案
#1
6
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).
当你在一个类中包含模块时,它可以工作,因为然后所有模块的方法都包含在该类中(module_func_a中的self指向MyClass,它也有private_b方法)。
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.
在另一种情况下,self指向MyModule,它没有private_b方法。如果您希望它以两种方式工作,您必须将private_b声明为模块方法,或者只需将行extend self添加到MyModule,这样它的所有方法都将成为模块方法。
#2
3
module_function
does copy your module_func_a
into the metaclass but not its dependencies.
module_function会将module_func_a复制到元类中,但不会复制到其依赖项中。
So when calling module_func_a
from an object, you get the other method private_b
. But calling it on the module itself fails because private_b
is not a module function.
因此,当从对象调用module_func_a时,您将获得另一个方法private_b。但是在模块本身上调用它会失败,因为private_b不是模块函数。
You should use module_function for private_b
too and it should work.
您也应该将module_function用于private_b,它应该可以工作。
#1
6
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).
当你在一个类中包含模块时,它可以工作,因为然后所有模块的方法都包含在该类中(module_func_a中的self指向MyClass,它也有private_b方法)。
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.
在另一种情况下,self指向MyModule,它没有private_b方法。如果您希望它以两种方式工作,您必须将private_b声明为模块方法,或者只需将行extend self添加到MyModule,这样它的所有方法都将成为模块方法。
#2
3
module_function
does copy your module_func_a
into the metaclass but not its dependencies.
module_function会将module_func_a复制到元类中,但不会复制到其依赖项中。
So when calling module_func_a
from an object, you get the other method private_b
. But calling it on the module itself fails because private_b
is not a module function.
因此,当从对象调用module_func_a时,您将获得另一个方法private_b。但是在模块本身上调用它会失败,因为private_b不是模块函数。
You should use module_function for private_b
too and it should work.
您也应该将module_function用于private_b,它应该可以工作。