如何重新定义一个Ruby常量没有警告?

我正在运行一些Ruby代码,每当它的date发生变化时,它就会传送一个Ruby文件。 在文件中,我有不变的定义

Tau = 2 * Pi 

当然,他们每次都会让解释器显示不需要的“已经初始化的常量”警告,所以我想要具有以下function:

 def_if_not_defined(:Tau, 2 * Pi) redef_without_warning(:Tau, 2 * Pi) 

我可以通过写下我所有的常量定义来避免这个警告:

 Tau = 2 * Pi unless defined?(Tau) 

但它不雅,有点潮湿( 不干 )。

有没有更好的方法def_if_not_defined ? 以及如何redef_without_warning

感谢Steve的解决scheme:

 class Object def def_if_not_defined(const, value) mod = self.is_a?(Module) ? self : self.class mod.const_set(const, value) unless mod.const_defined?(const) end def redef_without_warning(const, value) mod = self.is_a?(Module) ? self : self.class mod.send(:remove_const, const) if mod.const_defined?(const) mod.const_set(const, value) end end A = 1 redef_without_warning :A, 2 fail 'unit test' unless A == 2 module M B = 10 redef_without_warning :B, 20 end fail 'unit test' unless M::B == 20 

这个问题很老。 上面的代码只对Ruby 1.8是必需的。 在Ruby 1.9中,P3t3rU5的答案不会产生任何警告,只是更好。

以下模块可以做你想做的事情。 如果不是,它可能会提供一些指向您的解决scheme

 module RemovableConstants def def_if_not_defined(const, value) self.class.const_set(const, value) unless self.class.const_defined?(const) end def redef_without_warning(const, value) self.class.send(:remove_const, const) if self.class.const_defined?(const) self.class.const_set(const, value) end end 

并作为使用它的一个例子

 class A include RemovableConstants def initialize def_if_not_defined("Foo", "ABC") def_if_not_defined("Bar", "DEF") end def show_constants puts "Foo is #{Foo}" puts "Bar is #{Bar}" end def reload redef_without_warning("Foo", "GHI") redef_without_warning("Bar", "JKL") end end a = A.new a.show_constants a.reload a.show_constants 

给出以下输出

 Foo is ABC Bar is DEF Foo is GHI Bar is JKL 

原谅我,如果我已经打破了任何ruby的禁忌,因为我仍然得到了一些模块:类:在ruby内的Eigenclass结构

如果你想重新定义一个值,那么不要使用常量,而应该使用一个全局variables($ tau = 2 * Pi),但这也不是一个好习惯。 你应该把它变成一个合适的类的实例variables。

对于另一种情况, Tau = 2 * Pi unless defined?(Tau)是完全正确的,最具可读性,因此是最优雅的解决scheme。

另一种方法,使用$ VERBOSE来抑制警告,这里讨论: http : //mentalized.net/journal/2010/04/02/suppress_warnings_from_ruby/

除非常量的值是非常奇怪的(即你有常量设置nilfalse ),最好的select是使用条件赋值运算符: Tau ||= 2*Pi

如果它是nilfalse或未定义,则将Tau设置为2π,否则将其保留。

那么下面呢?

 TAU ||= 2 * Pi 

它在我正在工作的gem上工作。