Frage

method_missing

* obj.method_missing (Symbol h, args i) → other_obj

  

Ausgeführt von Ruby, wenn obj gesendet wird, ein   Nachricht nicht verarbeiten kann. Symbol   Das Symbol für die Methode aufgerufen, und   args sind alle Argumente, die waren   an sie übergeben. Das folgende Beispiel   erstellt eine Klasse Roman, der antwortet   Verfahren mit den Namen, bestehend aus   römische Ziffern, die Rückkehr   entsprechende ganzzahlige Werte. Eine   typische Verwendung von method_missing ist   implementieren Proxies, delegators und   Forwarder.

class Roman
  def roman_to_int(str)
    # ...
  end
  def method_missing(method_id)
    str = method_id.id2name
    roman_to_int(str)
  end
end
r = Roman.new
r.iv ! 4
r.xxiii ! 23
r.mm ! 2000

Ich habe gerade gehört, über Verfahren fehlenden und ging mehr in , um herauszufinden, Programmierung Rubin , aber die obige Erklärung aus dem Buch zitiert ist über meinen Kopf. Hat jemand eine einfachere Erklärung haben? Genauer gesagt, nur verfahrens fehlt vom Interpreter verwendet wird, oder es besteht immer ein Bedarf es in einem Programm direkt aufrufen (vorausgesetzt, ich Web-Anwendungen nur ich schreibe, im Gegensatz Code für die NASA zu schreiben)?

War es hilfreich?

Lösung

Rubin hat keine Art Durchsetzung und ebenfalls keine Kontrolle macht, was Methoden ein Objekt, wenn das Skript zuerst analysiert wird, da diese dynamisch wie die Anwendung ausgeführt geändert werden.

Was method_missing Fall ist, wird Sie abfangen und behandeln Anrufe Methoden lassen, die für ein bestimmtes Objekt nicht existieren. Dies stellt die unter der Motorhaube treibende Kraft hinter so ziemlich jedes DSL (domänenspezifische Sprache) geschrieben in Ruby.

Im Fall des Beispiels, jeder von ‚r.iv‘, ‚r.mm‘, und so weiter ist eigentlich ein Methodenaufruf an das römischen Objekt. Natürlich ist es keine ‚iv‘ oder eine ‚mm‘ Methode, so wird stattdessen zu method_missing weitergegeben steuern, die den Namen der Methode bekommt, die, ebenso wie alles, was Argument genannt wurden übergeben wurden.

method_missing wandelt dann den Methodennamen von einem Symbol zu einem String, und parst ihn als römische Zahl, die Ausgabe als eine Ganzzahl zurück.

Andere Tipps

Es ist wahrscheinlich am besten nicht von Rubin zu denken, wie Methoden mit. Wenn Sie ein Rubin „Methode“ rufen Sie senden tatsächlich eine Nachricht an diese Instanz (oder Klasse), und wenn Sie einen Handler für die Nachricht definiert haben, wird es verwendet, zu verarbeiten und einen Wert zurückgeben.

So method_missing eine spezielle Definition ist die aufgerufen wird, wenn Rubin keine apropriate Handler finden. Man könnte denken, es auch wie ein * Verfahren.

Es ist im Grunde ein Allheilmittel für alle Nachrichten, die an irgendwelchen Methoden nicht zusammenpassen. Es wird ausführlich in aktiver Datensatz für dynamische Sucher verwendet. Es ist, was können Sie so etwas schreiben:

SomeModel.find_by_name_and_number(a_name, a_number)

Das Modell enthält keinen Code für die find_by, so method_missing aufgerufen, die an heißt schaut sagt - ich dieses Format erkennen und führt es aus. Wenn dies nicht der Fall, dann bekommen Sie eine Methode nicht gefunden Fehler.

In der römischen Beispiel nennen Sie es zeigt, wie Sie die Funktionalität einer Klasse, ohne explizit definieren Methoden erweitern können.

r.iv ist keine Methode so method_missing es fängt und ruft roman_to_int über die Methode id "iv"

Es ist auch nützlich, wenn Sie an anderer Stelle unbekannte Methoden behandeln mögen, wie Proxies, delegators und Spediteure, wie die Dokumentation wird.

Sie rufen Sie nicht „method_missing“ (der Dolmetscher nennt). Vielmehr Sie definieren es (außer Kraft setzt es) für eine Klasse, die Sie seinen flexibler machen wollen. Wie in anderen Kommentaren erwähnt, wird der Dolmetscher Ihre Version von method_missing nennen, wenn die Klasse (oder Instanz) nicht ( „explizit“?) Die gewünschte Methode definieren. Dies gibt Ihnen eine Chance, etwas nach oben, auf dem ersatz Methode / Nachrichtennamen basieren.

Haben Sie jemals eine „Reflexion“ Programmierung in Java getan? Mit dieser Methode wäre, als ob die Klasse über Reflexion zugegriffen wird an der Zeichenfolge aussehen könnte (mich entschuldigen, „Symbol“) des Methodennamen, wenn eine nicht-so-Methode Ausnahme geworfen wurde, und dann etwas wie die Methode des Make-up Umsetzung im Fluge.

Die dynamische Programmierung Art eines "one-up" auf Reflexion ist.

Da Sie Web-Anwendungen erwähnen ich denke, dass Sie Ruby vertraut sind on Rails. Ein gutes Beispiel dafür, wie method_missing verwendet werden können, sind die unterschiedlichen find_by_<whatever> Methoden, die verfügbar ist. Keine dieser Methoden gibt es tatsächlich! Sie werden während der Laufzeit synthetisiert. All diese Magie, weil, wie Rubin fängt Anrufungen von nicht existierenden Methoden.

geschieht

Sie können mehr über diese und andere Verwendungen von method_missing lesen hier .

Active verwendet method_missing find_by Methoden zu definieren. Aber da, method_missing ist im Grunde ein letzter Ausweg Methode, kann dies eine ernsthafte Performance-Engpass sein. Was ich entdeckte, dass Active hat einige weitere ehrfürchtige metaprogramming durch die neue Suchmethode als Klassenmethode definieren !! Somit würde jeder weitere Anrufe zum gleichen Suchmethode nicht die method_missing getroffen, weil es jetzt eine Klassenmethode ist. Ausführliche Informationen über den aktuellen Code-Schnipsel aus base.rb, klicken Sie auf hier .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top