2010-12-29 9 views
15

オーバーライドされたメソッドでsuper.superのようなことができますか?つまり、直接親のスーパーをバイパスし、 "祖父母"のスーパーと呼ぶのですか?スーパーのスーパーメソッドを呼び出す

+0

...私はこの質問が実際には[They Might Be Giants](http://en.wikipedia.org/wiki/They_Might_Be_Giants)の曲だとは思えません。 。ごめんなさい。 –

+7

だから、基本的にあなたは「スーパーデファー」の方法を望んでいますか? :) –

答えて

19

これはお勧めしますが、何をたいことは、このようなことができありません。

grandparent = self.class.superclass.superclass 
meth = grandparent.instance_method(:the_method) 
meth.bind(self).call 

これは最初の祖父母のバージョンを表すUnboundMethodを得るためにそれにinstance_methodを呼び出し、その後、祖父母のクラスを取得することにより動作しますthe_method。次に、UnboundMethod#bindMethod#callを使用して、現在のオブジェクトで祖父母のメソッドを呼び出します。

-1

これがOOP(カプセル化)の原則の1つを破っていることを考えれば、私は心からそれができないことを願っています。これをやろうとした場合でも、あなたのデザインに問題があると言えます。

+0

本当に、私はすべてがRubyで可能なように思っていただけに興味がありました。 – Vincent

+1

申し訳ありませんが、相続ダイヤモンドについて聞いたことがありますか?これがRubyで解決できる方法です。だから、継承のダイヤモンドを作ってはいけません。それとも、Rubyを変えてみましょう。私は議論しません。あなたが言うことは、理想的な世界に定着するかもしれません。しかし現実の世界では、悪いプログラマによって書かれたコードを使って作業しています。コードを修正する権利を持たずに接続する必要があります。そして、これはこれらのドライバーのためのものです。 –

0

あなたは、ある種のオプションの「親に渡す」パラメータを許可するようにメソッドの引数を変更することができます。あなたの子のスーパークラスでこのパラメータをチェックし、もしそうなら、そのメソッドからsuperを呼び出して、それ以外の場合は実行を続行します。

class Grandparent; def method_name(opts={}); puts "Grandparent called."; end; end 
class Parent < Grandparent 
def method_name(opts={}) 
    return super if opts[:grandparent] 
    # do stuff otherwise... 
    puts "Parent called." 
end 
end 
class Child < Parent 
def method_name(opts={}) 
    super(:grandparent=>true) 
end 
end 

ruby-1.9.2-p0 > Child.new.method_name 
Grandparent called. 
    => nil 

そうでなければ、私は@Femarefに同意します。何かが可能なのは、それが良い考えであるとは限りません。必要と思われる場合は、デザインを再検討してください。

関連する問題