【问题标题】:'UndefVarError: x not defined' when calling a macro outside of its module (Julia v1.1)'UndefVarError: x not defined' 在其模块之外调用宏时(Julia v1.1)
【发布时间】:2019-01-29 09:22:07
【问题描述】:

我正在尝试编写一个宏来调用同一模块中定义的函数(使用 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]))

【问题讨论】:

    标签: julia


    【解决方案1】:

    您只需要escape 传入宏的变量即可:

    macro add_variable(model, var)
        quote
            add_variable($(esc(model)), $(string(var)), $(esc(var)))
        end
    end
    

    宏中的所有名称都在其定义的模块的上下文中解析,除非你 esc 他们 - 使用 esc 它们在调用者的上下文中解析。你几乎总是想esc 宏的参数。不过,像 add_variable 这样的名称,您希望在定义宏本身的位置解析。

    【讨论】:

    • 有效!它是如此简单......非常感谢您的帮助和清晰的解释!
    猜你喜欢
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 2017-04-01
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多