为什么 Elixir Logger 由宏组成?

Why is Elixir Logger composed of Macros?

今天不得不在我的一个应用程序中使用 Logger,并记得 . So I decided to look at the Logger source code 以了解为什么 debuginfoerror 等. 是宏而不是简单函数。

从代码上看,debuginfo等宏(甚至是它们的底层函数)看起来很简单。难道不能简单地将它们导出为方法而不是宏吗?


来自记录器代码:

  defmacro log(level, chardata_or_fn, metadata \ []) do
    macro_log(level, chardata_or_fn, metadata, __CALLER__)
  end

  defp macro_log(level, data, metadata, caller) do
    %{module: module, function: fun, file: file, line: line} = caller

    caller =
      compile_time_application ++
        [module: module, function: form_fa(fun), file: file, line: line]

    quote do
      Logger.bare_log(unquote(level), unquote(data), unquote(caller) ++ unquote(metadata))
    end
end

据我所知,将它们变成函数而不是宏会更简单。

可能是因为 __CALLER__ 特殊形式,它提供有关调用上下文的信息,包括文件和行,但仅在宏中可用。

事实证明,另一个原因是可以在编译期间针对应用程序不需要的日志级别删除调用代码。

来自ElixirForum discussion

It is to allow the code to just entirely not exist for logging levels that you do not want, so the code is never even called and incurs no speed penalty, thus you only pay for the logging levels that you are actively logging.

It's so the entire Logger call can be stripped out of the code at compile time if you use :compile_time_purge_level