In 0.6 I have a macro that evaluates an assignment if any of the left-hand-side variables is undefined. In Julia 0.7 I get a depwarn that urge me to change the call of isdefined
to @isdefined
. But @isdefined
only accept a symbol rather than a variable refering to a symbol.
using MacroTools
"""@maybe a,b,c=svdfact(randn(10000,10000))"""
macro maybe(ex)
@assert @capture(ex, ((lhs1_,lhss__)|lhs1_)=rhs_)
lhs = [lhs1]
lhss != nothing && append!(lhs, lhss)
# lhs = [:v1, :v2, ...] a vector of left-hand-side symbols
return quote
local really = false
for v in $lhs
isdefined(v) || (really = true; break) # @isdefined v does not work here
end
really && $(esc(ex))
end
end
In Julia 0.6, this macro only works in global scope. I only use this macro in repl/scripts so there is no problem. Now that @isdefined
works for bindings in local scope, which is very nice, how should I construct the return expression of the macro?
From the implementation of @isdefined(s)
I see that it simply translates to Expr(:isdefined, esc(s))
. That makes :isdefined
look like as special as :call
, :function
and :ref
. I am not knowledgeable enough to understand this magic. Could you provide some pointers so that I can learn about it?