Elixir脚本以递归方式加载文件夹中的所有模块

时间:2015-04-16 16:55:10

标签: elixir

我想在特定文件夹中递归编译和加载所有模块。 我知道我可以用Mix项目

来做到这一点
iex -S mix run

将加载lib/目录中的所有文件。

但是,我想在非混合脚本中使用相同的行为 - 如果可能的话,以编程方式进行。 类似Code.compile_all("directory/")的东西 有这样的API吗?

2 个答案:

答案 0 :(得分:31)

只是为了澄清术语:Mix不加载lib /中的文件,如果需要它会编译它们,然后使用编译的字节代码(不必再次执行整个文件)。

您可以通过调用Code.require_file/1Code.load_file/1来加载目录中的任何文件,但这不会在磁盘中生成任何工件。如果稍后调用Code.require_file/1,将再次评估相同的文件,这可能需要一些时间。编译的想法完全是你每次都不付这个价格。

那就是说,让我们直接回答你的问题。

  1. 在目录中加载所有内容的方法是:

    dir
    |> Path.join("**/*.exs")
    |> Path.wildcard()
    |> Enum.map(&Code.require_file/1)
    
  2. 如果要编译它们,请使用:

    dir
    |> Path.join("**/*.ex")
    |> Path.wildcard()
    |> Kernel.ParallelCompiler.files_to_path("path/for/beam/files")
    
  3. 如果您只想在项目的上下文中编译另一个目录(使用mix.exs而不是),您可以在def project内提供要混合的任何目录:

    elixirc_paths: ["lib", "my/other/path"]
    
  4. 就是这样。

答案 1 :(得分:1)

我不确定在Elixir中执行此操作的内置方法,但您可以使用Erlang中的filelib:fold_files/5之类的内容获得相同的结果。

:filelib.fold_files "directory/", "\.ex$", true, &Code.load_file/1, []