Using symbols from parent module without naming it

How about this: @.. c (or @.. c d e - if you need to import multiple symbols).

The macro definition here:

macro (..)(s...)
    Expr(:using,
        Expr(:(:), Expr(:., :., :., Symbol(nameof(parentmodule(__module__)))),
            (Expr(:., (Symbol(x))) for x in s)...))
end

In your context:

module Foo
const c = 1
const d = 2
module Bar

macro (..)(s...)
    Expr(:using,
        Expr(:(:), Expr(:., :., :., Symbol(nameof(parentmodule(__module__)))),
            (Expr(:., (Symbol(x))) for x in s)...))
end

# works with importing multiple symbols
@.. c d

fc() = c
fd() = d

@info "happy import: " fc() fd()

end
end

Running the program would produce:

┌ Info: happy import: 
│   fc() = 1
└   fd() = 2

Not sure if this is reliable enough for any context (limited testing) - I am sure it can be improved.

Later edit: the initial version only worked if the macro was defined inside the calling module. The current version of the macro works even if defined in module X and invoked from Y (it will still import symbols from the parent of Y).

LE2: renamed it for more convenience. You can invoke it by @.. c d e f g.

3 Likes