I have this example code and I do not get why it does not work in function test
macro dump(arg)
return :(println("dump", $arg))
end
a = 1
@dump a
function test()
b = 2
@dump b
end
test()
I have this example code and I do not get why it does not work in function test
macro dump(arg)
return :(println("dump", $arg))
end
a = 1
@dump a
function test()
b = 2
@dump b
end
test()
This is macro hygiene at work. Macros need to be careful about what the names they use actually reference. For example, within function test
, you could also have a variable named println = 3
. If the macro tried to literally splice in the expression println("dump", b)
, then it’d try to use 3
as the function and try to call it. So instead it uses “hygiene” to ensure that the println
the macro inserted actually referenced the thing the macro wanted it to.
The way macros opt-out of this hygeine is with the esc
function. In this case, you want the arg
to be evaluated in the namespace of the caller, so you remove the hygiene for it:
macro dump(arg)
return :(println("dump", $(esc(arg))))
end
This will now work as you expected within functions and in other modules. Hopefully you can also now see why your initial version worked at global scope — both the macro and the caller are in the same namespace!
Thank you very much!