web-dev-qa-db-fra.com

solutions au message ennuyeux "avertissement: constante déjà initialisée"

Aujourd'hui, je suis tombé sur un problème délicat avec les constantes Ruby. Dans notre équipe, quelqu'un a créé un module, qui est inclus dans plusieurs modèles. Dans notre sortie de test (spec), cela se traduit par des messages d'avertissement tels que comme:

/home/ayrton/project/lib/life_cycle.rb:5: avertissement: réinitialisation constante déjà initialisée

Une façon de résoudre ce problème est de déclarer vos constantes comme ceci:

module LifeCycle

  unless (const_defined?(:RESET))
    RESET = 'reset'
  end

  #...
end

J'ai également lu un article de blog, écrit par Avdi Grimm, qui fournit une alternative solution , je me demandais ce que vous en pensez à ce sujet.

63
user191766

J'ai rencontré ce même problème aujourd'hui et j'ai trouvé une solution simple.

Étant donné que l'avertissement est d'essayer de réaffecter une constante avec sa même valeur, je viens de changer

module LifeCycle
  RESET = 'reset'
end

à

module LifeCycle
  RESET ||= 'reset'
end

Cela a pris en charge l'avertissement et est beaucoup plus simple que de vérifier si chaque constante est définie. Faites-moi savoir si vous trouvez une meilleure solution.

112
Matthew Leonard

Ce n'est qu'un problème dans les applications qui se rechargent explicitement, comme Rails applications.

Si la verbosité vous offense, vous pouvez utiliser unless comme modificateur d'instruction à la place:

module LifeCycle
  RESET = 'reset' unless const_defined?(:RESET)
end

Cela laisse quelques arguments faibles contre la suggestion d'Avdi de n'utiliser que des méthodes:

  • la recherche constante est plus rapide que la recherche de méthode,
  • des valeurs constantes sont définies en charge, pas sur (première) demande,
  • les constantes suggèrent visuellement qu'elles n'ont besoin d'aucun travail pour dériver, et

Si vous aimez assez la suggestion d'Avdi pour les ignorer, allez-y.

20
sheldonh

RESET n'est pas une constante s'il continue de changer dans votre code. Si vous le renommez en minuscule "reset", le problème disparaît. Ruby pense que les variables majuscules sont des constantes et affiche donc une erreur pour vous avertir qu'une constante a changé.

5
Luis Pizana