2012-06-14 2 views
2

코드 변경 후 최신 버전의 코드가 사용되도록 모듈에서 로컬 함수를 호출하는 방법을 모르겠습니다.얼랭 코드 변경 및 로컬 함수 호출

예 :

1 -module(test). 
2 
3 -export([start/0, call/1]). 
4 -export([loop/0, add/1]). 
5 
6 start() -> 
7  register(foo, spawn(test, loop, [])). 
8 
9 call(X) -> 
10  foo ! {self(), X}, 
11  receive 
12   Y -> Y 
13 end. 
14 
15 loop() -> 
16  receive 
17   {Pid, Z} -> Pid ! add(Z) 
18  end, 
19  loop(). 
20 
21 add(N) -> 
22  N + 1. 

변경 될 add\1 함수이다. 함수의 최신 버전을 사용하려면 add/1 (17 행)의 호출은 정규화 된 함수 호출 {Pid, Z} -> Pid ! ?MODULE:add(Z)이어야합니다.

1> c(test). 
{ok,test} 
2> test:start(). 
true 
3> test:call(1). 
2 

라인 (22) N + 2

4> c(test).  
{ok,test} 
5> test:call(1). 
3 

라인 (22)으로 변경 나는이 오류가 이유는 무엇입니까 N + 3

6> c(test).  
{ok,test} 
7> test:call(1). 
** exception error: bad argument 
    in function test:call/1 (test.erl, line 10) 

로 다시 변경 : 내가 그것을하려고 할 때,이 얻을?

답변

3

새로운 모듈을로드하고 사용하려면 add/1 함수 대신 loop/0 함수의 정규화 된 버전을 호출해야한다고 생각합니다. 코드 로딩 메커니즘은 한 번에 두 모듈의 실행 버전을 처리 할 준비가되어 있으며, N+3의 예제는 세 번째 모듈로드이며 첫 번째 버전은 강제로 제거됩니다. 나는 loop/0의 다음 실행에 최신 버전을 다시로드를 변경했습니다

15 loop() -> 
16  receive 
17   {Pid, Z} -> Pid ! add(Z) 
18  end, 
19  ?MODULE:loop(). 

:

대신이 루프를 사용해보십시오.

나는 모든 요청에 ​​대해 모듈을 지속적으로 다시로드하는 오버 헤드를 피하기 위해 직접적으로 메인 루프를 직접 호출하는 reload 메시지 또는 비슷한 것을 사용하는 것이 더 일반적이라고 생각합니다.

+0

감사합니다. 그래서 'loop/1'은 변경되지 않았고 세 번째 변경 후에는 지워졌습니다. 그러나 왜 아직도'? MODULE : loop()'이 새로운 버전의 add/1을로드하고 왜'? MODULE : add()'가'loop/1'을 사용하지 않는지 이해하지 못합니다. . – juro

+0

트릭이'? MODULE : add()'가 완료까지 실행되고 그 모듈이 증발 할 것이라고 생각합니다. 이 모듈에서 수천 개의 프로세스가 실행 중일 수 있으며 변경하고자하는 코드 만 변경할 수는 없다는 것을 잊지 마십시오. – sarnold

+2

코드 대체에 대한 문서는 다음과 같습니다. Erlang - 편집 및 코드로드 http://www.erlang.org/doc/reference_manual/code_loading.html#id83918 – shino