2010-05-27 2 views
0

Привет,Как временно обезьяна с глобальной константой модуля?

Я хочу поработать с глобальным объектом memcache, и я нашел следующие проблемы.

  1. Cache является постоянным
  2. Cache представляет собой модуль

Я только хочу, чтобы изменить поведение кэша глобально для небольшой части коды для возможного крупного выигрыша в производительности.

Поскольку Cache - это модуль, я не могу его повторно назначить или инкапсулировать.

Я хотел бы сделать это:

Deep в методе контроллера ...

code code code... 

old_cache = Cache 
Cache = MyCache.new 

code code code... 

Cache = old_cache 

code code code... 

Однако, поскольку кэш является постоянным мне запрещено менять. На данный момент нить не является проблемой. :)

Было бы «хорошими манерами» для меня, просто для alias_method специальный код мне нужен только для небольшой части кода, а затем он еще раз откажется от него? Это не пройти тест запаха ИМХО.

У кого-нибудь есть идеи?

ТИА,

-daniel

ответ

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 
+0

Ах, я вижу, что происходит. Я пытался заменить константу экземпляром класса, таким образом, я получил ошибку «динамического постоянного назначения». – Daniel

Смежные вопросы