2009-12-13 13 views
12

Ho una classe con una costante definita per questo. Poi ho definito un metodo di classe che accede a quella costante di classe. Funziona bene Un esempio:(In Ruby) che consente ai metodi di classe mista accesso alle costanti di 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 

mio problema si pone nel tentare di spostare questo metodo di classe ad un modulo esterno, in questo modo:

#! /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 

rubino interpreta il metodo richiede una costante dal modulo, anziché la classe:

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

Quindi, quali trucchi di magia ti compagni deve lasciare che l'accesso metodo di classe costante? Grazie molto.

risposta

14

Questo sembra funzionare:

#! /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

Bene, questo chiarisce le cose. Dovevo ancora sperimentare la :: sintassi :). – jameshfisher

+0

Non smettere di leggere adesso. Leggi sotto la risposta di johannes. – Sebastian

9

Il problema è che, se si scrive Const viene valutata sulla modulo ora di creazione. Devi usare Module#const_get in questo modo: const_get(:Const). Questo viene valutato in fase di esecuzione quando viene eseguito il metodo. Quindi questo succede nella tua classe e non nel tuo modulo.

+0

Grazie! Era il tipo di metodo che stavo cercando, senza successo. – jameshfisher

12

Probabilmente vale la pena notare che non è necessario includere moduli in un metaclasse.

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

rubino ha la parola chiave extend che aggiunge efficacemente l'interfaccia moduli a una classe, ad esempio

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

è ancora necessario per garantire la riferimento la costante destra utilizzando self::Const o const_get, ma extend <module> è il modo migliore per aggiungere tali metodi alla classe.

+0

Ancora un altro commento utile. Ho imparato tre cose dal porre una domanda. – jameshfisher

Problemi correlati