Ruby 《Ruby 元编程》读书笔记 (八)

lazybios · 2015年09月15日 · 最后由 lazybios 回复于 2016年06月26日 · 3090 次阅读

博客地址 :《Ruby 元编程》读书笔记 (八)

相关文章:

《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)

元编程的方法大概都在 Module 这里了吧:

晕晕的!还没有缓过来,请允许我先走一会神!

#2 楼 @douxiance 你有必要每个帖子都顶一遍吗?

#1 楼 @chenge 嗯 kernel 里也有不少会用到的

@rei 备注:不是每个,是我看过觉得好的。 有很多我完全看不懂,或者觉得事不关己的,自然会飘过。

虽然我不知道怎么统计每天的发帖或者回帖总数,但我估计我看过的应该低于 10%,回复的小于 5%。

笔记七好像链接不对啊

#8 楼 @douxiance 昨晚有 7 个帖子被你连续顶起,占了半个版面,我还以为受发帖机攻击了。回复又没有实质内容,如果是刷脸只会留下言而无物的印象。希望你发帖前充实一下内容,不要灌水。

看了楼主的文章,专门搜了下 ruby singleton class 的介绍,推荐这篇文章:http://www.devalot.com/articles/2008/09/ruby-singleton

#9 楼 @tommylike 多谢指正,已经修复过来了,顺便看了你推荐的文章 :plus1:

@rei

昨晚有7个帖子被你连续顶起,占了半个版面,我还以为受发帖机攻击了。

首先,一般我们每天上论坛的时间其实是有限的,时间相对集中。

如果看到感兴趣的,主要是表达一下对楼主的敬意 (不希望好的东西无人问津),这个不违背论坛的精神吧!

其次,我们的论坛是否存在首页显示规则待完善的地方呢?

#13 楼 @douxiance 顶楼本身就有索引,顶一个贴就能看到之前的帖子。

论坛规则不能覆盖所有情况,如果硬性规定不能连续顶贴是不合理的,因为有内容的回复不应该受限制;又或者钻空子,顶两个隔一个,占完整屏。所以版面管理有弹性空间,管理员觉得不合理的就先言语制止。

你回一个贴,就要抢占一次别人的注意力,点进去什么实质性内容都没有,这样会让看贴的人很烦,并且其他主题被挤下去了。所以论坛一般有个约定,不能恶意灌水,就算是灌水区都会处理那些沾满整屏的发帖者。你如果一意孤行继续这样,我暂时不会处理,看看别人会不会对你反感。

@rei 为了避免被打上灌水的标签,后边我尽量不回复了。 打字其实挺累的,有时间我可以多看几行代码,何乐而不为呢!

lazybios 《Ruby 元编程》读书笔记 (十六)[连载完结] 提及了此话题。 06月26日 10:50
lazybios 《Ruby 元编程》读书笔记 (九) 提及了此话题。 06月26日 10:50
lazybios 《Ruby 元编程》读书笔记 (十) 提及了此话题。 06月26日 10:50
lazybios 《Ruby 元编程》读书笔记 (十一) 提及了此话题。 06月26日 10:50
lazybios 《Ruby 元编程》读书笔记 (十二) 提及了此话题。 06月26日 10:50
lazybios 《Ruby 元编程》读书笔记 (十三) 提及了此话题。 06月26日 10:50
lazybios 《Ruby 元编程》读书笔记 (十四) 提及了此话题。 06月26日 10:50
lazybios 《Ruby 元编程》读书笔记 (十五) 提及了此话题。 06月26日 10:50
需要 登录 后方可回复, 如果你还没有账号请 注册新账号