2010-05-27 5 views
0

인사말,어떻게 글로벌 모듈 상수로 일시적으로 원숭이합니까?

전역 memcache 개체를 고치고 싶습니다. 다음과 같은 문제점을 발견했습니다.

  1. 캐시는 일정한
  2. 캐시 나는 단지 가능한 주요 성능 향상을위한 코드의 작은 부분에 대해 전역 캐시의 동작을 수정하려는 모듈

입니다.

캐시가 모듈이기 때문에 다시 할당하거나 캡슐화 할 수 없습니다.

나는이 작업을 수행하는 싶습니다 그러나

code code code... 

old_cache = Cache 
Cache = MyCache.new 

code code code... 

Cache = old_cache 

code code code... 

컨트롤러 방법에 깊은

을 ..., 캐시 내가 그것을 변경 금지하고있어 일정한 때문이다. 스레딩은 현재 문제가 아닙니다. :)

"좋은 매너"내가 단지코드의 작은 부분에 대해서만 필요한 특수 코드를 alias_method하고 나중에 다시 unalias하는 것이 좋을까요? 그건 냄새 테스트 IMHO를 통과하지 않습니다.

누구에게 아이디어가 있습니까?

TIA,

다니엘

답변

3

하지만 (관계없이 모듈 또는 클래스 또는 간단한 다른 물체인지의) 루비 상수를 덮어 쓸 수 있습니다 :

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

아, 무슨 일이 있었는지를 참조하십시오. 저는 Constant를 클래스의 인스턴스로 대체하려고 했으므로 "동적 상수 할당"오류가 발생했습니다. – Daniel

관련 문제