2011-10-31 12 views
48

Oggi mi sono imbattuto in un problema spinoso con le costanti di Ruby. Nel nostro team qualcuno ha creato un modulo, che è incluso in più modelli. Nel nostro (spec) uscita di test questo si traduce in messaggi di avviso come ad esempio:soluzioni al fastidioso messaggio "avviso: costante già inizializzata"

/home/ayrton/project/lib/life_cycle.rb:5: avvertimento: già inizializzato costante RESET

One modo per risolvere questo è, è quello di dichiarare le costanti in questo modo:

module LifeCycle 

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

    #... 
end 

ho anche letto un post sul blog, scritto da Avdi Grimm, che fornisce un'alternativa solution, mi chiedevo quali sono le vostre opinioni sono, per quanto riguarda questo m Atter.

+0

vuoi dire che è 'require'd in più modelli o 'include'd? Dovrebbe essere caricato solo una volta anche se 'require'd più volte –

risposta

17

Questo è solo un problema nelle applicazioni che ricaricano esplicitamente, come le applicazioni Rails.

Se la verbosità ti offende, è possibile utilizzare unless come modificatore dichiarazione invece:

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

Questo lascia alcuni argomenti deboli contro il suggerimento di Avdi al solo metodi di utilizzo:

  • costante ricerca è più veloce della ricerca del metodo,
  • valori costanti sono definiti sul carico, non sulla (prima) richiesta,
  • costanti visuall Si suggerisce che non richiedono alcun lavoro per derivare, e

Se ti piace il suggerimento di Avdi abbastanza da ignorare questi, vai con esso.

+0

Questa è in realtà un'applicazione Rails, temevo che" a meno che const_defined? "Sia una soluzione che maschera il problema e in realtà non lo risolve. – Ayrton

+1

Se il problema è il ricaricamento dell'origine, questo lo maschera. Altrimenti, lo risolve.:-) – sheldonh

81

Ho riscontrato questo stesso problema oggi e ho trovato una soluzione semplice.

Dal momento che l'avviso è da cercare di riassegnare una costante con il suo stesso valore, ho appena cambiato

module LifeCycle 
    RESET = 'reset' 
end 

a

module LifeCycle 
    RESET ||= 'reset' 
end 

Questo ha curato l'avvertimento ed è molto più semplice di controllo se ogni costante è definita. Fammi sapere se trovi una soluzione migliore.

+2

Questo si presta molto bene all'allarme. –

+2

Memoizing è una buona soluzione se l'avviso è causato dal ricaricamento della classe. Se stai ignorando le costanti da classi di terze parti, è più sicuro lasciare l'avviso in posizione. –

+0

Questo funziona per Ruby ma Rubocop genera un errore quando si esegue questa operazione: 'Si è verificato un errore mentre il controllo Style/MutableConstant controllava ' – anthony

6

RESET non è una costante se continua a cambiare nel codice. Se si rinomina in minuscolo 'reset', il problema scompare. Ruby pensa che le variabili maiuscole sono costanti e quindi visualizza un errore per avvertirti che una costante è cambiata.

0

ho ottenuto questo errore in Ruby quando Intellij IDE .. Questo è dovuto al nome della variabile dichiarata inizia con lettere maiuscole .. fare che minuscole sarà risolvere questo problema ..

Problemi correlati