Select the same method from different modules

Reposting this from the #helpdesk channel on Slack

I am playing with a way of controlling which module a module should import some function from. Here’s an MWE:

module Mod1
foo() = "success"
export foo
end

module Mod2
sym = :foo
mod = :Mod1

@eval import $(mod)
@eval $(sym)() = $(Symbol(mod, :., sym))()
@eval export $(sym)
end

So Mod2, in theory, takes a function and passes that function to the module signified by mod. The problem is, it doesn’t work:

julia> using Mod2

julia> foo()
ERROR: UndefVarError: Mod1.foo not defined
Stacktrace:
 [1] foo() at ./REPL[2]:6

julia> Mod1.foo
foo (generic function with 1 method)

Mod1.foo appears to not be defined in the eval-context, though it is defined at the REPL.

The context is that I am looking into ways to change how backends are handled in Plots.

This works

module Mod2
    sym = :foo
    mod = :Mod1

    @eval import $(mod)
    @eval foo = $(Expr(:(.),mod,QuoteNode(sym)))
    @eval export $(sym)
end

It generates foo = Mod1.foo instead of foo() = begin Mod1.foo() end.

2 Likes

If you want to preserve your original functional relationship, you can also do

@eval $(sym)() = getfield($(mod),sym)()
1 Like

Amazing :tada: :heart: