2012-02-10 66 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

相关问题