特征类


obj = Object.new
class << obj
end

你知道这段代码中的 class 是什么吗?这段代码中的 class 定义的实际上就是 obj 这个对象的“单例类”。本帖主要是针对对 Ruby 单例类已经有了正确概念的朋友,否则可能不知所云。

Ruby 社区就 Ruby 的“单例类”这个术语的命名曾有过许多争议。至今,Ruby 的创造者 Matz 也没有宣布一个正式的、官方的名称。在大部分书籍,包括《The Ruby Programming Language》中,都使用了“单例类”(Singleton class)这个术语,故而“单例类”也就成了 Ruby 的“单例类”概念的 de facto(约定俗成的)命名。除了“单例类”这个命名以外,主要还有另外两种命名:“元类”(Metaclass)和“特征类”(Eigenclass)。

“元类”实际上在更早的时候就出现了。Smalltalk、Java、C#、Python 中都有被称为“元类”的概念。然而,这些语言中的元类和 Ruby 的“单例类”颇有不同。传统意义上的元类,说白了,就是类的类,是用来描述一种类的类型,其实例就是一个类。这相当于 Ruby 中的 Class 类——所有对象的类的类型都是这个 Class 类的实例。这当然和“单例类”风马牛不相及,所以以“元类”来命名 Ruby “单例类”的概念并不合适。

“特征类”是一个很好的命名。这个“特征”和线性代数中“特征值”、“特征向量”的“特征”是一个意思。“特征值”、“特征向量”的名称是由德国数学家 David Hilbert (大卫·希尔伯特)在 1904 年使用并得以流传的,德语单词“Eigen”本意为“自己的”。Eigenclass,也就意味着“自己的类”,用于 Ruby 的“单例类”概念之上十分贴切,因为“单例类”实际上就是一个对象独有的类。

我个人认为使用最广泛的“单例类”这个名称并不好,因为这很容易和著名的单例类设计模式混淆。单例类设计模式是在设计类的时候保证其实例只有一个,而 Ruby 的“单例类”却是先有一个可有多个实例的类型,比如本帖开头的 Object 类型,而后对其某个实例进行“单例的类”(及其方法)的创建。这么一想,是不是觉得“特征类”更加贴切了(特别是对于专精于线性代数的你)?

Eigenclass 这个术语应该算是 Ruby 社员的发明创造。上文提到的“特征类”是我直接从线性代数中 eigenvalue、eigenvector 取来的,也并非是正式的、官方的翻译。就目前来说,使用 eigenclass 的英语原型是最不会引起歧义的。

关于 eigenclass 的命名,更详细的讨论参见:http://www.ruby-forum.com/topic/571597

One Comment

  1. Posted 2011/08/20 at 22:12 | Permalink | Reply

    老板,我摘引了其中一段内容,参见:http://deathking.is-programmer.com/posts/28861

One Trackback

  1. By Ruby元编程(一) | Mr.Cpp on 2018/11/18 at 00:01

    […]   ——参考自紫苏的特征类一文     […]

Leave a comment