8

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

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

4

2 回答 2

7

当您将模块包含在一个类中时,它会起作用,因为然后模块的所有方法都包含在该类中(selfinmodule_func_a指向MyClass,它也具有该private_b方法)。

在另一种情况下 self 指向MyModule,它没有 private_b 方法。如果您希望它以两种方式工作,则必须同时声明private_b为模块方法,或者只需将行添加extend selfMyModule,以便它的所有方法都将成为模块方法。

于 2012-04-06T11:34:59.847 回答
3

module_function确实将您复制module_func_a到元类中,但不复制它的依赖项。

所以当module_func_a从一个对象调用时,你会得到另一个方法private_b。但是在模块本身上调用它会失败,因为private_b它不是模块函数。

您也应该使用 module_function private_b,它应该可以工作。

于 2012-04-06T11:32:50.330 回答