《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  #=>

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

最新文章

  1. 报错注入分析之(count()、rand()、group by)分析,被大佬称为floor报错注入
  2. 《Linux内核设计与实现》课本第十八章自学笔记——20135203齐岳
  3. oneCMDB
  4. python4delphi 安装
  5. 关于jquery插件 入门
  6. 阿里云利用web直传文件到oss服务器
  7. linux杂记(六)档案权限
  8. JavaScript 奇技淫巧
  9. Android Studio上修改项目(module)的包名(Package Name)
  10. Linux常用命令(第二版) --帮助命令
  11. C++11中map的用法
  12. sql取指定时间段内的所有月份
  13. OpenCV3如何使用SIFT和SURF Where did SIFT and SURF go in OpenCV 3?
  14. java基础系列--volatile关键字
  15. Java多线程学习(三)---线程的生命周期
  16. 企业网管用linux搭建邮件服务器为公司降本增效
  17. mysql问题处理记录
  18. pyqt4_应用例子(计算器,对话框,进度条,日历等等)
  19. 【[SDOI2009]Bill的挑战】
  20. 《Drools7.0.0.Final规则引擎教程》Springboot+规则重新加载

热门文章

  1. linux编程之pipe()函数
  2. VS2012快捷键突然不能用怎么办
  3. Python 面向对象教程
  4. python中repr和eval可以用来在数据结构和字符串间互转
  5. php json_decode() 如果想要强制生成PHP关联数组,json_decode()需要加一个参数true
  6. Collection体系
  7. ELK学习笔记之ElasticSearch的索引详解
  8. C++设计模式 之 “对象性能” 模式:Singleton、Flyweight
  9. AP聚类算法
  10. BZOJ 2141 排队(树状数组套treap)