Back

RUBY中重新定义常量(redefine constants in Ruby)

发布时间: 2012-07-24 07:09:00

有个需求:    生产环境中的代码, 有一个常量。
但是需要在测试环境中修改它,把它从一个真正的对象变成mock object.

(提示:核心方法:  const_set, const_defined? , remove_const )

所以搜索了一下,有这个文章:
( http://stackoverflow.com/a/3377188/445908 )

先定义这个module
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


下面是我自己的代码:

class Apple
  COLOR = "red"
end

puts Apple::COLOR
puts "const_defined?  #{Apple.const_defined?("COLOR")}"
Apple.send(:remove_const, 'COLOR')

# 三种不同的方法,都是定义常量
Apple.class_eval {        COLOR = "yellow"   }
#class Apple;   COLOR="yellow"  ; end
#Apple.const_set("COLOR", "green")
puts Apple::COLOR


运行结果:

引用
red
const_defined?  true
yellow



Back