9

Ruby 是如何隐式地允许类外部的类访问方法的?

例子:

class Candy
    def land
        homer
    end
end

def homer
    puts "Hello"
end

Candy.new.land #Outputs Hello
4

4 回答 4

24

“homer”方法的定义是将方法添加到 Object 类中。它没有定义自由功能。

Candy 类隐式继承自 Object,因此可以访问 Object 中的方法。当你在“land”方法中调用“homer”时,方法解析在当前类中找不到定义,去超类,找到你添加到Object的方法,并调用它。

于 2008-10-01T06:08:02.923 回答
5

一个简单的方法来找出发生了什么

  1. 搜索哪些类/模块来解析 Candy 对象中使用的方法?

    p Candy.ancestors #=> [糖果、对象、内核]

  2. Candy 有叫做 homer 的方法吗?

    p Candy.instance_methods(false).grep("homer") #=> []

    p Candy.private_instance_methods(false).grep("homer") #=> []

  3. OK Candy 没有任何名为“homer”的方法。

  4. 查找链中的下一步是什么(参见 1)=>“对象”

  5. Object 是否有一个名为“homer”的方法?p Object.instance_methods(false).grep("homer") #=> []

    p Object.private_instance_methods(false).grep("homer") #=> ["homer"]

Candy 在其查找链中有对象,而对象又具有私有实例方法“homer”,因此方法解析成功

def 语句总是在定义点定义 self 的类中的方法

  1. 定义 homer 之前的self是什么?

    p self #=> main def homer 将“Hello”结束

  2. 那么它的类型是什么?

    p self.class #=> 对象

这就是为什么本垒打最终出现在Object上的原因

于 2008-10-02T22:16:49.513 回答
4

从技术上讲,homer方法的定义实际上是在Kernel混入的模块上Object,而不是Object直接在模块上。所以当homer不是定义在 上的局部变量或实例方法时Candy,Ruby 方法继承链会跟进Object,然后到混入Kernel模块,然后运行这段代码。

编辑:对不起,我不知道我为什么这么想。看来该方法确实存在Object。不确定它在实践中是否有太大的不同,但我应该在发布之前确认一下。

于 2008-10-02T06:38:59.877 回答
0

Ruby 没有自由浮动函数。每个方法都属于某个对象。您def在顶层的方法实际上正在成为 class 的实例方法Object。因为一切都Object在某种程度上,所有对象都可以访问Object的实例方法。

于 2011-11-27T15:45:16.773 回答