为什么模块的’self’方法不能成为类的单例方法?

module Test def self.model_method puts "this is a module method" end end class A include Test end A.model_method 

这将是错误的:

A:Class的未定义方法`model_method’(NoMethodError)

但是当我使用A的元类时,它可以工作:

 module Test def model_method puts "this is a module method" end end class A class << self include Test end end A.model_method 

有人可以解释一下吗?

如果您希望在包含模块时将类方法和实例方法混合到类中,则可以遵循以下模式:

 module YourModule module ClassMethods def a_class_method puts "I'm a class method" end end def an_instance_method puts "I'm an instance method" end def self.included(base) base.extend ClassMethods end end class Whatever include YourModule end Whatever.a_class_method # => I'm a class method Whatever.new.an_instance_method # => I'm an instance method 

基本上是为了过度简化它,您可以extend为添加类方法,并添加实例方法。 当包含一个模块时,它的#included方法被调用,包含它所包含的实际类。从这里你可以用另一个模块中的一些类方法extend类。 这是一种非常常见的模式。

另见: http : //api.rubyonrails.org/classes/ActiveSupport/Concern.html

包含模块类似于复制其实例方法。

在您的示例中,没有要复制到A实例方法。 model_method实际上是Test的singleton类的实例方法。


鉴于:

 module A def method end end 

这个:

 module B include A end 

类似于:

 module B def method end end 

当你以这种方式想到它时,这是完全合理的:

 module B class << self include A end end B.method 

这里,方法被复制到B模块的单例类,这使它们成为B的“类方法”。

请注意,这与以下内容完全相同:

 module B extend A end 

实际上,这些方法并没有被复制; 没有重复 。 该模块仅包含在方法查找列表中。