我如何暂时使用全局模块常量?

时间:2010-05-27 19:23:31

标签: ruby-on-rails ruby metaprogramming

问候,

我想修改全局memcache对象,我发现了以下问题。

  1. 缓存是常量
  2. 缓存是一个模块
  3. 我只想为一小段代码全局修改Cache的行为,以获得可能的主要性能提升。

    由于Cache是​​一个模块,我无法重新分配或封装它。

    我想这样做:

    深入控制器方法......

    code code code...
    
    old_cache = Cache
    Cache = MyCache.new
    
    code code code...
    
    Cache = old_cache
    
    code code code...
    

    但是,由于Cache是​​常量,我禁止更改它。线程目前不是问题。 :)

    对我来说,只需alias_method我需要的特殊代码就是“礼貌” 只是为了一小部分代码然后再将它取消了吗?事实并非如此 通过气味测试恕我直言。

    有没有人有任何想法?

    TIA,

    -daniel

1 个答案:

答案 0 :(得分:3)

但你可以覆盖Ruby中的常量(无论它是模块还是类或简单的其他对象):

MyConst = 1

# do stuff...

old_my_const = MyConst
MyConst = 5
puts "MyConst is temporarily #{MyConst}"
MyConst = old_my_const

puts "MyConst is back to #{MyConst}"

输出:

a.rb:6: warning: already initialized constant MyConst
MyConst is temporarily 5
a.rb:8: warning: already initialized constant MyConst
MyConst is back to 1

警告只是:警告。您的代码将继续运行。

好吧,由于某种原因,警告可能在您的情况下是不可接受的。使用此suppress_all_warnings method I've written。示例包括重新分配模块。

def suppress_all_warnings
  old_verbose = $VERBOSE
  begin
    $VERBOSE = nil
    yield if block_given?
  ensure
    # always re-set to old value, even if block raises an exception
    $VERBOSE = old_verbose
  end
end

module OriginalModule
  MyConst = 1
end

module OtherModule
  MyConst = 5
end

def print_const
  puts OriginalModule::MyConst
end

print_const

suppress_all_warnings do
  old_module = OriginalModule
  OriginalModule = OtherModule

  print_const

  OriginalModule = old_module
end

print_const

现在您获得了正确的输出,但没有警告:

1
5
1