2013-02-18 3 views
3

루비로 확장 할 수있는 애플리케이션이 있습니다. 스크립트는 응용 프로그램 자체에서 만들 수 있으며 편집 할 때마다 다시로드됩니다. 따라서 사용자가 클래스에 메서드를 추가하면 즉시 적용됩니다. 사용자가 메서드를 제거한 것처럼 수정 된 파일을 실행할 수는 없습니다. 유일한 옵션은 인터프리터의 상태를 지우고 모든 스크립트를 다시로드하는 것입니다. 그러나 루비는 다시 시작에 대해 자신을 보호 : (eval.c)임베디드 루비 인터프리터의 상태를 리셋

void ruby_init(void) 
{ 
    int state = ruby_setup(); 
    if (state) { 
     error_print(); 
     exit(EXIT_FAILURE); 
    } 
} 

int ruby_setup(void) 
{ 
    static int initialized = 0; 
    int state; 

    if (initialized) 
     return 0; 
    initialized = 1; 

    /* ... */ 

    return state; 
} 

나는 또한 루비를 추적하고, GC 휴식 스택 위치에 문제가 발생할 수 있습니다 ruby_init() 여러 번 호출 생각합니다. GUI 인터페이스가 있으므로 전체 응용 프로그램을 다시 시작하는 것은 옵션이 아닙니다. 또한 분리 된 프로세스에서 모든 루비 항목을 유지하는 것은 응용 프로그램에 새로운 GUI 요소를 삽입하는 Qt 인터페이스가 노출되어 있기 때문에 고통 스러울 것입니다. 또 다른 옵션은 코드를 다시 실행하기 전에 모든 정의 된 메소드, 클래스, 상수 등을 어떻게 든 추적하고 undef합니다. 간단한 방법이 있습니까?

답변

2

예, 있습니다! (이것은 당신이 다른 루비 코드를로드하는 일부 루비 코드를 사용해야합니다) (내 생각) :

$current_env = nil 

def reload(code) 
    $current_env = Module.new 
    $current_env.module_eval(code) 
end 

예, 그것의 단순있다. 당신이 모듈로 플러그인, 바로 액세스 $의 current_env에서 사물에 액세스해야 할 때마다 : reload 할당이 해제 된 다음에 추가로 액세스 할 수 없게 호출 될 때 대체합니다 있습니다

$current_env::ExtensionClass.extension_thing 

오래된 클래스 물건을 GC는 주변에 도착 .

관련 문제