模块中 Julia 宏中的表达式和变量的范围

Cha*_*ang 5 macros scope metaprogramming julia

出于某种原因,我不得不将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
Run Code Online (Sandbox Code Playgroud)

当宏被放入模块时,它不再起作用:

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
Run Code Online (Sandbox Code Playgroud)

它说:

ERROR: LoadError: UndefVarError: x not defined
Run Code Online (Sandbox Code Playgroud)

我想我应该把它放在esc某个地方,以评估ex模块外主作用域中的表达式。我应该怎么处理这个?

P i*_*P i 5

这里的问题是宏(在模块内)引用xx在该模块中查找,例如MyModule.x

这是宏观卫生的一部分。

为了防止发生宏观卫生,您需要esc(x)- 这意味着它将使用调用站点范围内的任何 x 。

您的完整解决方案可能如下所示:

macro addsum_out()
  quote
    esc(x) + esc(y)
  end
end
Run Code Online (Sandbox Code Playgroud)

或更简洁地说:

macro addsum_out()
  :(  esc(x) + esc(y)  )
end
Run Code Online (Sandbox Code Playgroud)

请注意,这与执行esc( :(x+y) )转义+函数略有不同。即包含此宏的模块可能包含 for 的重载+,如果您想使用它,则不要转义+,否则请执行!

在我整理的指南中对这个主题进行了一些讨论:https :
//github.com/pi-/MetaGuideJulia/wiki#example-swap-macro-to-illustrate-esc