In Ruby 1.9.3 muss ich einige Klasseninstanzen anlegen, die jeweils ähnliche Instanz- und Klassenmethoden haben, aber nur um einige feste Parameter variieren. Die Unterscheidung ihrer Klassenart ist ebenfalls wichtig, daher kann ich nicht einfach einzelne Instanzen derselben Klasse verwenden.
Ein vereinfachtes Beispiel sieht so aus.
%Vor%Dies scheint gut zu funktionieren, außer dass die Variablen, die in dem Block verwendet werden, der die "Schrei" -Methode dynamisch definiert, zur Laufzeit der "Schrei" -Methode statt der Laufzeit der "make_animal" -Methode gebunden sind.
%Vor% Wie kann ich den obigen Code ändern, damit der Tiger "ROAR!"
? schreit?
[Anmerkung] Ich muss wirklich die doofe OO-Struktur im Beispiel beibehalten, aus Gründen, die hier zu beschreiben sind. Ich bin nur daran interessiert, zu lernen, wie man Klassenmethoden dynamisch definierter Klassen mit parametrisierten Methodenimplementierungen definiert.
klass.class
ist in beiden Fällen (Klasse) gleich: Alle Klassen sind Instanzen von Class
. Als Ergebnis definierst du den Schrei und definierst ihn dann neu.
Was oft als Klassenmethoden in Ruby angesehen wird, sind Singleton-Methoden (es gibt eine Menge zu lesen über Eigenklassen etc. wenn Sie interessiert sind).
Das
%Vor%Construct erstellt Singleton-Methoden. Sehr oft wird dies innerhalb einer Klassendefinition sein, die Sie selbst verwenden, aber Sie können es auch auf andere Weise tun, zum Beispiel wenn Sie
tun %Vor%Dann wird x.bark Woof zurückgeben, aber Rinde wird in keiner anderen Zeichenfolge definiert.
Hier muss Ihre Methode auf Ihre noise
Variable verweisen, daher müssen Sie define_singleton_method
verwenden, um Ihre Methode zu definieren.
Wenn Sie immer noch in Ruby 1.8 sind, können Sie nicht define_singleton_method verwenden - Sie müssen die Tatsache verwenden, dass Singleton-Methoden Methoden für die Eigenklasse sind.
%Vor%Dies entspricht der Verwendung von define_singleton_method
Das Problem mit Ihrem Code ist kein falscher Bindungsmoment. Sie definieren die Methode für Class#class
. Und es ist, Überraschung-Überraschung,% Co_de%, die einzige und einzige. Sie überschreiben also die "Brüll" -Version mit der "Derp" -Version.
Stattdessen sollten Sie Methoden für diese dynamischen Klassen direkt definieren. Hier ist mein Take (es ist die Verwendung von instance var für Class
, hoffe, das ist kein Problem).
Tags und Links ruby metaprogramming