Ruby中,当我们在方法调用的运行时,对象会查找他隶属的类,module,父类等,来找到相对应的方法。
Singleton/Meta/Anonymous/Ghost/Shadow Class
1.Singleton Class: 单例类
2.Meta Class:元类
3.Anonymous Class: 匿名类
4.Ghost Class:鬼类
5.Shadow Class: 影子类
上面的这些东东其实说的都是一个东西,我喜欢叫它 影子类。
Ruby中每一个对象都一个一个影子类,这个影子类存在于对象跟它所属的类之间:
对象("obj1") -> 影子类 -> 对象所属的类(String)
当一个对象的方法被调用时,首先查找的是影子类,之后才是它所属的类。
上面讲到实例变量存在于对象内,方法存在于对象的类中。
影子类上的方法,就是只有这一个对象拥有的方法。这个方法通常叫做单例方法(Singleton Method)。
这样的方法只存在于这个对象上,同一个类的其他对象没有这个方法,因为他们的影子类不同,其他对象的影子类上没有这个方法。
>> a = "obj1"
=> "obj1"
>> def a.hello
>> puts "hello world"
>> end
=> nil
>> a.hello
hello world
=> nil
>> b = "obj2"
=> "obj2"
>> b.hello
NoMethodError: undefined method `hello' for "obj2":String
from (irb):49
>> a.singleton_methods
=> ["hello"]
>> b.singleton_methods
=> []
Self
Ruby里面一切都是对象,self也是对象,确切地说是当前对象的引用。
前文说Ruby的方法调用是消息模式,比如obj.method, 消息的接受者是.之前的对象,.之后的是方法及参数。
如果对象和.没有出现的话,消息会被默认送到self对象。除了作为方法的默认接受者,self也是实例变量的解析对象。
self在ruby一开始的时候,被设定为一个叫做main的对象,再irb里面可以看到:
>> m = self
=> main
self可以被认为是一个特殊的变量,它的特殊性在于,你不能给他赋值:
>> self = "obj"
SyntaxError: compile error
(irb):77: Can't change the value of self
self = "obj"
^
有几个办法可以改变self的值,.(obj.method的.)是其中一个,除了.还有class/module关键字。
本回主要关注跟对象相关的.
当我们用obj.method调用方法时,接下来的时间代码的执行就会到相应的方法里,运行的上下文切换到那个对象,self自然也变成了那个对象。用def定义单例方法时,道理也是相通的。 下面的例子可以说明这个self切换的情况。
>> a = "obj"
=> "obj"
>> def a.hello_self










