直接回答你的问题:Module#define_method
创建一个实例方法。“类方法”是对象的单例类(或特征类)上的实例方法Class
。我敢肯定这听起来很令人困惑。让我解释一下为什么 Ruby 首先包含“单例类”的概念:
首先,让我说不同面向对象语言的基本“框架”是多种多样的。Ruby 在对象、类、元类等方面的设计绝不是唯一可能的设计,该语言可以以不同的方式设计。话虽如此,Ruby 以它的方式工作是有逻辑的原因的。我会尽量简明扼要地解释...
考虑一个简单的方法调用,例如:
[1,2,3].first
在这里,我们调用了一个名为 的方法first
,其中一个Array
对象作为接收者。为了处理这个方法调用,Ruby 需要搜索匹配的方法定义并执行它。它从哪里开始寻找?自然,在 的实例方法中Array
。如果在那里没有找到,它会在Array
's 的超类中查找,然后是超类的超类,以及Module
混入的 sArray
或其超类等。
“基于类”(与基于原型相反)的面向对象语言或多或少都以这种方式工作。如果您曾经使用 Java、C++ 或 Python 进行过编程,那么您应该对这种行为很熟悉。
现在,Ruby 的创建者还希望能够为一个对象添加方法。在基于原型的 OO 语言中,这很容易,但它如何在基于类的语言中工作?他通过引入“单例类”或“特征类”的概念使之成为可能。
简单地说,“单例类”是只有一个实例的类。我相信,与其尝试为每个对象跟踪不同的单例类,Ruby 会等到您第一次尝试访问对象的单例类,然后创建该类并将其动态插入到对象的继承链中。
正如我刚才所说,当一个方法被调用时,Ruby首先在对象的类中查找匹配的定义,然后是超类等。由于单例类作为对象继承链中的第一个链接插入,因此它们是第一位的Ruby 将寻找方法定义。
引入“单例类”的概念同时也解决了另一个问题。在 Java 中(例如),您可以定义static
在类上调用的方法。在 Ruby 中,人们经常想做类似的事情。使用“单例”类和方法,您可以做到这一点:您所要做的就是在 Class 对象上定义一个单例方法。
(请记住,在 Ruby 中,类也是对象。这就是为什么“单例”类和方法的概念可以“用 1 块石头杀死 2 只鸟”的原因,正如我在上面解释的那样!)
额外的信息:
一开始,我提到了“实例方法”。我不知道这是否会令人困惑,或者您是否已经知道“实例方法”是什么。当你定义一个 Ruby 类时,像这样......
class MyClass
def my_method
# do something
end
end
...然后my_method
将作为. MyClass
当 Ruby 在对象的类、超类等中搜索方法定义时,它实际查看的是它们的实例方法。所以一个对象的“方法”就是它的类的实例方法,加上超类的实例方法、超类的超类等等。
关于单例类如何与 Ruby 中的方法查找交互,有一点我上面没有提到的不一致。如果你想详细了解:
类对象的单例类的处理方式与一般其他对象的单例类略有不同。如果您有一个A
从另一个类继承的类B
,并且B
具有单例方法,A
则不仅会继承实例方法,还会继承的单例方法B
。换句话说,B
的单例类被视为 的单例类的超A
类。这不适用于任何其他对象的单例类。