Ruby module_function,调用模块的私有方法,在模块的类方法样式中调用显示错误

时间:2012-04-06 11:26:58

标签: ruby module private-methods

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 可以看出,当在模块中包含模块时,从模块函数调用模块的私有方法时不会出现问题 如果在类方法样式中直接调用模块上的模块函数,则找不到模块函数调用的模块私有方法。

任何人都可以让我理解上述行为背后的原因,是否可以在类方法样式中调用模块函数(进而调用模块的私有方法)?如果可能的话,我的代码中需要做哪些修正才能做同样的事情?

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,它应该可以工作。