为什么 Elixir Logger 由宏组成?
Why is Elixir Logger composed of Macros?
今天不得不在我的一个应用程序中使用 Logger
,并记得 . So I decided to look at the Logger source code 以了解为什么 debug
、info
、error
等. 是宏而不是简单函数。
从代码上看,debug
、info
等宏(甚至是它们的底层函数)看起来很简单。难道不能简单地将它们导出为方法而不是宏吗?
来自记录器代码:
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__
特殊形式,它提供有关调用上下文的信息,包括文件和行,但仅在宏中可用。
事实证明,另一个原因是可以在编译期间针对应用程序不需要的日志级别删除调用代码。
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
今天不得不在我的一个应用程序中使用 Logger
,并记得 debug
、info
、error
等. 是宏而不是简单函数。
从代码上看,debug
、info
等宏(甚至是它们的底层函数)看起来很简单。难道不能简单地将它们导出为方法而不是宏吗?
来自记录器代码:
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__
特殊形式,它提供有关调用上下文的信息,包括文件和行,但仅在宏中可用。
事实证明,另一个原因是可以在编译期间针对应用程序不需要的日志级别删除调用代码。
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