2009-03-30 12 views
72

Ho alcuni moduli in cui vorrei utilizzare variabili di istanza in Attualmente sto li inizializzazione in questo modo:Come posso inizializzare le variabili di istanza di un modulo in Ruby? .

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

Ho anche potuto chiamare un metodo init per inizializzare loro:

def init 
    @var = 0 
end 

ma questo significherebbe che devo ricordare di chiamarlo sempre.

C'è un modo migliore per farlo?

+3

Il primo blocco di codice non imposta un var di istanza di modulo (una var nell'ambito di oggetto di tipo MyModule), mentre il secondo imposta un'istanza di "plain" var (una var nell'ambito di un'istanza che includeva il modulo)? Penso che questi due blocchi di codice non facciano la stessa cosa ... –

risposta

98

inizializzarle nella definizione del modulo.

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!" 

Questo imposterà le variabili di istanza quando il modulo è definito. Ricorda che puoi alwasys riaprire il modulo di seguito per aggiungere più variabili di istanza e le definizioni di metodo, o ridefinire quelli esistenti:

# 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

Qualcuno sta leggendo la guida commovente;) –

+12

E 'stato un po', ma sì :). Inoltre, sento che tutto ciò che deve essere detto sui signori Foo e Bar è stato detto. – rampion

+0

Grazie per la risposta. – Geo

6

È possibile utilizzare:

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

E questo verrà impostato a 0 se non si passa nulla.

Se non si vuole avere a chiamarlo ogni volta, si potrebbe usare qualcosa di simile:

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

end 
+0

Quindi, devo ancora chiamare questa funzione prima di fare qualsiasi cosa con il modulo? – Geo

+0

Ho aggiunto un secondo modo per evitare questo problema - è dal codice di rotaia – Brian

2

per una classe, direi quanto segue, dal momento che l'inizializzazione viene chiamato ogni volta che si. nuova una nuova istanza della classe.

def initialize 
    @var = 0 
end 

da Practical Ruby:

Si va a dire che inizializzazione di un modulo verrà chiamato se un tra cui inizializzazione della classe chiama super, ma non dice che questo è una conseguenza di come funziona super dappertutto, non la gestione speciale per inizializzazione. (Perché potrebbe assumere uno inizializzazione ottiene un trattamento speciale? perché ottiene un trattamento speciale con rispetto alla visibilità. Casi particolari creare confusione.)

+1

Dal momento che è un modulo, verrà inizializzata la chiamata? Ecco la mia prima risposta. Ho aggiunto il secondo per spiegare che non viene chiamato. – Brian

+1

OP specificamente menzionato moduli, non classi – Zensaburou

1

mi risponde una simile question, è possibile impostare le variabili di istanza di classe fare questo

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

Apparentemente è una cattiva forma inizializzare le variabili di istanza in un modulo in Ruby. (Per ragioni che non comprendiamo, ma circa l'ordine in cui le cose vengono istanziati.)

Sembra che le migliori prassi è quella di utilizzare metodi di accesso con l'inizializzazione pigra, in questo modo:

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

Poi utilizzare var come getter per @var.

+3

Nota questo non ti consentirà mai di impostare @var su 'nil' o' false' – steel

Problemi correlati