如果我的课程Salad
包含方法chew
并且我在其中使用super
,则会调用下一个可用的chew
方法。祖先。如果我想“达到两个级别”(到第二个可用的chew
方法上升链接怎么办?)如果不将super
添加到第一个祖先的方法中,有没有办法做到这一点?
为了使这更具体一点,假设这是我的Salad
类,带有salad
对象:
class Salad < Food
include Almonds
include Gorgonzola
include Spinach
include Dressing
def chew
super
end
end
salad = Salad.new
祖先的阵列是这样的:
[Salad, Dressing, Spinach, Gorgonzola, Almonds, Food, Object, Kernel, BasicObject]
如果我希望salad.chew
在chew
中触发Spinach
方法而不将super
添加到Dressing #chew,那可能吗?有没有办法达到两级(与super
“达到”一级上升的方式相同)?
答案 0 :(得分:4)
是的,有一种方法可以执行您所描述的内容,这种方式是通过方法#method
和#instance_method
,就像在method = Spinach.instance_method( :chew )
中一样,您可以将其绑定到Salad,或者像沙拉实例的元类,如method.bind( Salad )
。此机制不如使用便捷关键字super
那样整洁,但提供了super
功能的超集。还有一些细节,但相信我,这样,你可以做任何你想做的事情。这就是Ruby的力量 - 你可以做任何事情,直到Lispiest魔法,你需要Ripper
,和(迄今为止未完成的)Sorcerer
。
(有关用法示例,请参阅Using the Object.inspect / Object.to_s on a class derived from Hash上的其他答案)
答案 1 :(得分:1)
不,没有办法做你所描述的(并且有充分的理由)。您描述的任何“超级超级”关键字的使用都会与您的继承链的细节紧密耦合(以及该链中的哪些类/模块实现给定的方法)。它会非常脆弱;如果这样的关键字存在,并且你使用它,那么移动方法定义这样的小改动就很容易破坏。对于您的代码的读者来说,这也会非常混乱。
super
关键字的目的是:您可以创建一个类,将其子类化,覆盖一个方法,并向该方法添加一些新行为,同时仍然执行该方法最初执行的所有操作。 super
有效地说:“现在执行此方法的默认行为”。无论是否在超类,超类,模块或其他任何地方定义了“默认”行为,这都可行。
答案 2 :(得分:1)
如果您想知道如何在所有模块上调用chew
方法,那么有一个更好的解决方案是使用合成。模块用于行为,如果你考虑你的Salad类,你不希望它的行为像菠菜或杏仁,你希望它由它们组成。所以当你chew
给你一个沙拉时chew
。