我正在尝试编写一个宏,该宏调用在同一模块(Julia v1.1)中定义的函数。我总是得到ERROR: LoadError: UndefVarError: myModel not defined
。
该模块的代码如下(Models.jl):
module Models
export Model
export createmodel
export add_variable
export @add_variable
mutable struct Model
variable_symbols::Dict{String, Symbol}
variable_data::Dict{Symbol, Array{Int64, 1}}
Model(; variable_symbols = Dict([]), variable_data = Dict([])) =
new(variable_symbols, variable_data)
Model(variable_symbols, variable_data) = new(variable_symbols,
variable_data)
end
function createmodel()
model = Model()
return model
end
function add_variable(model, label::String, value::Array{Int64, 1})
symbol = Symbol(label)
model.variable_symbols[label] = Symbol(symbol)
model.variable_data[symbol] = value
end
macro add_variable(model, var)
quote
add_variable($model, $(string(var)), $var)
end
end
end
该宏的调用方式如下:
include("Models.jl")
using .Models
x = [1, 2, 3]
myModel = createmodel()
@add_variable(myModel, x)
show(myModel)
我知道这是一个逃避/卫生的问题,但是尝试了许多想法之后,我没有得到预期的结果。到目前为止,获得预期结果的唯一方法是在模块外部定义宏以获取:Model(Dict("x"=>:x), Dict(:x=>[1, 2, 3]))
答案 0 :(得分:2)
您只需要esc
ape传递给宏的变量:
macro add_variable(model, var)
quote
add_variable($(esc(model)), $(string(var)), $(esc(var)))
end
end
除非在宏中使用esc
,否则将在其定义的模块的上下文中解析宏中的所有名称-使用esc
在调用者的上下文中解析它们。您几乎总是想esc
宏的参数。不过,诸如add_variable
之类的名称要在定义宏本身的位置进行解析。