为什么模块的单例方法在混合的下游特征类中不可见?

我理解常规方法查找路径,即class, superclass/module, all the way up to BasicObject 。 我认为链的单例版本也是如此,但是当您在元链中混合模块时似乎并非如此。 我很感激,如果有人能解释为什么在下面的示例中,当我将此模块包含在Vehicle的本征类中时,调用Automobile模块的banner方法而不是其单例版本。

 module Automobile def banner "I am a regular method of Automobile" end class << self def banner "I am a singleton method of Automobile" end end end class Vehicle def banner "I am an instance method of Vehicle" end class << self include Automobile def banner puts "I am a singleton method of Vehicle" super end end end class Car < Vehicle def banner "I am an instance method of Car" end class << self def banner puts "I am a singleton method of Car" super end end end puts Car.banner # I am a singleton method of Car # I am a singleton method of Vehicle # I am a regular method of Automobile 

首先, include不包括你所期望的本征类方法。 考虑:

 module Foo class << self def do_something puts "Foo's eigenclass method does something" end end end module Bar include Foo end puts Bar.do_something # undefined method `do_something' for Bar:Module (NoMethodError) 

请注意,这与经典定义的类方法的行为一致:

 module Foo def self.do_something puts "Foo's class method does something" end end module Bar include Foo end puts Bar.do_something # undefined method `do_something' for Bar:Module (NoMethodError) 

一个常见的习惯用法是在子模块中定义类方法,然后在包含模块时触发调用以进行extend

 module Foo def self.included(base) base.extend ClassMethods end module ClassMethods def do_something puts "Foo::ClassMethod's instance method does something" end end end module Bar include Foo end puts Bar.do_something # Foo::ClassMethod's instance method does something 

第二点需要注意的是,您确实将Automobile的实例方法包含在Vehicle本征类中,因此Automobile的实例方法转化为Vehicle (本征)类方法。

你的Car课基本上与这一切无关。 这里唯一需要注意的是,类inheritance也使类方法可用,而include则没有。 例:

 class Foo def self.do_something puts "Foo's class method does something" end end class Bar < Foo end puts Bar.do_something # "Foo's class method does something" 

首先,类是一个对象,就像其他对象一样,它也有自己的超类; 第二,Eigenclass本身是一个普通的类,只有匿名和sorta隐形; 第三,派生类的特征类的超类是基类的本征类; 第四, include包含包含模块的实例方法(不是单例方法),使它们成为接收器类对象的实例方法。

您的示例中有两个并行的inheritance链

车<车<...

汽车的本征级<汽车的本征级<汽车<...

在irb上进行以下测试:

 class Object def eigenclass class << self self end end end Car.ancestors # => [Car, Vehicle, Object, Kernel, BasicObject] Car.eigenclass.ancestors # => [Automobile, Class, Module, Object, Kernel, BasicObject] Vehicle.eigenclass.ancestors # => [Automobile, Class, Module, Object, Kernel, BasicObject] Car.eigenclass.superclass.equal? Vehicle.eigenclass # => true 

你看, Automobile属于本征类inheritance链。 但令人遗憾的是, ancestor方法并没有返回不可见的本征类,尽管如此,它们实际上是在第二个链中。