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

时间:2017-02-17 13:40:22

标签: scope macros 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

将宏放入模块时,它不再有效:

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。我该怎么办呢?

1 个答案:

答案 0 :(得分:4)

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

这是macro hygiene的一部分。

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

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

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

或更简洁:

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

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

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