2012-02-10 3 views
24

C'è un modo per disabilitare warning: already initialized constant quando si caricano determinati file?Come disattivare l'avviso per la ridefinizione di una costante durante il caricamento di un file

+3

Il codice è davvero fuori questione? – sarnold

+1

Gli avvisi sono spesso indicativi di errori ** non fatali ** e dovrebbero essere corretti. In questo caso è molto probabile che tu abbia un problema reale da risolvere. –

+1

hai inizializzato la tua variabile più di una volta. –

risposta

5

siano soppressi gli avvisi, utilizzare il seguente codice nella parte superiore dello script:

$VERBOSE = nil 
12

La risposta accettata a this question era utile. Ho guardato la fonte di Rails per ottenere quanto segue. Prima e dopo il caricamento del file, posso inserire queste righe:

# Supress warning messages. 
original_verbose, $VERBOSE = $VERBOSE, nil 
    load(file_in_question) 
# Activate warning messages again. 
$VERBOSE = original_verbose 
+0

che ha funzionato. Probabilmente dovrei scrivere un wrapper per questo. – Dorian

39

La soluzione al vostro problema dipende da ciò che sta causando esso.

1 - Si sta modificando il valore di una costante impostata prima da qualche parte nel codice o si sta tentando di definire una costante con lo stesso nome di una classe o modulo esistente. Soluzione: non utilizzare le costanti se si sa in anticipo che il valore della costante cambierà; non definire costanti con lo stesso nome di classe/moduli.

2 - Si è in una situazione in cui si desidera ridefinire una costante per buoni motivi, senza ricevere avvisi. Ci sono due opzioni.

In primo luogo, si potrebbe undefine la costante prima di doverlo definire nuovamente (questo richiede un metodo di supporto, perché remove_const è una funzione privata):

Object.module_eval do 
    # Unset a constant without private access. 
    def self.const_unset(const) 
    self.instance_eval { remove_const(const) } 
    end 
end 

Oppure, si può solo dire all'interprete di Ruby di stare zitto (questo sopprime tutti avvisi):

# Runs a block of code without warnings. 
def silence_warnings(&block) 
    warn_level = $VERBOSE 
    $VERBOSE = nil 
    result = block.call 
    $VERBOSE = warn_level 
    result 
end 

3 - si stanno richiedendo una libreria esterna che definisce un/modulo di classe cui si scontra con una nuova costante o classe/modulo che si sta creando nome. Soluzione: avvolgi il tuo codice all'interno di uno spazio dei nomi del modulo di livello superiore per evitare il conflitto tra i nomi.

4 - Come sopra, ma è assolutamente necessario definire una classe con lo stesso nome della classe gemma/libreria. Soluzione: è possibile assegnare il nome della classe della biblioteca a una variabile, e quindi cancellarlo per il vostro uso successivo:

require 'clashing_library' 
some_class_alias = SomeClass 
SomeClass = nil 
# You can now define your own class: 
class SomeClass; end 
# Or your own constant: 
SomeClass = 'foo' 
15

Prova questo:

Kernel::silence_warnings { MY_CONSTANT = 'my value '} 
+3

Questo metodo non esiste con Ruby 2.0.0. – bfontaine

+5

È una parte di binari: http://api.rubyonrails.org/classes/Kernel.html#method-i-silence_warnings – stackdump

+2

Soluzione eccellente, fa parte di binari, ma puoi semplicemente importare i 2 metodi 'silence_warnings' e' with_warnings' in un file di tua scelta e patch 'Kernel' con esso. – Benj

Problemi correlati