2010-12-29 15 views
15

Ist es möglich, etwas wie super.super in der Overriven-Methode zu tun? Das heißt, die Supergroßmutter des direkten Elternteils zu umgehen und "Großeltern" -Super zu nennen?Aufruf Super-Super-Methode

+0

... Ich kann mir nicht helfen, aber diese Frage ist in der Tat ein Lied von [They Might Be Giants] (http://en.wikipedia.org/wiki/They_Might_Be_Giants) ... Oo .. .Es tut uns leid. –

+7

Also im Grunde willst du eine 'superduper' Methode? :) –

Antwort

19

Dies ist nicht empfehlenswert, aber was Sie wollen, ist möglich wie folgt aus:

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

Dies funktioniert, indem zuerst die Großeltern Klasse bekommen, dann instance_method forderte sie auf, eine UnboundMethod zu bekommen als Vertreter der Großeltern-Version the_method. Anschließend ruft es die Methoden UnboundMethod#bind und Method#call auf, um die Methode des Großelternteils für das aktuelle Objekt aufzurufen.

-1

In Anbetracht dessen ist eines der Prinzipien der OOP (Kapselung) zu brechen, ich hoffe sehr, dass es nicht möglich ist. Selbst wenn Sie dies versuchen, spricht dies von einem Problem mit Ihrem Design.

+0

Stimmt, ich war nur neugierig, da alles in Ruby möglich scheint. – Vincent

+1

Es tut mir leid, aber haben Sie schon von Erbdiamanten gehört? So können sie in Ruby aufgelöst werden. Also lass uns keine Erbschaftsdiamanten machen, oder lass uns Ruby ändern, um sie unterzubringen, könnte man sagen. Ich werde nicht streiten. Was du sagst, könnte in der idealen Welt halten. Aber in der realen Welt arbeiten Sie mit dem Code von schlechten Programmierern, den Sie miteinander verbinden müssen, ohne das Recht zu haben, ihn zu modifizieren. Und dafür sind diese Schraubendreher da. –

0

Sie könnten die Argumente der Methode ändern, um eine Art von optionalen 'pass to parent' Parameter zu erlauben. Suchen Sie in der Superklasse Ihres Kindes nach diesem Parameter, und wenn dies der Fall ist, rufen Sie super von dieser Methode auf und geben Sie zurück, andernfalls können Sie die Ausführung fortsetzen.

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 

sonst bin ich mit @Femaref, nur b/c etwas möglich ist, bedeutet nicht, es ist eine gute Idee. Überdenken Sie Ihr Design, wenn Sie dies für notwendig halten.