2011-10-31 24 views
48

Hoy he tropezado con un problema complicado con las constantes de Ruby. En nuestro equipo, alguien creó un módulo, que se incluye en múltiples modelos. En nuestra (SPEC) salida de prueba esto se traduce en mensajes de advertencia, tales como:soluciones para el molesto mensaje "warning: already initialized constant"

/home/ayrton/project/lib/life_cycle.rb:5: advertencia: que ya está iniciado constante de RESET

Uno manera de resolver esto es, es declarar sus constantes de la siguiente manera:

module LifeCycle 

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

    #... 
end 

también he leído un blog, escrito por Avdi Grimm, que ofrece una alternativa solution, me preguntaba ¿cuáles son sus opiniones, con respecto Esta m Atter.

+0

Cómo que es 'require'd en modelos múltiples, o 'include'd? Debería cargarse solo una vez aunque 'requiera 'varias veces –

Respuesta

17

Esto es solo un problema en las aplicaciones que se vuelven a cargar explícitamente, como las aplicaciones de Rails.

Si el nivel de detalle que ofende, puede utilizar unless como un modificador de comando en su lugar:

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

Esto deja algunos argumentos débiles contra la sugerencia de Avdi que sólo los métodos de uso:

  • de búsqueda constante es más rápido que la búsqueda de métodos,
  • Los valores constantes se definen en la carga, no en la (primera) solicitud,
  • constantes visuall y sugieren que no requieren ningún trabajo para derivar, y

Si le gusta la sugerencia de Avdi lo suficiente como para ignorar estos, vaya con ello.

+0

Esto es, de hecho, una aplicación de Rails, me temo que' a menos que const_defined? 'Es una solución que enmascara el problema y no lo resuelve realmente. – Ayrton

+1

Si el problema es la recarga de la fuente, esto lo enmascara. De lo contrario, lo resuelve.:-) – sheldonh

81

Encontré este mismo problema hoy y encontré una solución simple.

Dado que la advertencia es de tratar de volver a asignar una constante con su mismo valor, que acaba de cambiar

module LifeCycle 
    RESET = 'reset' 
end 

a

module LifeCycle 
    RESET ||= 'reset' 
end 

Esto se hizo cargo de la advertencia y es mucho más simple que la comprobación si cada constante está definida. Avíseme si encuentra una mejor solución.

+2

Esto cuida muy bien la advertencia. –

+2

Memoizing es una buena solución si la advertencia es causada por la recarga de su clase. Si está anulando las constantes de clases de terceros, es más seguro dejar la advertencia en su lugar. –

+0

Esto funciona para Ruby, pero Rubocop lanza un error al hacer eso: 'Se produjo un error mientras el policía Style/MutableConstant estaba inspeccionando ' – anthony

6

RESTABLECER no es una constante si sigue cambiando en su código. Si cambia el nombre a 'restablecer' minúsculas, el problema desaparece. Ruby piensa que las variables mayúsculas son constantes y, por lo tanto, muestra un error para advertirle que una constante ha cambiado.

0

Tengo este error en Ruby cuando IntelliJ IDE .. Eso se debió a nombre de la variable declarada comenzando con mayúscula .. hacen que a minúsculas se resolver este problema ..

Cuestiones relacionadas