Ich habe ein paar Module, die die Methode missing erweitern:
%Vor% Das alles funktioniert gut, zB ObjectA.new.hello_there
outputs "Hello, hello_there"
. Gleichermaßen gibt ObjectB.new.goodbye_xxx
"Goodbye, xxx"
aus. respond_to?
funktioniert auch, zB ObjectA.new.respond_to? :hello_there
gibt true zurück.
Dies funktioniert jedoch nicht sehr gut, wenn Sie sowohl SaysHello
als auch SaysGoodbye
verwenden möchten:
Während ObjectC.new.goodbye_aaa
korrekt funktioniert, verhält sich ObjectC.new.hello_a
seltsam:
Es wird korrekt ausgegeben und ein Fehler ausgegeben. Auch respond_to?
stimmt nicht korrekt, ObjectC.new.respond_to? :hello_a
gibt false zurück.
Schließlich fügen Sie diese Klasse hinzu:
%Vor% Wirkt auch seltsam. ObjectD.new.lol_zzz
funktioniert, jedoch werfen ObjectD.new.hello_a and ObjectD.new.goodbye_t
beide eine Namensausnahme ab, nachdem sie die richtige Zeichenfolge ausgegeben haben. respond_to?
schlägt auch für Hello und Goodbye-Methoden fehl.
Gibt es eine Möglichkeit, das alles richtig zu machen? Eine Erklärung, wie method_missing
, Module und super
interagieren, wäre auch sehr nützlich.
EDIT: coreyward hat das Problem gelöst, wenn ich in allen von mir definierten Methoden super statt super.<method-name>(args...)
verwende, funktioniert das Programm korrekt. Ich verstehe nicht, warum das so ist, also habe ich eine andere Frage dazu gestellt Was macht super. & Lt; Methodenname & gt; in Rubin tun?
Wenn Sie eine Methode neu definieren, definieren Sie eine Methode neu; Zeitraum.
Was Sie tun, wenn Sie das zweite Modul mit der method_missing
-Methodendefinition einschließen, überschreibt das zuvor definierte method_missing
. Sie können es behalten, indem Sie es aliasieren, bevor Sie es neu definieren, aber Sie möchten vielleicht damit aufpassen.
Außerdem weiß ich nicht, warum Sie super.method_missing
aufrufen. Sobald deine method_missing
-Definition keine Tricks mehr hat, solltest du Ruby wissen lassen, dass es weiter oben in der Kette nach einer Möglichkeit suchen kann, den Aufruf zu verarbeiten, indem du einfach super
aufruft (keine Argumente übergeben oder einen Methodennamen angeben) .
Über Super (Update)
Wenn Sie super
aufrufen, fährt Ruby die Nachschlagekette hoch und sucht nach der nächsten Definition der aufgerufenen Methode. Wenn sie eine findet, ruft sie sie auf und gibt die Antwort zurück. Wenn Sie super.method_missing
aufrufen, rufen Sie die Methode method_missing
für die Antwort auf super()
auf.
Nehmen Sie dieses (etwas alberne) Beispiel:
%Vor% Sie können sehen, dass Super eine Methode ist wie jede andere, es macht nur etwas Magie hinter den Kulissen. Wenn Sie super.class
hier aufrufen, sehen Sie String
, da "Teriyaki" eine Zeichenkette ist.
Machen Sie jetzt Sinn?
Dieser Artikel erklärt genau, wie es funktioniert: Jedes neue Modul überschreibt oder ersetzt keine Methoden - stattdessen werden seine Methoden in die Vererbungskette eingefügt. Deshalb ruft der Aufruf von super von jedem method_missing schließlich alle method_missing auf.
Die Klasse bleibt in der Vererbungskette am niedrigsten, und das zuletzt hinzugefügte Modul ist neben der Klasse.
Also:
%Vor%ergibt Kernel - & gt; A - & gt; B - & gt; Foo
Tags und Links ruby method-missing