Как временно обезьяна с глобальной константой модуля? - PullRequest
0 голосов
/ 27 мая 2010

Привет,

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

  1. Кэш-константа
  2. Кеш это модуль

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

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

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

Глубоко в методе контроллера ...

code code code...

old_cache = Cache
Cache = MyCache.new

code code code...

Cache = old_cache

code code code...

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

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

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

ТИА

-daniel

1 Ответ

3 голосов
/ 27 мая 2010

Но вы можете перезаписать константы в 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 метод, который я написал . Пример включает переназначение модуля.

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
...