Importing modules from function

Hi,

I’m working on a project at the moment that involves many packages and modules, as well as many different files. I have a “setup.jl” file that adds all the packages (Pkg.add("Pkg_name"); using Pkg_name;) and includes all the files (include("./filename")). That way, I can simply start Julia and run the command include("setup.jl") and I can use all of the code.

I however don’t like how I import packages. Essentially, I am using a try-catch system, where I try using Pkg_name and the catch is Pkg.add("Pkg_name"); using Pkg_name. I would like to call a function which would do that for me. That way, I wouldn’t have to write the try-catch for every package and I could simply write a for loop that goes through all the packages and imports them. The problem is with “using” because it uses a package identifier and I’m not sure how to convert a string (the package name) into a package identifier. I tried using $Pkg_name, as well as using Symbol(Pkg_name) but both do not work. Here is what I have in mind in a nutshell:

# Function to import packages
function use_pkg( pkg_name )
    try
        using pkg_name;
    catch err;
        Pkg.add("pkg_name");
        using pkg_name;
    end
end

# Defining list of packages to import
pkg_list = ["CSV", "Random", "Plots"]; # There would be more packages of course

# Importing all packages
for i = 1:length( pkg_list )
    if !in( pkg_list[i], keys( Pkg.installed( ) ) )
        use_pkg( pkg_list[i] );
    end
end

Does anyone have any idea on how to do this?

Debug info

Julia Version 1.0.0
Commit 5d4eaca0c9 (2018-08-08 20:58 UTC)
Platform Info:
OS: Windows (x86_64-w64-mingw32)
CPU: Intel® Core™ i7-4710HQ CPU @ 2.50GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.0 (ORCJIT, haswell)

As you’ve found, you can’t quite do it this way because using is forbidden inside functions. Instead it’s limited to top level so that the compiler can generate efficient function code without having to worry that new functions will be added while a function is running. There’s ways to do what you’re imagining in this particular case by hacking around this design feature.

However, if you just want a nice way to make sure that all packages are installed in your project it’s much better to use Pkg itself which has builtin support for creating environments with a well defined set of packages. Here’s the documentation: https://julialang.github.io/Pkg.jl/v1/environments/#Creating-your-own-projects-1

Once you’ve set up an environment for your project I suggest you add Project.toml to your source control and start julia with the --project=$project_dir. See https://stackoverflow.com/questions/53613663/what-is-in-julia-project-command-line-option for a nice explanation of --project.

2 Likes

Awesome! Thanks for the quick response. I’ll take a look at that :slight_smile: