我正在运行一些Ruby代码,每当Ruby文件的日期发生变化时,都会对其进行判断.在文件中,我有恒定的定义,比如

Tau = 2 * Pi

当然,它们会让解释器每次都显示不需要的"已初始化常量"警告,因此,我想有以下功能:

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

我可以这样写我所有的固定定义来避免警告:

Tau = 2 * Pi unless defined?(Tau)

但它不雅观,有点湿(不是DRY).

有更好的办法达到def_if_not_defined分吗?那么如何使用redef_without_warning呢?

--

感谢Steve的解决方案:

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的答案不会产生任何警告,只是更好.

推荐答案

以下模块可能会执行您想要的操作.如果没有,它可能会为您的解决方案提供一些指导

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中的一些模块:类:特征类 struct

Ruby相关问答推荐

ASDF 上缺少 Ruby 版本

在Ruby中将嵌套哈希键从CamelCase转换为snake_case

使用 Homebrew 安装 Ruby

Ruby 中的关联数组

如何从最后一个元素开始遍历数组?

格式化 Ruby 的漂亮打印

卸载所有 gem Ruby 2.0.0

Ruby 中的方法: objects与not?

如何引用全局变量和类变量?

Ruby CSV - 获取当前行/行号

很好地格式化输出到控制台,指定选项卡的数量

计算文件中的行数而不将整个文件读入内存?

Ruby 删除目录

如何判断变量是数字还是字符串?

解析带有标题字段的 CSV 文件作为每行的属性

class << self vs self.method with Ruby:什么更好?

obj.nil?与 obj == nil

Ruby:是否可以在模块中定义类方法?

如何在Ruby中将字符串拆分为仅具有给定字符的两部分?

Ruby 中的那些管道符号是什么?