博客地址 :《Ruby 元编程》读书笔记 (八)
相关文章:
《Ruby 元编程》读书笔记 (一) 《Ruby 元编程》读书笔记 (二) 《Ruby 元编程》读书笔记 (三) 《Ruby 元编程》读书笔记 (四) 《Ruby 元编程》读书笔记 (五) 《Ruby 元编程》读书笔记 (六) 《Ruby 元编程》读书笔记 (七)
传神的头图↓↓↓
我们知道 Ruby 中对象的方法的查找顺序是:先向右,再向上,其含义就是先向右找到对象的类,先在类的实例方法中尝试查找,如果没有找到,再继续顺着祖先链找。
前面一篇中有介绍过单件方法,单件方法是指那些只针对某个对象有效的方法,那么如果为一个对象定义了单件方法,那么这个单件方法的查找顺序又应该是怎样的?
class MyClass
def my_method; end
end
obj = MyClass.new
def obj.my_singleton_method; end
首先,单件方法不会在 obj 中,因为 obj 不是一个类,其次它也不在 MyClass 中,那样的话所有的 MyClass 都应该能共享调用这个方法,也就构不成单件类了。同理,单件方法也不能在祖先链的某个位置 (类似 superclass: Object) 中。正确的位置是在单件类中,这个类其实就是我们在 irb 中向对象询问它的类时 (obj.class) 得到的那个类,不同的是这类与普通的类还是有稍稍不同的。也可以称其为元类或本征类。
Ruby 提供了两种方法获取单件类的引用,一种是通过传统的关键词 class 配合特殊的语法
class << an_object
# 自己的代码
end
obj = Object.new
singleton_class = class << obj
self
end
singleton_class.class # => Class
另一个方法是,通过Object#singleton_class方法来获得单件类的引用:
“abc”.singleton_class # => #<Class: #<String:0xxxxxx>>
基于上面对单件类的基本认识,引入单件类后,Ruby 的方法查找方式就不应该是先从其类 (普通类) 开始,而是应该先从对象的单件类中开始查找,如果在单件类中没有找到想要的方法,它才会开始沿着类 (普通类) 开始,再到祖先链上去找。这样从单件类之后开始,一切又回到了我们在没有引入单件类时候的次序。
通过下面这个代码可以自行验证一下
class C
def a_method
‘C#a_method()’
end
end
class D < C; end
obj = D.new
#打开单件类定义单件方法
class << obj
def a_singleton_method
‘obj#a_singleton_method()’
end
end
obj.singleton_class.superclass #=> D
-待续-
=============== 最后贴一下自己的公众账号
可以十日不将军,不可一日不拱卒,日拱一卒 (rigongyizu365)