Julia 宏中的可变范围问题

Julia 宏中的可变范围问题,julia,Julia,我有一个宏工程,如果在主要定义 macro check_set(d,v) nm = string(v) quote global $v if haskey($d,$nm) $v = $d[$nm] end end end 但是,当我把它放在一个模块(在模块内定义的宏)中,以便在一个函数(也在模块内定义)中使用时,我会遇到范围问题 export setVars function setVars(va

我有一个宏工程,如果在主要定义

macro check_set(d,v)
    nm = string(v)
    quote
        global $v
        if haskey($d,$nm)
            $v = $d[$nm]
        end
    end
end
但是,当我把它放在一个模块(在模块内定义的宏)中,以便在一个函数(也在模块内定义)中使用时,我会遇到范围问题

export setVars

function setVars(val::Dict)
   global max_iter
   @check_set val max_iter
end
在main中,我调用
setVars(config)
其中
config
是预期的字典。我得到:

错误:未定义val错误:未定义val

添加
@macroexpand
我看到了:

begin
    #= /home/dpazzula/Documents/Stuff/src/Stuff.jl:156 =#
    global max_iter
    #= /home/dpazzula/Documents/Stuff/src/Stuff.jl:157 =#
    if Stuff.haskey(Stuff.val, "max_iter")
        #= /home/dpazzula/Documents/Stuff/src/Stuff.jl:158 =#
        Stuff.max_iter = Stuff.val["max_iter"]
    end
end
因此,当
val
的作用域局限于函数时,错误是查找
Stuff.val

如何让它查找本地范围的
val

您的问题与之相关。在您的情况下,由于希望
d
v
引用宏调用环境范围内的变量名,因此必须使用

下面是一个与您所写内容大致相同的示例:

module Stuff

macro check_set(d,v)
    nm = string(v)
    d = esc(d)
    v = esc(v)
    quote
        global $v
        if haskey($d,$nm)
            $v = $d[$nm]
        end
    end
end

end #module Stuff
我们可以检查这是否扩展到预期的范围:

julia> @macroexpand Stuff.@check_set val max_iter
quote
    #= REPL[1]:8 =#
    global max_iter
    #= REPL[1]:9 =#
    if Main.Stuff.haskey(val, "max_iter")
        #= REPL[1]:10 =#
        max_iter = val["max_iter"]
    end
end
并且它在运行时的行为也符合预期:

julia> function setVars(val::Dict)
           Stuff.@check_set val max_iter
       end
setVars (generic function with 1 method)

julia> config = Dict("max_iter" => 42)
Dict{String,Int64} with 1 entry:
  "max_iter" => 42

julia> setVars(config)
42

julia> max_iter
42