2017-02-17 6 views
2

어떤 이유로 든 quote ... end 블록을 매크로에 넣고 ex을 프로그래밍 방식으로 생성해야했습니다. 이 코드는 작동합니다.모듈의 줄리아 매크로에서 표현식과 변수의 범위

macro addsum_out() 
    quote 
    ex = :(x+y) 
    sum(eval(ex)) 
    end 
end 

x = [1 1 1] 
y = [2 2 2] 

z2 = @addsum_out 

매크로가 모듈 내부에 넣어, 그것은 더 이상 작동하지 않습니다 :

module MyModule 

export @addsum 

macro addsum() 
    quote 
    ex = :(x+y) 
    sum(eval(ex)) 
    end 
end 

end 

using MyModule 
x = [1 1 1] 
y = [2 2 2]  
z = @addsum 

그것은 말한다 :

ERROR: LoadError: UndefVarError: x not defined 

내가 표현을 평가하기 위해, 어딘가 esc을 넣어해야한다고 생각 ex은 모듈 외부의 주요 범위에 있습니다. 이걸 어떻게 처리해야합니까?

+3

'eval' 매크로에서 사용할 수 없습니다 :

내가 조립 가이드에서이 주제에 대한 약간의 토론이있다. 너 뭐하려고? –

+2

'eval'은 모듈 전역 범위에서 작동합니다. 'macroexpand (: (@ addsum))'을보고'MyModule.eval'을 확인하십시오. 어쨌든, 그것은 완전히 불필요합니다. 대신'esc (:(x + y))'를 반환해야합니다. –

답변

4

여기서 문제는 x을 참조하는 매크로 (모듈 내부)가 해당 모듈에서 x을 검색한다는 것입니다. MyModule.x

이것은 macro hygiene의 일부입니다.

매크로 위생이 일어나지 않게하려면 esc(x)이 필요합니다. 즉, 호출 사이트에서 x가 범위 내에 있으면 무엇이든 사용합니다. 더 간결

macro addsum_out() 
    quote 
    esc(x) + esc(y) 
    end 
end 

나 :

당신의 완벽한 솔루션처럼 보일 수 이것은 또한 + 기능을 탈출 할 것이다 esc(:(x+y))을하고 약간 다르다는 것을

macro addsum_out() 
    :( esc(x) + esc(y) ) 
end 

참고. 즉이 매크로가 포함 된 모듈에 +에 대한 오버로드가 포함될 수 있으며이 경우 사용하려는 경우 +을 탈출하지 마세요. 그렇지 않으면 수행하십시오!
https://github.com/p-i-/MetaGuideJulia/wiki#example-swap-macro-to-illustrate-esc

+0

':($ (esc (: x)) + $ (esc (: y)))'를 의미합니다. – tim

+0

또는'esc (Expr (: call, +, : x, : y))'를 사용할 수 있습니다. – tim