在过去的几个提示中,我们已经涵盖了祖先。 prepend和 include都是为了学习Ruby允许我们将代码导入到类中的不同方式。还有一种方法可以做到这一点,那就是extend 。然而,在我们直接跳到学习extend 之前,我们首先需要了解单子类。
单子类是Ruby对象模型的关键。假设我们有一个类的实例,并想在该实例上定义一个方法:
class ExampleClass ; end
example = ExampleClass.new
def example.example_method
"This is a singleton method"
end
example.example_method
=> "This is a singleton method"
Example.new.example_method
# NoMethodError (undefined method `example_method' for #<ExampleClass:0x00007f9686858a80>)
我们看到,我们的example 实例可以有它自己专门定义的方法,example_method ,它不会对其他的ExampleClass 实例起作用。但是example_method 存储在哪里?Ruby是如何跟踪它的呢?它被定义在example's singleton class上。
每个Ruby对象都有一个单子类。这允许我们做类似上面的事情:在实例上定义方法,并让它们只对这些实例起作用。我们还知道,Ruby中的类本身就是对象--所以也有单子类。这实际上就是类方法在引擎盖下的工作方式。
类方法实际上是一个类的单子类上的实例方法。让我们更深入地看看:
class ExampleClass
def self.example_class_method
"This is a class method"
end
end
ExampleClass.example_class_method
=> "This is a class method"
ExampleClass.singleton_class.instance_methods(false)
=> [:example_class_method]
单子类的深度足以让我们自己编写一个完整的系列不过现在,我们已经学到了我们需要的东西,以便在下周正确理解extend 的工作方式。也就是说,我们已经知道了类的方法是一个类的单子类的实例方法。