Ich stecke fest. Ich versuche, dynamisch eine Klasse-Methode zu definieren und ich kann nicht wickeln meinen Kopf um die Ruby-Metaklasse-Modell. Betrachten Sie die folgende Klasse:
class Example
def self.meta; (class << self; self; end); end
def self.class_instance; self; end
end
Example.class_instance.class # => Class
Example.meta.class # => Class
Example.class_instance == Example # => true
Example.class_instance == Example.meta # => false
Offensichtlich geben beide Methoden eine Instanz von Class zurück. Aber diese beiden Instanzen sind nicht dieselben. Sie haben auch unterschiedliche Vorfahren:
Example.meta.ancestors # => [Class, Module, Object, Kernel]
Example.class_instance.ancestors # => [Example, Object, Kernel]
Welchen Sinn hat es, einen Unterschied zwischen der Metaklasse und der Klasseninstanz zu machen?
Ich habe herausgefunden, dass ich send :define_method
an die Metaklasse, um eine Methode dynamisch zu definieren, aber wenn ich versuche, sie an die Klasseninstanz zu senden, funktioniert es nicht. Zumindest konnte ich mein Problem lösen, aber ich möchte immer noch verstehen, warum es auf diese Weise funktioniert.
Update 15. März 2010 13:40
Sind die folgenden Annahmen richtig?
- Wenn ich eine Instanzmethode habe, die self.instance_eval aufruft und eine Methode definiert, wirkt sie sich nur auf die jeweilige Instanz dieser Klasse aus.
- Wenn ich eine Instanzmethode habe, die self.class.instance_eval aufruft (was dasselbe wäre wie der Aufruf von class_eval) und eine Methode definiert, wirkt sich das auf alle Instanzen dieser bestimmten Klasse aus und führt zu einer neuen Instanzmethode.
- Wenn ich eine Klassenmethode habe, die instance_eval aufruft und eine Methode definiert, wird dies zu einer neuen Instanzmethode für alle Instanzen führen.
- Wenn ich eine Klassenmethode habe, die instance_eval auf der Meta-/Eigenklasse aufruft und eine Methode definiert, führt dies zu einer Klassenmethode.
Ich glaube, das ergibt langsam einen Sinn für mich. Es würde sicherlich Ihre Möglichkeiten einschränken, wenn self innerhalb einer Klassenmethode auf die eigene Klasse verweisen würde. In diesem Fall wäre es nicht möglich, eine Instanzmethode innerhalb einer Klassenmethode zu definieren. Ist das richtig?