元编程:对象模型

第一章节的内容是对象模型,相对来说比较简单,本篇文章先直接总结知识点,其实以后再回过头来看本篇文章的时候直接看知识点总结就可以了,除了知识点的罗列之外,重点介绍几个关键性的知识,比如self的使用,方法查找、方法执行、Kernel模块中定义的方法、私有方法调用的方式等。

下面是这个章节的知识点总结:

  1. 对象由一组实例变量和一个类的引用组成
  2. 对象的方法存在于对象所属的类中,从类的角度看,它们叫做实例方法
  3. 类本身是Class类的对象,类的名字不过是一个常量而已
  4. Class类是Module的子类,一个模块基本上是由一组方法组成的包,类除了具有模块的特性之外,还可以被实例化(new)以及被组织为层次结构(superclass)
  5. 常量像文件系统一样,是按照树形结构组织的,其中模块和类的名字扮演目录的角色,其他普通的常量则扮演文件的角色
  6. 每个类都有一个祖先链,这个链从自己所属的类开始,向上直到BasicObject类结束
  7. 当调用一个方法时,Ruby首先向右一步到接受者所属的类,然后一直向上查找祖先链,直到找到该方法,或者到达链的顶端为止
  8. 每当类包含一个模块时,该模块会被插入到祖先链中,位置在该类的正上方
  9. 当调用一个方法时,接收者会扮演self的角色
  10. 当定义一个模块或者类时,该模块扮演self的角色
  11. 实例变量永远被认定为self的实例变量
  12. 任何没有明确指定接受者的方法调用,都当成是调用self的方法。
self的使用

如知识点9、10所示,self的角色通常由最后一个接收到方法调用的对象来充当,不过在类和模块的定义中,并且在任何方法定义之外,self的角色由这个类或模块担任,代码如下所示:

class MyClass
  puts self      #打印结果是MyClass
end

当前对象显示,在类或者模块外面,当前对象是main,代码如下所示:

puts self  #这段代码返回的是main
private的使用

私有(private)方法是实现一个类时使用的内部方法,它只能被这个类(或者它的子类)的实例方法所调用。私有方法只能隐式地被self对象调用,并且不能通过一个对象进行显式调用。如果m是一个私有方法,那么只能用m这种方式来调用它,而不能用obj.m或者self.m来调用它,代码如下所示:

class C
  def public_method
    self.private_method()
  end

  private
  def private_method
  end
end

C.new.public_method  #这段代码会报出NoMethodError
方法查找

规则:向右一步,再向上,先向右一步来到接收者所在的类,然后沿着祖先链向上直到找到给定的办法,代码如下所示:

class MyClass
end

class MySubClass < MyClass
end

puts MySubClass.ancestors #这段代码打印出来的结果是[MySubClass, MyClass, Object, Kernel, BasicObject]

如果类中include模块,代码如下所示:

module Printable
end

module Document
end

class Book
  include Document
  include Printable
end


puts Book.ancestors #这段代码返回的是[Book, Printable, Document, Object, Kernel, BasicObject]
#上面这段代码说明最后include的模块,其方法最先被使用
#假如Document和Printable模块都包含了print方法,Book类的实例调用print方法,最先调用的是模块Printable中的方法

以上的代码说明,后加入的模块刚好在Book类的下面。

方法执行

下面的代码是演示代码执行:

class MyClass
  def testing_self
    my_method  #这段代码的作用和self.my_method一致
  end

  def my_method
    puts "this is my_method"
  end
end

obj = MyClass.new
obj.testing_self  #这段代码返回的是this is my_method

上面代码中testing_self的self是obj,在方法内部中调用my_method,其self也是obj,my_method和self.my_method的作用是一样的。

Kernel方法的调用

Kernel中的方法也被称为Kernel method(内核方法),这个关键知识点也可以见我提出的一个问题,问题内容见链接,问题中的知识点总计已经整理成文章

Refinement

修改类带来一个问题就是,这种修改是全局性的,解决这个方法的方案是使用refinement,而且只能在模块中进行refine,类中不行。

refinement只在三种场合有效:

  • refine代码块内部
  • 如果是模块中,从using开始到模块结束
  • 如果是顶层上下文中,从using开始到文件结束
#在refine代码块内部有效的代码如下所示:
module StringExtensions
  refine String do
    def to_alphanumeric
      gsub(/[^\w\s]/, '')
    end

    "**first**".to_alphanumeric #=>first
  end
end

在全局中使用refinement
module StringExtensions
  refine String do
    def to_alphanumeric
      gsub(/[^\w\s]/, '')
    end
  end
end

"my *first* refinement!".to_alphanumeric  #undefined method

using StringExtensions
"my *first* refinement!".to_alphanumeric #=>my first refinement

在模块中使用refinement
module StringExtensions
  refine String do
    def reverse
      "cc"
    end
  end
end

module StringStuff
  using StringExtensions
  "my_string".reverse  #=>"cc"
end

"my_string".reverse #=> "gnirts_ym"
测试

1、利用ancestors方法理解类的继承和模块导入原则
2、利用refine方法介绍refinement的三种形式

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容