2009-12-13 10 views
12

Tengo una clase con una constante definida para él. Luego tengo un método de clase definido que accede a esa constante de clase. Esto funciona bien Un ejemplo:(En Ruby) permitiendo métodos de clase mixta acceso a constantes de clase

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

surge Mi problema en el intento de mover este método de clase a un módulo externo, así:

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

Rubí interpreta el método como solicitar una constante desde el módulo, en lugar de la clase:

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

Entonces, ¿qué hacer trucos de magia que compañeros que dejar que el acceso método de la constante de la clase? Muchas gracias.

Respuesta

14

Esto parece funcionar:

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

Bueno, eso aclara las cosas. Aún no había experimentado la :: sintaxis :). – jameshfisher

+0

No pares de leer ahora mismo. Lea a continuación la respuesta de Johanna. – Sebastian

9

El problema es, si usted acaba de escribir Const se evalúa el tiempo de creación de módulos. Tienes que usar Module#const_get en lugar de esta manera: const_get(:Const). Esto se evalúa en tiempo de ejecución cuando se ejecuta el método. Entonces esto sucede en tu clase y no en tu módulo.

+0

Gracias! Ese era el tipo de método que estaba buscando, sin éxito. – jameshfisher

12

Vale la pena señalar que no es necesario incluir módulos en una metaclase.

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

Ruby tiene la palabra clave extend que añade eficazmente la interfaz de módulos a una clase, por ejemplo,

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

usted todavía necesita para asegurarse de que está haciendo referencia a la constante derecha usando self::Const o const_get, pero extend <module> es la mejor manera de añadir esos métodos a la clase.

+0

Otro comentario útil. Aprendí tres cosas al hacer una pregunta. – jameshfisher

Cuestiones relacionadas