题
Ruby如何隐式地允许类外部的类访问方法?
示例:
class Candy
def land
homer
end
end
def homer
puts "Hello"
end
Candy.new.land #Outputs Hello
解决方案
“本垒打”的定义。方法是将方法添加到Object类。它没有定义自由函数。
类Candy隐式继承自Object,因此可以访问Object中的方法。当你打电话给“本垒打”时在“土地”中方法,方法解析无法在当前类中找到定义,转到超类,找到已添加到Object的方法,并调用它。
其他提示
找出发生的事情的简单方法
-
搜索哪些类/模块来解析Candy对象中使用的方法?
p Candy.ancestors#=> [糖果,对象,内核]
-
Candy有没有叫做本垒打的方法?
p Candy.instance_methods(false).grep(" homer")#=> []
p Candy.private_instance_methods(false).grep(" homer")#=> []
-
OK Candy没有任何名为'homer'的方法。
-
查找链中的下一步(参见1)=> "对象"
-
Object是否有一个名为“homer”的方法。 ? p Object.instance_methods(false).grep(" homer")#=> []
p Object.private_instance_methods(false).grep(" homer")#=> [" homer"]
醇>
-
在定义本垒打之前, self 是什么?
p self#=>主要 def本垒打 把“你好” 结束
-
那它的类型是什么?
p self.class#=>对象
醇>
Candy在其查找链中具有Object,该查找链又具有私有实例方法“homer”。所以方法解析成功
def语句始终定义类中的方法 self 在定义点
这就是为什么 homer 最终在对象上
从技术上讲, homer
方法的定义实际上是 Kernel
模块,它被混合到 Object
中,而不是<代码>对象直接。因此,当 homer
不是局部变量或在 Candy
上定义的实例方法时,Ruby方法继承链将通过 Object
进行跟进,然后到混合的 Kernel
模块,然后运行此代码。
编辑:抱歉,我不知道为什么我这么想。看来该方法确实存在于 Object
上。不确定它在实践中是否有太大差异,但我应该在发布之前确认一些事情。
Ruby没有自由浮动函数。每个方法都属于某个对象。您在顶层 def
的方法实际上正在成为类 Object
的实例方法。因为在某种程度上所有对象都是 Object
,所有对象都可以访问 Object
的实例方法。