2012-02-10 16 views
24

加載特定文件時是否有禁用warning: already initialized constant的方法?如何禁用加載文件時重新定義常量的警告

+3

修復代碼真的不合適嗎? – sarnold 2012-02-10 23:27:51

+1

警告通常表示非致命**錯誤**,應該修復。在這種情況下,你很可能有一個應該修復的真正問題。 – 2012-02-10 23:29:35

+1

您不止一次初始化您的變量。 – 2012-02-10 23:34:40

回答

5

禁止警告,在腳本的頂部使用下面的代碼:

$VERBOSE = nil 
12

this question的接受答案很有幫助。我查看了Rails源代碼以獲得以下內容。加載文件之前和之後,我可以插入以下行:

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

工作。我應該爲它寫一個包裝。 – Dorian 2014-10-13 22:39:14

39

問題的解決方案取決於導致它的原因。

1 - 您正在更改在代碼中的某個位置之前設置的常量的值,或者嘗試使用與existant類或模塊相同的名稱定義常量。解決方案:如果事先知道常數值會改變,請不要使用常數;不要定義與class/modules同名的常量。

2 - 您處於某種情況下,因爲很好的原因想要重新定義常數而不會收到警告。有兩種選擇。

首先,你可以重新定義之前取消定義的常量(這需要一個輔助方法,因爲remove_const是私有函數):

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

或者,你可以直接告訴Ruby解釋閉嘴(這抑制所有警告):

# 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 - 您需要定義一個類/模塊的名稱以一個新的常數或類/模塊要創建衝突的外部庫。解決方案:將代碼包裝在頂級模塊命名空間中以防止名稱衝突。

class SomeClass; end 
module SomeModule 
    SomeClass = '...' 
end 

4 - 同上,但絕對需要定義一個與gem/library的類同名的類。解決方法:您可以將庫的類名分配給一個變量,然後將其清除您以後使用:

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

試試這個:

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

這個方法在Ruby 2.0.0中不存在。 – bfontaine 2014-02-05 15:52:28

+5

它是rails的一部分:http://api.rubyonrails.org/classes/Kernel.html#method-i-silence_warnings – stackdump 2014-04-18 00:38:45

+2

優秀的解決方案,它是rails的一部分,但你可以導入2個方法'silence_warnings'和' with_warnings'在你選擇的文件中,並用它修補'Kernel'。 – Benj 2015-02-08 01:32:59