对象:一些[内部]变量,一些方法以及特殊引用[super]
class A
def hello = "hello"
def to_s = "A"
end
p A.class # Class; 定义的类 A 是对象,是 Class 的实例
p A.instance_of? Class # true; A 作为 Class 实例就有 Class#superclass 方法可调用
p Class.instance_of? Class # true; Class 作为类,同时也是 Class 的实例; 类 Module/Object/BasicObject 同样如此
p Class.superclass # Module; Module 是 Class 的父类,那么 A 就有 Module#ancestors 方法可用
p Module.superclass # Object; Object 是 Module 的父类,那么 A 就有 Object#to_s 方法可用
p Object.superclass # BasicObject; BasicObject 是 Object 的父类,那么 A 就有 BasicObject#__id__ 方法可用
p BasicObject.superclass # nil; BasicObject 作为最顶层存在
p A.superclass # Object; 使用关键字 [keyword] class 定义的类 A,默认父类是类 Object
# 方法 ancestors 返回 modules 和 superclass
p A.ancestors # [A, Object, Kernel, BasicObject];
p Object.ancestors # [Object, Kernel, BasicObject];
p Class.ancestors # [Class, Module, Object, Kernel, BasicObject];
a = A.new
p a.to_s # "A"
def a.bye = 'bye' # 向 singleton_class 上添加 #bye 方法
# case
# a.hello -> a[receiver] -> A#hello
# a.bye -> a[receiver] -> a.singleton_method(:bye).call
Class
- 以代码
class A end; a = A.new
举例,A 是一个对象,即有对应的类[Class],用 A.class 查看;再 A 有.new
方法调用,即存在 Class#new 方法 - 支持以静态方法 Class::new定义类,形式如:
Class new (superclass) { ... }
- Class#superclass, Class#subclasses, Class#inherited
继承关系
Class.superclass == Module
;在 class Module 上定义有关类相关的属性/方法Module.superclass == Object
;Ruby 里一切都是对象来源 - class ObjectObject.superclass == BasicObject
;基础的方法#__id__, #__send__, #method_missing
BasicObject.superclass == nil
object
singleton_class
- 需要时才会存在
- obj 的 singleton_class方法返回 Class 类的实例化对象[匿名 class] code
class A end # 定义类 a = A.new # 实例化 # singleton_class 是实时根据需要补齐的 - Class.new 得到类 # 在 singleton_class 上添加方法 def a.hello = 'hello' p a.hello # hello an = a.singleton_class # 获取类 p an.instance_methods false # 打印类的方法。[:hello]
- 匿名类会绑定[attach]到 obj 上,即
A.singleton_class.attached_object == A
- nil, true, false 对应的 singleton_class 是 NilClass, TrueClass, FalseClass; 但它们不是 singleton_class, 可以用
true.singleton_class.singleton_class?
判定 - 而 an Integer, a Float or a Symbol 没有 singleton_class,即
1.singleton_class
异常。ps:x = 3; y = 3
这里 x, y 是完成一样的,即x.object_id == y.object_id
self[scope]
- 当前对象[contxt][binding]
- toplevel
self.to_s # main
- 在类定义期间,当前对象[self]就是当前类 code
Variable
- local name
- global $name
- class @@name 类/子类共享
- instance @name 子类可覆盖 What is a class instance variable?
- constant @NAME
存在几种 scope 定义
- the toplevel(main),
- a class(or module) definition,
- a method definition
- block
{ ... }
或do ... end
; 使用新定义的变量,在外部不可见;与外部已定义的变量重名时,直接使用外部变量 ps: Kernel#loop 是个方法
怎么知道方法在什么类上
先向右[self]再向上查找[class, …ancestors]
- Class 实现
- #new, #allocate, #superclass, #subclasses
- #attached_object [singleton_class]
- #inherited
- BasicObject 实现基础方法,以便子类 inherit
- #new
- #__id__, #__send__
- #method_missing
- #instance_exec, #instance_eval 使用 self 执行 block?! - Ref
- #singleton_method_added, #singleton_method_removed, #singleton_method_undefined
- Object
- #instance_of?, #kind_of?, #is_a? code
- #methods, #public_methods, #private_methods, #protected_methods
- #method, #public_method
- #define_singleton_method
- #instance_variables, #instance_variable_get, #instance_variable_set, #instance_variable_defined?, #remove_instance_variable
- #singleton_class, #singleton_method, #singleton_methods
- #respond_to?, #respond_to_missing?
- #send, #public_send
- #extend[向 singleton_class 上 mixin Module]
- Kernel
- #class
- Module
- #ancestors
- #alias_method
- #attr_accessor, #attr_reader, #attr_writer, #attr
- #private, #protected, #public
- #extend_object[实现], #extended[回调] - code
- #prepend, #prepend_features[实现], #prepended[回调], #include, #append_features[实现], #included[回调], #include?, #included_modules code
- #module_function
- #class_exec/#module_exec, #class_eval/#module_eval, #method_exec, #method_eval
- #define_method, #undefine_method, #remove_method, #method_added, #method_removed, #method_undefined, #method_defined?, #public_method_defined?, #protected_method_defined?, #private_method_defined?
- #class_variables, #class_variable_defined?, #class_variable_get, #class_variable_set, #remove_class_variable
- #instance_method, #instance_methods, #public_instance_method, #public_instance_methods, #private_instance_methods, #protected_instance_methods, #undefined_instance_methods
- #constants, #public_constant, #private_contant, #const_get, #const_set, #remove_const, #deprecate_constant, #const_defined?, #const_added, #const_missing
- #autoload, #autoload?
- #singleton_class?
- #refine, #refinements, #using - 防止冲突
include
module T
def hello = 1
end
class D
include T
end
D.new.hello # 1
- 创建 proxy_class 且设置 supperclass 为 D.superclass; 再把 D.superclass 设置为 proxy_class
- 当遇到 method 查找到 proxy_class 上时,直接到 T 上查找即可 - T 是独立存在的,如果中间有修改就可以做到实时生效
- 当 T 本身存在 include 时,会生成 proxy_class chain
prepend
- 有顺序问题,但与 include 类似
- 再创建一个 class,把 D 的 method 移过去,把 proxy_class 插在两者中间
extend code
module Foo; @@foo = 'foo'; end
class Bar; extend Foo; end
p Bar.class_variables
p Bar.singleton_class.class_variables
p Bar.singleton_class.singleton_class.class_variables
p Bar.singleton_class.singleton_class.class_variable_get(:@@foo)
- 创建 Bar.singleton_class 类
- 在 Bar.singleton_class 中 include Foo
constant 查找过程
Module.nesting
Module.nesting.first
为空的话,从 Object 开始找Module.nesting.first.ancestors
上查找class.class_eval { block; p Module.nesting }
使用 block 所在的 class/module 上class.class_eval("p Module.nesting")
会把 class 放到 Module.nesting.first 上
Struct
- Struct 简化 class 定义
- OpenStruct