名前空間付き定数対応のObject.cost_set
Object.const_getをハックした話 を参考に、Object.const_setもモジュールによる名前空間付き定数に対応させてみた。車輪の再発明をした気がしなくはないけど、そこは気にしない。
class Object
def self.nested_const_get(name)
stack = (name.is_a?(Array)) ? name : name.split("::")
klass = Object
while const = stack.shift
klass = klass.const_get(const)
end
return klass
end
def self.nested_const_set(args = {})
args.each do |name, value|
stack = (name.is_a?(Array)) ? name : name.to_s.split("::")
last_const = stack.pop
klass = nested_const_get(stack)
klass.const_set(last_const, value)
end
end
end
使い方は、
Object.nested_const_set("Foo::Bar" => "foooo")
RSpec: Stubbing RAILS_ENV and other constantsのように、一時的に定数を換えたいという場合に使えると思う。
ただしまだテストはしていない :)