2009-03-30 15 views
72

tengo algunos módulos donde me gustaría utilizar variables de instancia en la que estoy actualmente inicialización de ellos de esta manera:¿Cómo puedo inicializar las variables de instancia de un módulo en Ruby? .

module MyModule 
    def self.method_a(param) 
    @var ||= 0 
    # other logic goes here 
    end 
end 

que también podría llamar a un método init para inicializar ellos:

def init 
    @var = 0 
end 

pero esto significaría que debo recordar llamarlo siempre.

¿Hay una mejor manera de hacerlo?

+3

El primer bloque de código no establece un var de instancia de módulo (var en el alcance del objeto de tipo de MyModule), mientras que el segundo establece una var de instancia "simple" (una var en el alcance de una instancia que incluye módulo)? Creo que estos dos bloques de código no hacen lo mismo ... –

Respuesta

98

ellos Inicialización en la definición del módulo.

module MyModule 
    # self here is MyModule 
    @species = "frog" 
    @color = "red polka-dotted" 
    @log = [] 

    def self.log(msg) 
    # self here is still MyModule, so the instance variables are still available 
    @log << msg 
    end 
    def self.show_log 
    puts @log.map { |m| "A #@color #@species says #{m.inspect}" } 
    end 
end 

MyModule.log "I like cheese." 
MyModule.log "There's no mop!" 
MyModule.show_log #=> A red polka-dotted frog says "I like cheese." 
        # A red polka-dotted frog says "There's no mop!" 

Esto configurará las variables de instancia cuando se defina el módulo. Recuerde, usted puede volver a abrir alwasys el módulo más tarde para agregar más variables de instancia y definiciones de métodos, o redefinir las existentes:

# continued from above... 
module MyModule 
    @verb = "shouts" 
    def self.show_log 
    puts @log.map { |m| "A #@color #@species #@verb #{m.inspect}" } 
    end 
end 
MyModule.log "What's going on?" 
MyModule.show_log #=> A red polka-dotted frog shouts "I like cheese." 
        # A red polka-dotted frog shouts "There's no mop!" 
        # A red polka-dotted frog shouts "What's going on?" 
+17

Alguien ha estado leyendo la guía conmovedora;) –

+12

Ha pasado un tiempo, pero sí :). Además, creo que todo lo que debe decirse sobre los Sres. Foo y Bar ha sido dicho. – rampion

+0

Gracias por su respuesta. – Geo

6

Se puede utilizar:

def init(var=0) 
@var = var 
end 

Y pondrá por defecto a 0 si no pasa nada.

Si no quieren tener que llamar cada vez, usted podría utilizar algo como esto:

module AppConfiguration 
    mattr_accessor :google_api_key 
    self.google_api_key = "123456789" 
... 

end 
+0

Entonces, ¿aún necesito llamar a esta función antes de hacer algo con el módulo? – Geo

+0

Agregué una segunda forma para evitar ese problema: es del código de los rieles – Brian

2

para una clase, diría lo siguiente, ya que la inicialización se llama cada vez que. nueva una nueva instancia de la clase.

def initialize 
    @var = 0 
end 

de Practical Ruby:

Se llega a decir que inicialización de un módulo será llamado si un incluyendo initialize de la clase llama estupendo, pero no menciona que esta es una consecuencia de cómo super trabaja en todas partes, no se inicializa el manejo especial para . (¿Por qué podría suponer una initialize consigue un manejo especial? porque se pone un tratamiento especial con respecto a la visibilidad . Casos especiales crear confusión.)

+1

, dado que es un módulo, ¿se inicializará? Esa fue mi primera respuesta. Agregué el segundo para dar cuenta de que no fue llamado. – Brian

+1

OP módulos mencionados específicamente, no las clases – Zensaburou

1

i respondieron un similares question, se puede establecer variables de instancia de clase hacer esto

module MyModule 
    class << self; attr_accessor :var; end 
end 

MyModule.var 
=> nil 

MyModule.var = 'this is saved at @var' 
=> "this is saved at @var" 

MyModule.var  
=> "this is saved at @var" 
2

Aparentemente es incorrecto inicializar variables de instancia en un módulo en Ruby. (Por razones que no entiendo totalmente, pero perteneciente al orden en el que se crean instancias de las cosas.)

Parece que la mejor práctica es utilizar métodos de acceso con la inicialización perezosa, así:

module MyModule 
    def var 
    @var ||= 0 
    end 
end 

Entonces use var como getter para @var.

+3

Tenga en cuenta que esto nunca le permitirá configurar @var en 'nil' o' false' – steel

Cuestiones relacionadas