什么时候应该在.exs文件中使用defmodule

我尝试创建一个没有curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -的混合项目,所以我创建了文件。

我从凤凰城项目中引荐了sudo apt-get install -y nodejs

我看到config.exs没有模块定义。我尝试在config.exs文件中声明一个独立函数,它引发了预期的错误

config.exs

然后,我假设可以不用.ex来编写** (ArgumentError) cannot invoke def/2 outside module ,然后看到.exs具有模块定义。为什么会这样呢?

我的问题是为什么要defmodule保留没有模块定义,而mix.exs保留这个定义?

什么时候应该在config.exs中使用defmodule?

linshi0 回答:什么时候应该在.exs文件中使用defmodule

如果您查看mix.exs文件,您会注意到:

use Mix.Project

file现在包含:

  @doc false
  defmacro __using__(_) do
    quote do
      @after_compile Mix.Project
    end
  end

  # Invoked after each Mix.Project is compiled.
  @doc false
  def __after_compile__(env,_binary) do
    push(env.module,env.file)
  end

@after_compile是在elixir/kernel.ex中定义的宏,即使它是一种奇怪的形式,也由__using__mix.exs调用。由于您无法在模块外部调用宏,因此需要在mix.exs文件中包含一个模块。

为了更清楚地说明这一点,让我们尝试删除mix.exs中的模块并运行项目:

* (ArgumentError) cannot invoke @/1 outside module
    (elixir) lib/kernel.ex:5230: Kernel.assert_module_scope/3
    (elixir) expanding macro: Kernel.@/1
    mix.exs:2: (file)
    (mix) expanding macro: Mix.Project.__using__/1
    mix.exs:2: (file)
    (elixir) expanding macro: Kernel.use/1
    mix.exs:2: (file)

因此,您的问题的答案是,如果没有模块,则无法调用钩子@after_compile,因为钩子本身就是宏。钩子最有可能用于在所有文件编译之后自动加载项目。

PS:push/3函数调用一个有趣的模块函数:

  

Mix.ProjectStack.push(原子,配置,文件)

如果查看ProjectStack模块的源代码,您会发现它是基于Agent的状态机。因此,基本上所有混合项目都被压入堆栈,并且可以检查它们的名称中是否存在重复项。

本文链接:https://www.f2er.com/3164591.html

大家都在问