2009-12-13 4 views
12

J'ai une classe avec une constante définie pour cela. J'ai alors une méthode de classe définie qui accède à cette constante de classe. Cela fonctionne bien. Un exemple:(In Ruby) permettant des méthodes de classe mélangées accès aux constantes de classe

#! /usr/bin/env ruby 

class NonInstantiableClass 
    Const = "hello, world!" 
    class << self 
     def shout_my_constant 
      puts Const.upcase 
      end 
     end 
    end 

NonInstantiableClass.shout_my_constant 

Mon problème se pose en tentant de déplacer cette méthode de classe vers un module externe, comme suit:

#! /usr/bin/env ruby 

module CommonMethods 
    def shout_my_constant 
     puts Const.upcase 
     end 
    end 

class NonInstantiableClass 
    Const = "hello, world!" 
    class << self 
     include CommonMethods 
     end 
    end 

NonInstantiableClass.shout_my_constant 

Ruby interprète le procédé demandant une constante à partir du module, plutôt que la classe:

line 5:in `shout_my_constant': uninitialized constant CommonMethods::Const (NameError) 

Alors, quels tours de magie avez-vous pour laisser la méthode accéder à la constante de classe? Merci beaucoup.

Répondre

14

Cela semble fonctionner:

#! /usr/bin/env ruby 

module CommonMethods 
    def shout_my_constant 
     puts self::Const.upcase 
    end 
end 

class NonInstantiableClass 
    Const = "hello, world!" 
    class << self 
     include CommonMethods 
    end 
end 

NonInstantiableClass.shout_my_constant 

HTH

+0

Eh bien, cela éclaircit les choses. Je devais encore expérimenter la syntaxe :: :). – jameshfisher

+0

N'arrêtez pas de lire pour le moment. Lire ci-dessous la réponse de johannes. – Sebastian

9

Le problème est, si vous écrivez juste Const il est évalué à l'heure de création du module. Vous devez utiliser Module#const_get à la place comme ceci: const_get(:Const). Ceci est évalué à l'exécution lorsque la méthode est exécutée. Cela se passe donc dans votre classe et non dans votre module.

+0

Merci! C'était le genre de méthode que je cherchais, sans succès. – jameshfisher

12

Il vaut probablement la peine de noter que vous n'avez pas besoin d'inclure des modules dans une métaclasse.

class NonInstantiableClass 
    Const = "hello, world!" 
    class << self 
     include CommonMethods 
    end 
end 

Ruby a le mot-clé extend qui ajoute de manière efficace l'interface de modules à une classe, par exemple,

class NonInstantiableClass 
    Const = "hello, world!" 
    extend CommonMethods 
end 

Vous devez toujours vous assurer que vous faites référence à la constante droite à l'aide self::Const ou const_get, mais extend <module> est la meilleure façon d'ajouter ces méthodes à la classe.

+0

Encore un autre commentaire utile. J'ai appris trois choses en posant une question. – jameshfisher

Questions connexes