`
任清宇
  • 浏览: 20612 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Ruby 元编程 第二版随笔(二)

    博客分类:
  • ruby
阅读更多

 

 

  调用方法时发生了什么? 

  What happens when you call a method?

 

      调用方法时Ruby会做两件事:

     (1)找到这个方法,这个过程成为方法查找。

   (2)执行这个方法,为了做到这点,ruby要用到一个称为self 的东西。

       

    1.方法查找

         Method lookup

         

      调用一个方法前,Ruby会在对象中查找那个方法。不过,在进一步学习之前,我们还要掌握两个新概念:接受者(receiver)和祖先链(ancestors chain)。接受者就是你调用方法所在的对象。例如,在my_string.reverse()语句中,my_string就是接收者。为了理解祖先链 的概念,可以先观察一个Ruby类。想像从一个类找到它的超类,然后依次往上找,直到找到basicObject(Ruby类体系结构的根节点)。在这个过程中,经历的类的路径就是该类的祖先链。(祖先链中可能会包含模块,后面再说。)

       知道了接收者和祖先链,就可以用一句话来概括方法查找的过程:Ruby首先在接收者的类中查找。然后顺着祖先链向上查找,直到找到这个方法为止。

       

class MyClass
  def my_method; 'my_method'; end
end

class MySubclass < MyClass
end

   

 obj = MySubclass.new
 obj.my_method()                #   => "my_method()"

  

           我们已经知道了祖先链是从类开始到其超类结束。 实际上,祖先链中也包含模块(module)。当吧一      个模块包含在一个类(或者一个模块)中时,Ruby就会把这个模块加入该类的祖先链中,该模块在祖先链      中的位置就在包含它的类之上。

   

module M1
  def my_method
    'M1#my_method()'
  end
end

class C
  inculde M1
end

class D < C; en   

 D.ancestors            #  =>  [D, C, M1, Object, Kernel, BasicObject] 

 

 

          从Ruby 2.0 开始,还可以用另外一种方法吧模块插入一个类的祖先链中:使用prepend方法。 他的功能和include方法相似, 不过这个方法会把模块插入到祖先链中包含它的该类的下方,而不像include方法那样插入上方:

   

class C2
  prepend M2
end

class D2 < C2; end

  

   

D2.ancestors                #   =>  [D2, M2, C2, Object, Kennel, BasicObject]

 

 

    关于include和prepend,还有一个重要的知识点。

 

   多重包含

 

   如果试图在某个类的祖先链中多次加入同一个模块,会如何呢?

 

module M1; end

module M2
  include M1
end

module M3
  prepend M1
  inculde M2
end

   

M3.ancestors        #  => [M1, M2, M3]

 

 

          可以看出虽然我们多次的添加模块但是最后并没有重复,每次include或者prepend的时候,如果该模块 已经存在于祖先链中, 那么Ruby会悄悄的忽略这个包含(include或prepend)指令。因此一个模块只会在一条祖先链中出现一次。

 

    无处不在的Kernel模块

 

    Ruby中有一些方法(如print)可以随时随地的进行调用,看起来就像是所有对象都有print方法一样。这是因为这些方法实际上都是kerenl模块的私有方法:

 

Kernel.pricate_instance_methods.grep(/^pr/) # => [:printf, :print, :proc]

 

 

        这里的秘密在于Object类包含了Kernel模块,因此Kernel模块就进入了每个对象的祖先链。于是,无论哪个对象都可以随意调用Kernel模块的方法。这使得print看起来就像一个关键字,其实它只是一个方法而已。 

分享到:
评论

相关推荐

    Ruby元编程第二版中文

    Ruby元编程第二版,中文影印版,便于英文不好的同学们学习

    ruby元编程.pdf

    ruby元编程.pdf ruby 元编程 这本书对ruby的调用原理做了非常精辟的分析。 ruby 元编程 这本书对ruby的元编程方式做了比较好的阐释。 ruby 元编程 这本书对结对编程有一个很好的提现。

    Ruby元编程 第2版 中文 佩罗塔著 2015.08

    ruby元编程 第2版 中文 目录清晰 方便广大通勤族路上看,如果喜欢请购买正版纸质图书

    《Ruby元编程》PDF版本下载.txt

    《Ruby元编程》PDF版本下载

    Ruby元编程中文版

    Ruby元编程中文版

    Ruby元编程pdf

    Ruby元编程pdf

    Ruby元编程-中文

    ruby 元编程 中文 《Ruby元编程》以案例形式循序渐进地介绍Ruby特有的实用编程技巧。通过分析案例、讲解例题、回顾Ruby代码库的实现细节,作者不仅向读者展示了Ruby编程的优势和Ruby特有的解决问题的方式,更详细开...

    Ruby编程,Ruby编程,

    Ruby编程,Ruby编程,Ruby编程,Ruby编程,Ruby编程,

    Ruby 元编程

    Ruby 一种面向对象程序设计的脚本语言 本书的第一部分“Ruby元编程”是本书的核心部分...本书的第二部分“Rails中的元编程”是一个元编程实例,Rail是Ruby标志性框架。 在阅读本书之前,需要了解本书的三个附录 A、B、C

    Ruby元编程【英文版】

    《Ruby元编程》以案例形式循序渐进地介绍Ruby特有的实用编程技巧。通过分析案例、讲解例题、回顾Ruby代码库的实现细节,作者不仅向读者展示了Ruby编程的优势和Ruby特有的解决问题的方式,更详细开列出发挥其优势的...

    ruby元编程

    《Ruby元编程》以案例形式循序渐进地介绍了Ruby特有的实用编程技巧 元编程 通过分析案例 讲解例题 回顾Ruby代码库的实现细节 《Ruby元编程》作者Paolo Perrotta不仅向读者展示了Ruby编程的优势和Ruby特有的解决问题...

    Ruby元编程 源代码 Metaprogramming Ruby source code

    Ruby元编程 书籍配套源代码 Metaprogramming Ruby source code

    Programming Ruby中文版(第二版)

    本书是它的第2版,其中包括超过200页的新内容,以及对原有内容的修订,涵盖了Ruby 1.8中新的和改进的特性以及标准库模块。它不仅是您学习Ruby语言及其丰富特性的一本优秀教程,也可以作为日常编程时类和模块的参考...

    Ruby编程语言中文版

    Ruby编程语言中文版,涵盖Ruby 1.8和Ruby 1.9

    Ruby 元编程 中文 高清扫描版

    Ruby 元编程 中文 高清扫描版, 完整中文版

    Metaprogramming Ruby 2nd Edition ruby元编程

    Metaprogramming Ruby 2nd Edition ruby元编程

    Ruby动态编程对象编程Ruby动态编程对象编程Ruby动态编程对象编程

    2. 动态性:Ruby是一门动态性极强的编程语言,允许开发人员在运行时通过元编程(metaprogramming)来修改和扩展代码的行为。这种动态性使得Ruby具有很大的灵活性,可以应对各种需求和场景。 3. 面向对象编程:Ruby...

    programming+ruby中文版第二版

    《 programming+ruby中文版第二版》 对programming+ruby 中文版的再版。

    元编程 Ruby

    元编程:编写可以编写代码的代码,ruby和rails的技术核心

Global site tag (gtag.js) - Google Analytics