为什么是“超级”? Ruby 中的关键字而不是方法?
为什么要这样设计呢?
Ruby 的设计倾向于实现尽可能多的方法;关键字通常是为有自己的语法规则的语言特征保留的。然而,super
的外观和行为都类似于方法调用。
(我知道在纯 Ruby 中实现 super
会很麻烦,因为它必须从 caller
或 使用trace_func。仅此一点并不能阻止它成为一种方法,因为大量 Kernel 的方法未在纯 Ruby 中实现。)
In Ruby, super
is a keyword rather than a method.
Why was it designed this way?
Ruby's design tends toward implementing as much as possible as methods; keywords are usually reserved for language features that have their own grammar rules. super
, however, looks and acts like a method call.
(I know it would be cumbersome to implement super
in pure Ruby, since it would have to parse the method name out of caller
, or use a trace_func. This alone wouldn't prevent it from being a method, because plenty of Kernel's methods are not implemented in pure Ruby.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它的行为有点不同,因为如果您不传递参数,则所有当前参数(和块,如果存在)都会传递......我不确定这作为一种方法如何工作。
举一个相当人为的例子:
我不需要处理产量,或将参数传递给
super
。在您特别想要传递不同参数的情况下,它的行为更像是方法调用。如果您不想传递任何参数,则必须传递空括号 (super()
)。它根本没有与方法调用完全相同的行为。
It behaves a little differently, in that if you don't pass arguments, all of the current arguments (and block, if present) are passed along... I'm not sure how that would work as a method.
To give a rather contrived example:
I did not need to handle the yield, or pass the arguments to
super
. In the cases where you specifically want to pass different arguments, then it behaves more like a method call. If you want to pass no arguments at all, you must pass empty parentheses (super()
).It simply doesn't have quite the same behaviour as a method call.
super
不会自动调用父类的方法。如果您将 ruby 类的继承层次想象为一个列表,类位于底部,Object
位于顶部,那么当 ruby 看到super
关键字时,而不是只需检查父类,它就会向上移动整个列表,直到找到第一个具有用该名称定义的方法的项目。我很小心地说“item”,因为它也可能是一个模块。当你将一个模块包含到一个类中时,它会被包装在一个匿名超类中,并放在我之前讨论过的列表中你的类之上,这意味着如果你为你的类定义了一个方法,该方法也在模块中定义,然后从类的实现中调用 super 将调用模块的实现,而不是父类的实现:
而且我不认为可以从 ruby 环境本身访问此“继承列表”,这意味着此功能不会可用(但有用是的;我不太确定这是否是一个预期的功能。)
super
doesn't automatically call the parent class's method. If you imagine the inheritance hierarchy of a ruby class as a list, with the class at the bottom andObject
at the top, when ruby sees the thesuper
keyword, rather than just check the the parent class, it moves up the entire list until it finds the first item that has a method defined with that name.I'm careful to say item because it could also be a module. When you include a module in to a class, it is wrapped in an anonymous superclass and put above your class in the list I talked about before, so that means if you had a method defined for your class that was also defined in the module, then calling super from the class's implementation would call the module's implementation, and not the parent class's:
And I don't believe that it is possible to access this 'inheritance list' from the ruby environment itself, which would mean this functionality would not be available (However useful it is; I'm not every sure if this was an intended feature.)
嗯,好问题。我不确定您还会如何引用给定方法的超级版本(除了使用
super
之外)。您不能简单地按名称调用该方法,因为多态性的工作方式(它如何根据对象类确定实际调用该方法的哪个版本)会导致您的方法调用本身,旋转成无限的调用集,并导致堆栈溢出。
Hm, good qustion. I'm not sure how else (besides using
super
) you would you reference the super version of a given method.You can't simply call the method by name, because the way that polymorphism works (how it figures out which version of that method to actually call, based on the object class) would cause your method to call itself, spinning into an infinite set of calls, and resulting in a stack overflow.