77 votes

Comment initialiser les variables d'instance d'un module en Ruby?

J'ai quelques modules dans lesquels j'aimerais utiliser des variables d'instance. Je les initialise actuellement comme ceci:

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

Je pourrais aussi appeler une méthode init pour les initialiser:

 def init
  @var = 0
end
 

mais cela voudrait dire que je devrais me rappeler de toujours l'appeler.

Existe-t-il une meilleure façon de le faire?

105voto

rampion Points 38697

Initialisez-les dans la définition du module.

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

Cela définira les variables d'instance lors de la définition du module. N'oubliez pas que vous pouvez toujours rouvrir le module ultérieurement pour ajouter d'autres variables d'instance et définitions de méthode, ou pour redéfinir celles existantes:

 # 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?"
 

5voto

Brian Points 3889

Vous pouvez utiliser:

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

Et il sera par défaut à 0 si vous ne passez rien.

Si vous ne voulez pas avoir à l'appeler à chaque fois, vous pouvez utiliser quelque chose comme ceci:

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

end
 

2voto

Orlando Points 3184

J'ai répondu à une question similaire, vous pouvez définir des variables d'instance de classe pour le faire.

 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"
 

2voto

Andy Points 26

Apparemment, c'est une mauvaise forme pour initialiser des variables d'instance dans un module en Ruby. (Pour des raisons que je ne comprends pas tout à fait, mais concernant l'ordre dans lequel les choses sont instanciées.)

Il semble que la meilleure pratique consiste à utiliser des accesseurs avec une initialisation lente, comme suit:

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

Ensuite, utilisez var comme getter pour @var .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X