Calling function of included file


#1

I’m looking to include load some files dynamically and then call a function on the newly created file.

here is the file I’m trying to include

module SetupModule

function setup()
    println("------------setup called")
# end module
end

Here is the module calling setup()

function registerFactory()
    factoryPaths::Array{String} = ioAntigenFS.getPathsBySufffix("./core/factories", "Factory.jl")
    for path in factoryPaths
        @debug ("Including path: " * path)
        include(path)
        setup()
    end
end

So when I try to run the setup() function of the SetupModule from the registerFactory function I see the below error.

ERROR: LoadError: UndefVarError: setup not defined

From what I read, include just included the file verbatim, so the function should be in scope.

If I remove the module declaration from the SetUp module then I see a different error.

(method too new to be called from this world context.)

Wondering if there is a way to include a Julia source file and execute one of it’s functions.


#2

The file you are including defines a module with the setup function inside.

Therefore you should be using the fully qualified function name, that is SetupModule.setup to invoke it.


#3

I’ve made the suggested modifications, but in order to get them to work I have to use the @eval macro.

The docs just say that @eval evaluates an expression. Does this mean that include brings in the source code of a file unevaluated, and it has to be evaluated manually?

function registerFactory()
    factoryPaths::Array{String} = ioAntigenFS.getPathsBySufffix("./core/factories", "Factory.jl")
    for path in factoryPaths
        @debug ("Including path: " * path)
        include(path)
        @eval(SetupModule.setup())
    end
end

#4

No, you’re essentially running into https://docs.julialang.org/en/v0.7.0/manual/methods/#Redefining-Methods-1 . The methods defined when you include() something are “too new”, just like the @eval newfun() = 1 definition in the example from the documentation. The solution from the documentation will also work here: you should be able to do something like:

...
include(path)
Base.invokelatest(SetupModule.setup)
...

#5

You hit the nail on the head.
The error makes sense now.