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

示例:

class Candy
    def land
        homer
    end
end

def homer
    puts "Hello"
end

Candy.new.land #Outputs Hello
有帮助吗?

解决方案

“本垒打”的定义。方法是将方法添加到Object类。它没有定义自由函数。

类Candy隐式继承自Object,因此可以访问Object中的方法。当你打电话给“本垒打”时在“土地”中方法,方法解析无法在当前类中找到定义,转到超类,找到已添加到Object的方法,并调用它。

其他提示

找出发生的事情的简单方法

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

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

  2. Candy有没有叫做本垒打的方法?

    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"]

  6. Candy在其查找链中具有Object,该查找链又具有私有实例方法“homer”。所以方法解析成功

    def语句始终定义类中的方法 self 在定义点

    1. 在定义本垒打之前, self 是什么?

      p self#=>主要   def本垒打     把“你好”   结束

    2. 那它的类型是什么?

      p self.class#=>对象

    3. 这就是为什么 homer 最终在对象上

从技术上讲, homer 方法的定义实际上是 Kernel 模块,它被混合到 Object 中,而不是<代码>对象直接。因此,当 homer 不是局部变量或在 Candy 上定义的实例方法时,Ruby方法继承链将通过 Object 进行跟进,然后到混合的 Kernel 模块,然后运行此代码。

编辑:抱歉,我不知道为什么我这么想。看来该方法确实存在于 Object 上。不确定它在实践中是否有太大差异,但我应该在发布之前确认一些事情。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top