在 Ruby 中,Object 是所有类的超类 (Superclass) , "Class"是所有对象的类 (class) 。即,对任何类取有限次 superclass ,最后都能得到 Object (其实是 BasicObject); 对任何的对象 (类也是一种对象) 取有限次 class 最后都能得到 Class。
相对于其他的编程语言,Ruby 这里存在一个比较绕的逻辑,这里先画出基本的关系图如下:
由于对象与类之间特殊的关系,那么在方法的角度来分析,能得出什么样好玩的结论呢?
1. Object 中的类方法 (methods) 与 Class 中的实例方法 (instance_methods) 相同
Object.methods == Class.instance_methods
# => true
2. Class 中的实例方法 (instance_methods) 一部分继承于 Object 的实例方法 (instance_methods), 另一部分应该 Mixin 于独立的 模块。
Object.instance_methods.length
# => 56
(Class.instance_methods-Object.instance_methods).length
# => 44
3. Class 中的类方法 (methods) 主要继承于 Object 的类方法 (methods)
Class.methods-(Object.methods&Class.methods)
# => [:nesting]
从输出的结果来看,Class 的类方法主要继承与 Object, 但是在此之外添加了一个 :nesting 方法。
4. [基于前两个结论]Class 中的类方法与实例方法具有很高的重合性
Class.methods-(Object.methods&Class.instance_methods)
# => [:nesting]
根据个人的理解,Ruby 的元编程能力的最本质表现,是 Ruby 可以像对待对象 (Object) 那样动态地对类 (Class) 进行运行时编辑。在代码层面的表达,则是 类 (Class) 能够同时进行两次 new ("Class#new"和"Class#new#new") 分别创建 类 和 对象 .
根据上面的结论,可以认为 Ruby 在设计之初主要问题之一便是统一 对象 (Object) 与 类 (Class) 之间的关系。而为了赋予 Ruby 元编程的能力,设计上无法避免 对象 和 类 在方法定义上的冗余问题 (比如一些方法同时是 Class 的类函数和实例函数 ), 为了解决这个问题,就自然而然地引入了 模块 (module) 的概念。
在 Ruby 中,最简单的方法调询路径,是当某个对象调用某个方法时,Ruby 会首先到对象所对应的类中查找是否有这个方法。但是因为继承以及混入 (mixin) 的存在,Ruby 中存在更为复杂的方法调询路径。
与 Java 等语言类似,为了调用方法,Ruby 会首先查找对象的类,然后依次查找类的超类 (superclass) ,直到找到这个方法为止(当然如果已经找到了 Object 还找不到一般就会报错了)。比如下面的代码:
class MyClass:
def my_method;
'my_mythod()'
end
end
class MySubclass < MyClass
end
obj = MySubclass.new
obj.my_method() # => "my_method()"