zoukankan      html  css  js  c++  java
  • 3-8《Ruby元编程》第二章对象模型

    《Ruby元编程》


    第二章 对象模型

    类定义揭秘inside class definitions: class关键字更像一个作用域操作符,核心作用是可以在里面随时定义方法。

    [].methods.grep(/^re/):调用 出Array的所有以re开头的method.

     

    Monkeypatch:涉及全局修改,定义某个方法前应该仔细检查该类是否已有同名的方法。 

    实例对象存放在对象中,方法存放在类中。

    类的真相:类本身也是对象。Ruby允许在运行时修改类的信息。

     Class.instance_methods

     Array.superclass  =>Object

    模块 

    类也是模块,是带有三个方法new,allocate,superclass的增强模块。

    代码要include,使用module.代码需要被实例化或被继承用class.

    就是一个对象外加一组实例方法和一个对其超类的引用。 类和其他对象一样必须通过引用来访问。 

     

    常量,任何以大写字母开头的引用(包括类名和模块名)。常量和变量的区别是作用域不一样。常量的作用域类似于文件系统中的文件,在不同目录下,不同的文件可以有相同的名字。

    常量的路径:用::双冒号进行分隔。

    Module.nesting方法:返回当前代码的路径

    module M

      class C

        module M2

          Module.nesting  #=>[M::C::M2, M::C, M]

        end

      end

    end

    Ruby常量,可以用module来存放常量,这样不同的类库的类名就不会产生冲突。

    如Rake是流行的Ruby构建版本。gems/rake-1.0/lib/rake/task.rb

    module Rake

      class Task

      #...

    这里Task类的全名就变成 Rake::Task .  不会再和其他类库的类名冲突了。 

    命名空间Namespace : 只充当常量容器的模块。

    2.4What Happends when you call a method?

    1. 查找方法。Method lookup(原则:object找到所在类,再顺着祖先链查找方法). receiver和ancestors-chain 
    2. 执行这个方法。self 


    include:把模块插到祖先链中包含它的该类的后面。先查找该类的method。

    prepend: 把模块插到祖先链中包含它的该类的前面。先在prepend 模块中查找method。

    module Printable
      def print
        puts "sxx"
      end
      def prepare_cover
      end
    end
    module Document
      def print_to_screen
        prepare_cover
        print
      end
      def print
        puts "123"
      end
    end
    class Book
      include Printable
      include Document
      p ancestors    #=> [Book, Document, Printable, Object, Kernel, BasicObject]
    end
    b = Book.new
    b.print_to_screen  #=>123

    kernel是核心模块被Object包含了。通过给Kernel模块加一个方法,就对所有对象可用了。这个方法称作内核方法.如Awesome_print包的方法ap就用了内核方法。

    Method Execution

    Ruby的每一行代码都会在一个对象中被执行--这个对象就是当前对象,self 

    没有明确指定receiver的method都在self上调用。

    Private私有方法

    1.如果调用方法的接收者不是自己,就必须指明接受者

    2.私有方法只能通过隐性的接受者self调用。 

    3 所以只能在自身中调用私有方法,或者继承来的私有方法。--私有规则

    顶层上下文top level context 

    如果没有调用任何方法,self是Ruby提供的叫main的对象(也称为top level context)main.class #=> Object

    在类和模块定义中,self是这个类或模块本身。

    Refinement 细化:

    技巧用途:使修改kernal里的类的方法只在局部代码中有效,不会影响其他代码,防止猴子补丁。

    Module#refine,Refine mod in the receiver.Returns a module, where refined methods are defined.

    Module#using:Import class refinements from module into the current class or module definition.

    1. 首先,定义一个模块
    2. 然后,在这个模块的定义中调用refine方法。
    3. 在另一个模块内部,使用Module#using方法,细化的作用范围就限定在该模块内部了。或者在文件main中调用using,在文件结束前生效。
    module StringExtensions
      refine String do
        def reverse
          "自定义的反转"
        end
      end
    end
    module StringStuff
      using StringExtensions
      p"my_string".reverse
    end
    p "my_string".reverse
  • 相关阅读:
    VC内存泄露检查工具:Visual Leak Detector
    ArcGIS Server 开发系列(五)自定义 Toolbar 工具2 (转载于Flyingis)
    Arcgis Server系列 安装与配置
    ArcGIS Server 开发系列(四)ArcGIS Server data sources 开发 (转载于Flyingis)
    ArcGIS Server 开发系列(五)自定义 Toolbar 工具 (转载于Flyingis)
    ArcMap的地图缓存MapCache
    C# 字符串 合并时 + 和 stringbulilder 的区别是什么?
    ArcGIS Server 体系结构
    ArcGIS Server 开发系列(三)漫游 Graphics data sources (转载于Flyingis)
    ArcGIS Server .Net Web ADF体系结构
  • 原文地址:https://www.cnblogs.com/chentianwei/p/8531089.html
Copyright © 2011-2022 走看看