元编程不过是编程——经典必读
作用域(绑定)
改变作用域的关键字, 分别是module,class和def。我们称为作用域的门(scope gate)
instance_eval以实例作用域执行代码
class_eval以类定义作用域执行代码
Kernel#eval方法,当前上下文中直接执行代码字符串
instance_eval | class_eval | |
---|---|---|
对象 | 单例方法 | -- |
类名(元类对象) | 类方法 | 实例方法 |
表格是不精准、不完备
的表达,instance_eval、class_eval使用时需要注意区分调用对象
打破作用域门的方式
- 类定义使用 Class.new 替换
- 模块定义使用 Module.new 替换
- 方法定义使用 define_method 替换
对象模型图
七条规则
- 只有一种对象——要么是普通对象,要么是模块
- 只有一种模块——可以是一个普通模块、一个类或者一个单件类
- 只有一种方法,它存在于一个模块中——通常是在一个类中
- 每个对象(包括类)都有自己的“真正的类”——要么是一个普通类,要么是一个单件类
- 除了BasicObject类没有超类外,每个类有且只有一个祖先——要么是一个类,要么是一个模块。这意味着任何类只有一条向上的、直到BasicObject的祖先链。
- 一个
对象
的单件类的超类是这个对象的类
;一个类
的单件类的超类是这个类的超类的单件类
; - 调用一个方法时,Ruby先向右迈一步,进入接收者真正的类,然后向上进入祖先链。这就是Ruby查找方法的方式
法术手册
- 环绕别名:加一层包装,A => A-B-_A
- 白板类:移除一个类的所有方法,以便把它们转换为幽灵方法
- 类扩展:通过向类的单件类中加入模块定义类方法,是对象扩展的一个特例
- 类实例变量:Class对象的实例中存储类级别的状态
- 类宏:在类定义中使用方法
- 洁净室:使用一个对象作为执行一个代码块的环境Cleanroom.new.instance_eval{fun()}
- 代码处理器:处理从外部获得的代码字符串
- 上下文探针:执行一个代码块来获取一个对象上下文中的信息
- 延迟执行:在proc和lambda中存储一段代码及其上下文,用于以后执行
- 动态派发:在运行时决定调用哪个方法
- 动态方法:在运行时决定怎样定义一个方法
- 动态代理:把不能对应某个方法名的消息转发给另外一个对象
- 扁平作用域:
- 幽灵方法:响应一个没有关联方法的消息
- 钩子方法:覆写一个方法来截获对象模型事件
- 内核方法:在Kernel模块中定义一个方法,使得所有对象都可使用
- 惰性实例变量:等第一次访问时才进行初始化@a ||= "str"
- 拟态方法:把一个方法伪装成另外一个语言构件
- 猴子补丁:修改已有类的特性
- 命名空间:在一个模块中定义常量,以防止命名冲突
- 空指针保护:x=nil;y = x || ‘str‘
- 对象扩展:通过给一个对象的单件类混入模块来定义单件方法
- 打开类:修改已有的类
- 下包含包装器:调用一个用prepend方式覆写的方法
- 细化:refine为类打补丁,作用范围仅到文件结束或模块作用域
- 细化封装器:在细化中调用非细化的方法
- 沙盒:$SAFE在一个安全环境中执行未授信代码
- 作用域门:class、def、module
- Self Yield:把self传给当前代码块
- 共享作用域:在同一个扁平作用域的多个上下文中共享变量
- 单件方法:在一个对象上定义一个方法
- 代码字符串:
- 符号到Proc:把一个调用单个方法的块转换为一个符号
时间: 2024-12-09 02:53:44