如何重新定义一个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/
除非常量的值是非常奇怪的(即你有常量设置nil
或false
),最好的select是使用条件赋值运算符: Tau ||= 2*Pi
如果它是nil
, false
或未定义,则将Tau设置为2π,否则将其保留。
那么下面呢?
TAU ||= 2 * Pi
它在我正在工作的gem上工作。