Dynamically constructing a using statement

I think it should be doable with @eval but I’m stuck at the moment… I have a set of packages in an array and I’d like to run a using statement on them. My first attempt of constructing a comma-delimited string doesn’t work…

julia> x = ["BenchmarkTools", "Plots"]
2-element Array{String,1}:
 "BenchmarkTools"
 "Plots"

julia> pkgs = join(x, ",")
"BenchmarkTools,Plots"

julia> @eval using $pkgs
ERROR: TypeError: import or using: expected Symbol, got String
Stacktrace:
 [1] eval(::Module, ::Expr) at ./sysimg.jl:23

x = [:BenchmarkTools, :Plots]
e = Expr(:toplevel, map(x → Expr(:using, x), x)…)
eval(e)

2 Likes

@bramtayl’s answer should be helpful, but can you give a bit more context? Why are you trying to do this? Depending on the objective, perhaps there is a simpler way of achieving it.

I’m trying to force precompilation of all packages so that the package images are written then I can fix the Unix file permissions… I think I submitted another post some time ago regarding the file permission problem. So this is really a workaround.

I see. You may be interested in these comments:
https://github.com/JuliaLang/julia/issues/16409#issuecomment-228873060
and
https://github.com/JuliaLang/julia/issues/16409#issuecomment-242360802

1 Like

Use symbols instead of strings in x then just do

for pkg in x
    @eval using $pkg
end
3 Likes

I am still newbie but would try something like this:

    for pkg in x
        try
            info("importing: $pkg")
            @eval import $(Symbol(pkg))
            # next line you probably want to change file permission 
            run(Cmd(["ls", "-la",  joinpath(replace(Pkg.dir(), ".julia", ".julia/lib"), pkg*".ji")]))
        catch e
            println("$e")
        end
    end

import could probably avoid some name clash problems…

run(Cmd(…)) is not the best (replace is ugly hack too) and you’ll very probably find better way. :slight_smile: