TomS
TomS

Reputation: 290

How to load modules (or scripts) dynamically at runtime with Julia 1.5

I was wondering whether it is possible to define modules (or scripts)

# SomeName.jl

module SomeName
export worker()

function worker()
    println( @__FILE__ )
    ...
    return
end

and

# SomeOtherName.jl

module SomeOtherName
export worker()

function worker()
    println( @__FILE__ )
    ...
    return
end

to load them dynamically and to call their standard worker functions like

function foo() 
    ...
    modname = "SomeName"    # in practice we would call something like retrievename() 
    mod = import( modname ) # imports the module (or includes the script)
    
    mod.worker()            # calls the worker function
end

The functionality should be similar to dynamic loading with Libdl.dlopen(), Libdl.dlsym() on LINUX or LoadLibrary(), GetProcAddress() on Windows. But I guess for Julia it may be even more elegant.

It would be interesting to learn this for both modules and scripts.

Upvotes: 2

Views: 383

Answers (1)

Przemyslaw Szufel
Przemyslaw Szufel

Reputation: 42214

You can do that but it is a bad idea given how Julia is combining compilation with multiple dispatch.

Suppose you have the following file:

shell> more Foo3.jl
module Foo3
    export hello
    hello() = "hello3"
end

Now you can have the following function:

function foo(m::AbstractString)
    include(m * ".jl")
    Main.eval(Meta.parse("using Main.$m"))
    mod = getfield(Main, Symbol(m))
    Base.invokelatest(mod.hello)
end

Note that in that case it is not possible to simply compile the foo function and hence we had to use Base.invokelatest.

Now you can test it:

julia> foo("Foo3")
"hello3"

I would normally load all modules (having them as Julia packages) and then select the dynamically as in the example below:

julia> getfield(Main, Symbol("Foo3")).hello()
"hello3"

Upvotes: 2

Related Questions