2010-07-28 9 views
19

Est-il possible de déclarer des méthodes statiques dans un module dans ruby?Méthodes statiques dans les modules ruby?

module Software 
    def self.exit 
    puts "exited" 
    end 
end 

class Windows 
    include Software 

    def self.start 
    puts "started" 
    self.exit 
    end 
end 

Windows.start 

L'exemple ci-dessus n'imprime pas "sortie".

Est-il seulement possible d'avoir des méthodes d'instance dans un module?

Répondre

29

Définir votre module comme celui-ci (à savoir faire exit une méthode d'instance dans le module):

module Software 
    def exit 
    puts "exited" 
    end 
end 

puis utilisez extend plutôt que include

class Windows 
    extend Software 
    # your self.start method as in the question 
end 

En utilisation:

irb(main):016:0> Windows.start 
started 
exited 
=> nil 

Ex aplanissement

obj.extend(module, ...) ajoute à obj les méthodes d'instance de chaque module donné comme paramètre

... donc quand il est utilisé dans le cadre d'une définition de classe (avec la classe comme le récepteur) les méthodes deviennent des méthodes de classe.

0

Il est possible d'inclure des méthodes statiques dans un module:

module Software 

    def self.exit 
    puts "exited" 

    end 
end 

Software.exit 

L'exécution de cette impression 'quitté' comme prévu.

+0

mais dois-je inclure ce module dans la classe pour utiliser la méthode statique? cause include inclut juste des méthodes d'instance d'un module non statique? –

+0

Ah, pas sûr sur celui-là. Une solution facile serait juste d'appeler 'Software.exit' dans la classe Windows et de se débarrasser de la partie 'include Software' (pas la solution la plus élégante, mais en dehors de la portée de cette question telle qu'elle est actuellement posée). –

2

Deux choses doivent changer pour pouvoir appeler Windows.exit:

  1. Software#exit doit être une méthode d'instance
  2. Windows besoins à extendSoftware, pas include il.

En effet, un autre module extend ing met en les méthodes de classe du module courant des méthodes d'instance de ce module, alors que include un module met ing les méthodes que de nouvelles méthodes d'instance.

module Software 
    def exit 
     puts "exited" 
    end 
end 

class Windows 
    extend Software 

    def self.start 
     puts "started" 
     self.exit 
    end 

end 

Windows.start 

sortie est:

 
started 
exited 
12

Mettez vos méthodes de classe dans un module imbriqué, puis remplacer le crochet "inclus". Ce hook est appelé à chaque fois que votre module est inclus.A l'intérieur du crochet, ajoutez les méthodes de la classe à qui ne le comprennent:

module Foo 

    def self.included(o) 
    o.extend(ClassMethods) 
    end 

    module ClassMethods 

    def foo 
     'foo' 
    end 

    end 

end 

Maintenant, toute classe, y compris Foo obtient une méthode de classe nommée foo:

class MyClass 
    include Foo 
end 

p MyClass.foo # "foo" 

Toutes les méthodes non-classe peuvent être définies dans Foo comme d'habitude.

+0

(à côté: c'est MyClass.foo) Cette approche a l'avantage de pouvoir également ajouter des fonctions non statiques. – Baju

+0

@Baju, soit '::' ou '.' fonctionne, mais je suppose que' .' est préféré. J'ai modifié l'exemple. Merci d'avoir fait remarquer cela. –

+0

-1. Yuck, c'est complètement inutile. Utilisez simplement 'extend' au lieu de' include'. –

Questions connexes