为什么’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 )你会引用给定方法的超级版本。

你不能简单地按名称调用方法,因为多态的工作方式(如何根据对象类确定实际调用哪个方法的版本 )会导致你的方法调用自身,旋转到无限集调用,并导致堆栈溢出。