为什么’super’是关键字而不是Ruby中的方法?
在Ruby中, super
是关键字而不是方法。
为什么这样设计?
Ruby的设计倾向于尽可能多地实现方法; 关键字通常保留用于具有自己的语法规则的语言function。 然而, super
看起来像一个方法调用。
(我知道在纯Ruby中实现super
会很麻烦,因为它必须从caller
解析出方法名,或者使用trace_func 。仅此一项不会阻止它成为一种方法,因为内核很多方法没有在纯Ruby中实现。)
它的行为有点不同,因为如果你不传递参数,所有当前的参数(和块,如果存在的话)都会被传递……我不确定它将如何作为一种方法。
给出一个相当人为的例子:
class A def example(a, b, c) yield whatever(a, b) + c end end class B < A def example(a, b, c) super * 2 end end
我不需要处理yield,也不需要将参数传递给super
。 在您特别想要传递不同参数的情况下,它的行为更像是方法调用。 如果您想要根本不传递任何参数,则必须传递空括号( super()
)。
它与方法调用的行为完全不同。
super
不会自动调用父类的方法。 如果您将ruby类的inheritance层次结构想象为列表,底层的类和顶部的Object
,当ruby看到super
关键字时,而不是仅检查父类,它会向上移动整个列表,直到它找到第一个具有使用该名称定义的方法的项目。
我小心说项目因为它也可能是一个模块 。 当你将一个模块包含在一个类中时,它被包装在一个匿名的超类中,并放在我之前讨论的列表中的类之上,这意味着如果你有一个为你的类定义的方法,也是在模块中定义的,然后从类的实现中调用super将调用模块的实现,而不是父类的调用:
class Foo def f puts "Foo" end end module Bar def f puts "Bar" super end end class Foobar < Foo include Bar def f puts "Foobar" super end end foobar = Foobar.new foobar.f # => # Foobar # Bar # Foo
而且我不相信可以从ruby环境本身访问这个“inheritance列表”,这意味着这个function将无法使用(但它很有用;我不确定这是否是一个预期的function。)
嗯,好脾气。 我不确定如何(除了使用super
)你会引用给定方法的超级版本。
你不能简单地按名称调用方法,因为多态的工作方式(如何根据对象类确定实际调用哪个方法的版本 )会导致你的方法调用自身,旋转到无限集调用,并导致堆栈溢出。