Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Elixir script load all modules in folder recursivelly

Tags:

elixir

I want to compile and load all modules recursivelly in specific folder. I know I can do this with Mix project

iex -S mix run

Which will load all files in lib/ directory.

However I want the same behaviour in non-Mix script - programmaticly if it's possible. Something like Code.compile_all("directory/")
Is there any API like that?

like image 974
Krzysztof Wende Avatar asked Apr 16 '15 16:04

Krzysztof Wende


2 Answers

Just to clarify the terms: Mix does not load the files in lib/, it compiles them if needed, and then uses the compiled byte code (without having to execute the whole file again).

You can load any file in a directory by calling Code.require_file/1 or Code.load_file/1 but that does not generate any artifact in disk. If later on you call Code.require_file/1, the same files will be evaluated again, which may take time. The idea of compiling is exactly so you don't pay this price every time.

That said, let's answer your question directly.

  1. A way to load everything in a directory is:

    dir
    |> Path.join("**/*.exs")
    |> Path.wildcard()
    |> Enum.map(&Code.require_file/1)
    
  2. If you want to compile them, use:

    dir
    |> Path.join("**/*.ex")
    |> Path.wildcard()
    |> Kernel.ParallelCompiler.files_to_path("path/for/beam/files")
    
  3. If you want to just compile another directory in the context of a project (with a mix.exs and what not), you can give any directory you want to Mix inside def project:

    elixirc_paths: ["lib", "my/other/path"]
    

That's it.

like image 149
José Valim Avatar answered Oct 02 '22 14:10

José Valim


I'm not sure about built-in ways to do this in Elixir, but you could achieve the same result using something like filelib:fold_files/5 from Erlang.

:filelib.fold_files "directory/", "\.ex$", true, &Code.load_file/1, []
like image 28
whatyouhide Avatar answered Oct 02 '22 12:10

whatyouhide