Betrachten Sie die folgende Klasse:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
end
Dies ist kein Problem und Sie können Foo.new.a_new_inst_method
ohne Probleme anrufen .
Ich hätte gerne die Möglichkeit, eine Klassenmethode wie Foo.add_widget(*items)
und einen Alias zu haben, damit ich so etwas tun kann:
Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'
Im Wesentlichen hat es also einen "Ruby-Stil" wie 1.minute
und 2.minutes
so möchte ich einen Alias eines Foo.add_widget
so aufrufenden Aufrufs Foo.add_widgets
genau der gleichen Methode. Ich weiß, dass ich es einpacken könnte, aber ich denke, ich sollte dies sauberer tun können.
Betrachten Sie meinen Versuch, so etwas zu versuchen:
class Foo
def an_inst_method
'instance method'
end
def self.a_class_method
'class method'
end
alias_method :a_new_inst_method, :an_inst_method
alias_method :a_new_class_method, :a_class_method
end
Ich erhalte jedoch den folgenden Fehler:
NameError (undefined method `a_class_method' for class `Foo')
Es sieht also so aus, als würde dies für Klassenmethoden nicht funktionieren. Wie mache ich das?
quelle
extend ClassMethods
Lösung vergessen . +1Es ist wichtig zu verstehen, dass es in Ruby keine Klassenmethode gibt .
Eine Klassenmethode ist eigentlich nur eine Singleton-Methode. Klassenmethoden haben nichts Besonderes. Jedes Objekt kann Singleton-Methoden haben. Wir nennen sie einfach "Klassenmethoden", wenn das Objekt eine ist,
Class
weil die "Singleton-Methode einer Instanz vonClass
" zu lang und unhandlich ist.Warten! Habe ich "Singleton-Methode" gesagt?
Ein weiterer wichtiger Punkt ist, dass es in Ruby keine Singleton-Methode gibt .
Eine Singleton-Methode ist eigentlich nur eine normale, langweilige alte Instanzmethode der Singleton-Klasse. Singleton-Methoden haben nichts Besonderes. Sie sind nur Instanzmethoden wie jede andere Instanzmethode.
Tatsächlich verfügt Ruby nur über Instanzmethoden. Keine Funktionen, keine Konstruktoren, keine statischen Methoden, keine Klassenmethoden, keine Modulfunktionen, keine Singleton-Methoden.
Die Frage ist nicht "Ist dies eine Klassenmethode, ist dies eine Singleton-Methode ?" , Sondern "In welchem Modul ist diese Methode definiert?"
"Singleton-Methoden" sind wirklich Instanzmethoden, die in der Singleton-Klasse definiert sind. Die Syntax für den Zugriff auf die Singleton-Klasse von
foo
lautetEs gibt auch eine Methode,
Object#singleton_class
die die Singleton-Klasse eines Objekts zurückgibt.Warum hämmere ich so aggressiv auf die Tatsache ein, dass jede Methode eine Instanzmethode ist und dass Klassenmethoden nicht existieren? Weil es bedeutet, dass Rubys Objektmodell viel einfacher ist, als die Leute denken! Schließlich zeigen Sie in Ihrer Frage bereits, dass Sie wissen, wie Instanzmethoden aliasisiert werden, aber Sie sagen, dass Sie nicht wissen, wie Klassenmethoden aliasisiert werden. Aber das ist falsch! Sie wissen , wie man Klassenmethoden aliasisiert, da es sich nur um Instanzmethoden handelt . Wenn Ihnen diese Tatsache richtig beigebracht worden wäre, hätten Sie diese Frage niemals stellen müssen!
Sobald Sie verstehen, dass jede Methode eine Instanzmethode ist und dass das, was wir "Singleton-Methoden" nennen, nur Instanzmethoden der Singleton-Klasse sind, wird die Lösung klar:
Hinweis: Als ich oben schrieb, dass "es kein X gibt", meinte ich, dass "es in der Ruby-Sprache kein X gibt ". Das bedeutet nicht , dass diese Konzepte in der Ruby-Community nicht existieren .
Wir sprechen regelmäßig über "Singleton-Methoden" und "Klassenmethoden", einfach weil es einfacher ist, als über "Instanzmethoden der Singleton-Klasse" oder "Instanzmethoden der Singleton-Klasse eines Objekts, das zufällig eine Instanz der
Class
Klasse ist" ". Es gibt auch Methoden wieObject#define_singleton_method
,Object#singleton_method
,Object#singleton_methods
,Module#private_class_method
,Module#public_class_method
, undModule#module_function
in der Ruby - Core - Bibliothek. Es ist jedoch immer wichtig, sich daran zu erinnern, dass dies keine Sprachkonzepte sind. Dies sind Community- Konzepte, die nur in unseren Köpfen und in den Namen einiger Bibliotheksmethoden existieren.quelle
OK, es sieht so aus, als ob ich so etwas machen kann und es wird funktionieren:
Wenn jemand hier nützliche Informationen über die Ruby-Sprache hat und eine umfassende Antwort einreichen möchte, gebe ich Ihnen eine +1.
quelle
class << self
indem gefolgtalias_method :a_new_class_method, :a_class_method
rufen Sie eigentlichalias_method
auf die Singleton - Klasse vonFoo
. Eine andere Art, dies zu schreiben, ist:singleton_class.alias_method :a_new_class_method, :a_class_method
im Klassenkontext.alias_method
wird auf der Instanz ausgeführt, daher müssen Sie eine Ebene tiefer gehen und dieClass
Instanz oder die Metaklasse der Klasse bearbeiten . Ruby hat ein Wildobjektmodell, das eine Art Gehirnbruch sein kann, aber es gibt Ihnen auch eine Menge Kraft:quelle