Considérez la classe suivante:
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
Ce n'est pas un problème et vous pouvez appeler Foo.new.a_new_inst_method
sans problème.
J'aimerais pouvoir avoir une méthode de classe comme Foo.add_widget(*items)
et l'alias pour que je puisse faire quelque chose comme:
Foo.add_widget 'item1'
Foo.add_widgets 'item2', 'item3'
Donc, essentiellement, il a un "style rubis" 1.minute
et 2.minutes
je veux donc alias un Foo.add_widget
appel qui Foo.add_widgets
appelle exactement la même méthode. Je sais que je pourrais l'envelopper, mais je pense que je devrais pouvoir le faire de manière plus propre.
Considérez ma tentative d'essayer quelque chose comme ceci:
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
Cependant, j'obtiens l'erreur suivante:
NameError (undefined method `a_class_method' for class `Foo')
Il semble donc que cela ne fonctionne pas pour les méthodes de classe. Comment dois-je procéder?
ruby
alias-method
aarona
la source
la source
Réponses:
alias_method
alias une méthode d'instances du récepteur. Les méthodes de classe sont en fait des méthodes d'instance définies sur la classe singleton d'une classe.Pour alias une méthode d'instance définie sur la classe singleton, vous pouvez soit l'ouvrir à l'aide de la
class << object
syntaxe.Ou vous pouvez vous y référer directement en utilisant la
singleton_class
méthode.Si vous êtes toujours dans le contexte de la classe
self
, vous vous référerez à la classe. Ainsi, ce qui précède pourrait également s'écrire:Ou
Ou une combinaison des deux.
la source
Vous pouvez encapsuler les méthodes de classe et leurs
alias_method
appels dans un module séparé et incorporer ce module dans votre classe viaextend
:la source
extend ClassMethods
solution. +1La chose importante à comprendre est qu'il n'existe pas de méthode de classe dans Ruby.
Une méthode de classe n'est vraiment qu'une méthode singleton. Il n'y a rien de spécial dans les méthodes de classe. Chaque objet peut avoir des méthodes singleton. Nous les appelons simplement «méthodes de classe» lorsque l'objet est un
Class
car «la méthode singleton d'une instance deClass
» est trop longue et trop lourde.Attendre! Ai-je dit "méthode singleton"?
Une autre chose importante à comprendre est qu'il n'existe pas de méthode singleton en Ruby.
Une méthode singleton n'est en fait qu'une ancienne méthode d'instance ennuyeuse ordinaire de la classe singleton. Les méthodes singleton n'ont rien de spécial. Ce ne sont que des méthodes d'instance comme toute autre méthode d'instance.
En fait, Ruby n'a que des méthodes d'instance. Aucune fonction, aucun constructeur, aucune méthode statique, aucune méthode de classe, aucune fonction de module, aucune méthode singleton.
La question n'est pas "est-ce une méthode de classe, est-ce une méthode singleton", mais plutôt "dans quel module cette méthode est-elle définie?"
Les "méthodes singleton" sont en fait des méthodes d'instance définies dans la classe singleton. La syntaxe pour accéder à la classe singleton de
foo
estIl existe également une méthode
Object#singleton_class
qui renvoie la classe singleton d'un objet.Pourquoi suis-je si agressif sur le fait que chaque méthode est une méthode d'instance et que les méthodes de classe n'existent pas? Parce que cela signifie que le modèle objet de Ruby est beaucoup plus simple que les gens ne le pensent! Après tout, dans votre question, vous montrez déjà que vous savez comment alias les méthodes d'instance, mais vous dites que vous ne savez pas comment alias les méthodes de classe. Mais c'est faux! Vous ne savez comment les méthodes de classe d'alias, parce qu'ils ne sont que des méthodes d'instance . Si vous aviez appris ce fait correctement, vous n'auriez jamais eu besoin de poser cette question!
Une fois que vous comprenez que chaque méthode est une méthode d'instance et que ce que nous appelons les "méthodes singleton" ne sont que des méthodes d'instance de la classe singleton, la solution devient claire:
Remarque: lorsque j'ai écrit ci-dessus «il n'y a rien de tel que X», je voulais dire «qu'il n'y a pas de chose telle que X dans le langage Ruby ». Cela ne signifie pas que ces concepts n'existent pas dans la communauté Ruby .
Nous parlons régulièrement de «méthodes singleton» et de «méthodes de classe», simplement parce que c'est plus facile que de parler de «méthodes d'instance de la classe singleton» ou de «méthodes d'instance de la classe singleton d'un objet qui se trouve être une instance de la
Class
classe ". Il existe des méthodes comme mêmeObject#define_singleton_method
,Object#singleton_method
,Object#singleton_methods
,Module#private_class_method
,Module#public_class_method
, etModule#module_function
dans la bibliothèque de base Ruby. Mais il est toujours important de se rappeler que ce ne sont pas des concepts de langage. Ce sont des concepts communautaires qui n'existent que dans nos têtes et dans les noms de certaines méthodes de bibliothèque.la source
OK, on dirait que je peux faire quelque chose comme ça et ça marchera:
Si quelqu'un a des informations utiles sur le langage Ruby ici et souhaite soumettre une réponse complète, je vous donnerai un +1.
la source
class << self
suiviez paralias_method :a_new_class_method, :a_class_method
vous appelez en faitalias_method
sur la classe singletonFoo
. Une autre façon d'écrire ceci est:singleton_class.alias_method :a_new_class_method, :a_class_method
dans le contexte de la classe.alias_method
fonctionne sur l'instance, vous devez donc aller plus loin et opérer sur l'Class
instance ou la métaclasse de la classe . Ruby a un modèle d'objet sauvage qui peut être une sorte de rupture cérébrale, mais il vous donne également une tonne de puissance:la source