Macro behavior depends on method of code loading?

I have two identical versions of a macro that prints all exported names of a given module. One version is imported from a package; the other is defined globally. The former fails while the latter succeeds. What am I doing wrong?

The package:

module JuliaUtils

macro modulenames_from_package(module_) 
    return quote 
        names($module_)
    end 
end 

end 

The REPL:

using JuliaUtils:  @modulenames_from_package
using Example 

macro modulenames_global(module_) 
    return quote 
        names($module_)
    end 
end 

julia> @modulenames_global Example  # works 
3-element Array{Symbol,1}:
 :Example
 :domath
 :hello

julia> @modulenames_from_package Example # FAILS -- why???
ERROR: UndefVarError: Example not defined
Stacktrace:
 [1] top-level scope at /home/elliot/proj/cluster/JuliaUtils/src/JuliaUtils.jl:11

I am pretty sure this is because of macro hygine
and that you need

macro modulenames_global(module_) 
    return quote 
        names($(esc(module_))
    end 
end 

and that that will work the same no matter if it is invoked from the module it was defined in, vs being invoked from another module.

I don’t have a good way of explaining why this is the case though.

1 Like

Thanks, and congratulations on the speediest response ever!