Edit: In the category of “never mind…” , the example below does not accurately replicate the problem.
My apologies to those who took time to consider it.
Consider
macro x(expr)
dump(expr)
println("------")
dump(expr.args[1])
println("======")
expr.args[1] = :z
end
julia> @x y()
Expr
head: Symbol call
args: Array{Any}((1,))
1: Symbol y
typ: Any
------
Symbol y
======
UndefVarError: z not defined
Why is expr
evaluated when expr.args[1] = :z
?
In a macro
the return expression is evaluated. So the last line of code expr.args[1] = :z
is the return value of the macro, and therefore :z
is the expression that is evaluated.
Indeed. In Jupyter the following works.
z()="hello world"
macro x(expr)
dump(expr)
println("------")
dump(expr.args[1])
println("======")
expr.args[1] = :z
end
julia> @x y()
Expr
head: Symbol call
args: Array{Any}((1,))
1: Symbol y
typ: Any
------
Symbol y
======
Out[1]:
z (generic function with 1 method)
But…
Module MyModule
z()="hello world"
macro x(expr)
dump(expr)
println("------")
dump(expr.args[1])
println("======")
expr.args[1] = :z
end
export @x, z
end
julia> using MyModule
julia> @x y()
UndefVarError: MyModule.z not defined
When I try out both examples, I get the same result for both and no error.
julia> using MyModule
julia> @x y()
Expr
head: Symbol call
args: Array{Any}((1,))
1: Symbol y
typ: Any
------
Symbol y
======
z (generic function with 1 method)
When I run that, I don’t get the same UndefVarError
you got, I get same result as first example.
Hmm…
Thank you for looking into this.
To be continued tomorrow…
Just a sanity check. This
looks like a complicated way to write
macro x(expr)
return :z
end
Did you mean
macro x(expr)
expr.args[1] = :z
return expr
end
?
2 Likes
@chakravala and @GunnarFarneback, thank you for trying to help out. Unfortunately my “Minimum Working Example” did not accurately recreate the problem. My apology.
Based on your feedback I dug deeper and the actual problem was not where I thought it was. There was another statement (not in the MWE) that evaluated expr.args[1] before returning it. Therefore the evaluation occurred in the wrong context. Problem solved.