So erstellen Sie Module, die method_missing in Ruby enthalten

8

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:

%Vor%

Während ObjectC.new.goodbye_aaa korrekt funktioniert, verhält sich ObjectC.new.hello_a seltsam:

%Vor%

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?

    
David Miani 16.06.2011, 02:28
quelle

2 Antworten

5

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?

    
coreyward 16.06.2011, 02:33
quelle
1

Ссылка

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

    
ChrisPhoenix 10.12.2013 17:53
quelle

Tags und Links