sai*_*ala 7 ruby inheritance mixins eigenclass
我理解常规方法查找路径即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
Run Code Online (Sandbox Code Playgroud)
首先,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)
Run Code Online (Sandbox Code Playgroud)
请注意,这与经典定义的类方法的行为一致:
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)
Run Code Online (Sandbox Code Playgroud)
一个常见的习惯用法是在子模块中定义类方法,然后在包含模块时触发调用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
Run Code Online (Sandbox Code Playgroud)
第二点要注意的是,你实际上是将实例方法包含Automobile到了本征类中Vehicle,因此将实例方法Automobile转化为(本征)类方法Vehicle.
你的Car班级基本上与这一切无关.这里唯一要注意的是,类继承也使类方法可用,而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"
Run Code Online (Sandbox Code Playgroud)