Singleton 的思考
Jan 6, 2019
Everything in Ruby is an Object
1
Ruby 允许给单个对象增加方法,方法添加后只对该对象生效
1  | # foo 是 String 类的对象  | 
2
Ruby 允许给类添加类方法,方法添加后只对该类生效
1  | # 定义类方法的第一种方式  | 
3
Ruby 中一切皆是对象
类也是对象
所有类都是 Class 类的对象
#2 中的 Foo 类,也是 Class 类的对象,给 Foo 添加的类方法在其他 Class 的对象中不存在
1  | # 同为 Class 的对象,String 却没有 bar 方法  | 
#2 中给类 Foo 添加的类方法,就像给 #1 中给对象 foo 添加的方法一样
添加的都是单例方法
所以所谓的类方法,其实就是类对象的单例方法
只不过 #1 和 #2 它们作用在不同的对象上而已
1  | # 证明 bar 确实是 Foo 类的单例方法(类方法)  | 
如果对象是个实例对象,添加的方法就是他的单件方法
如果对象是个类,添加的方法就是这个类的类方法
4
Ruby 中查找方法遵循“向右一步,再向上”
先向右一步查找实例对象所属的类是否存在该方法,再向上查找该类的祖先类是否存在该方法

而单例方法并不定义在类中(否则所以实例对象都能共享)
所以单例方法存在在 ghost 里,这个 ghost 位于对象和类之间

这个 ghost 又被称作单例类,或单件类(singleton class)
5
单例类位于类和实例之间,像个幽灵,但是利用 class << obj 语法可以打开 obj 所属的单例类
比如 #2 的 Foo 类
1  | class Foo; end  | 
再比如 #1 中的实例对象 foo
1  | foo = 'bar'  | 
6
Ruby 的对象模型相当简洁,归根结底在于一切皆对象,本质上来说没有类方法和实例方法,只有属于对象的方法
Simple is hard