Ruby中的方法访问

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

例:

class Candy def land homer end end def homer puts "Hello" end Candy.new.land #Outputs Hello 

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

Candy类隐式inheritance自Object,因此可以访问Object中的方法。 当您在“land”方法中调用“homer”时,方法解析无法在当前类中找到定义,转到超类,找到已添加到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有一个叫做“本垒打”的方法吗? p Object.instance_methods(false).grep(“homer”)#=> []

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

Candy在其查找链中有Object,而后者又有一个私有实例方法“homer”,因此方法解析成功

def语句总是定义类中的方法,无论self在定义点是什么

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

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

  2. 那它的类型是什么?

    p self.class#=> Object

这就是为什么本垒打最终会成为对象的原因

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

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

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