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的方法,并调用它。
找出发生的事情的简单方法
-
搜索哪些类/模块来解析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有一个叫做“本垒打”的方法吗? p Object.instance_methods(false).grep(“homer”)#=> []
p Object.private_instance_methods(false).grep(“homer”)#=> [“homer”]
Candy在其查找链中有Object,而后者又有一个私有实例方法“homer”,因此方法解析成功
def语句总是定义类中的方法,无论self在定义点是什么
-
在定义本垒打之前, 自我是什么?
p self#=> main def homer将“Hello”结束
-
那它的类型是什么?
p self.class#=> Object
这就是为什么本垒打最终会成为对象的原因
从技术上讲, homer
方法的定义实际上是在Kernel
模块上,它被混合到Object
,而不是直接在Object
。因此,当 homer
不是局部变量或在Candy
定义的实例方法时,Ruby方法inheritance链通过Object
跟进,然后到混合Kernel
模块,然后运行此代码。
编辑:对不起,我不知道为什么我这么想。 看来该方法确实存在于Object
。 不确定它在实践中是否有太大差异,但我应该在发布之前确认一些事情。
Ruby没有自由浮动函数。 每个方法都属于某个对象。 您在顶层定义的方法实际上正在成为类Object
实例方法。 因为在某种程度上所有对象都是Object
,所以所有对象都可以访问Object
的实例方法。