Elixir语言中 Code
相关用法介绍如下。
用于管理代码编译、代码评估和代码加载的实用程序。
该模块补充了 Erlang 的:code 模块以添加特定于 Elixir 的行为。这个模块中的几乎所有函数都对 Elixir 的行为产生了全局副作用。
处理文件
该模块包含三个用于编译和评估文件的函数。以下是它们及其行为的摘要:
-
require_file/2
-
compile_file/2
-
eval_file/2
简而言之,当您要跟踪系统处理的文件时,必须使用第一个,以避免多次编译同一个文件。这在脚本中很常见。
必须在您对文件中定义的模块感兴趣时使用,无需跟踪。当您对评估文件的结果而不是它定义的模块感兴趣时,应该使用compile_file/2
。eval_file/2
上述函数适用于 Elixir 源代码。如果您想使用编译为字节码的模块,这些模块具有 .beam
扩展名,通常位于 Mix 项目的 _build 目录下,请参阅 Erlang 的
模块中的函数。:code
Erlang VM 上的代码加载
Erlang 有两种加载代码的模式:交互式和嵌入式。
默认情况下,Erlang VM 以交互模式运行,模块根据需要加载。在嵌入式模式下,情况正好相反,因为所有模块都需要预先或显式加载。
您可以使用
(以及 ensure_loaded/1
和 ensure_loaded?/1
)在使用模块之前检查模块是否已加载并采取行动。ensure_loaded!/1
ensure_compiled/1
和 ensure_compiled!/1
ensure_compiled/1
ensure_compiled!/1
Elixir 还包括
和 ensure_compiled/1
函数,它们是 ensure_compiled!/1
的超集。ensure_loaded/1
由于 Elixir 的编译是并行进行的,在某些情况下,您可能需要使用尚未编译的模块,因此甚至无法加载它。
调用时,
和ensure_compiled/1
会停止调用者的编译,直到模块可用。请注意 ensure_compiled!/1
和 ensure_compiled/1
之间的区别很重要:如果您使用的是 ensure_compiled!/1
,则表示您向编译器表明只有在所述模块可用时才能继续。ensure_compiled!/1
如果您正在使用
,则意味着您可以在没有模块的情况下继续,因此 Elixir 可能会在模块尚不可用的情况下返回 Code.ensure_compiled/1
{:error, :unavailable}
(但稍后可能可用)。
由于这些原因,开发人员通常必须使用
。特别是,不要这样做:Code.ensure_compiled!/1
case Code.ensure_compiled(module) do
{:module, _} -> module
{:error, _} -> raise ...
end
最后,请注意您只需要
来检查在同一项目中定义的模块。它不适用于依赖项中的模块,因为依赖项总是预先编译的。ensure_compiled!/1
在大多数情况下,
就足够了。 ensure_loaded/1
必须在极少数情况下使用,通常涉及需要调用模块以获取回调信息的宏。使用ensure_compiled!/1
的可能性更小。ensure_compiled/1
编译跟踪器
Elixir 支持编译跟踪器,它允许模块在编译文件时观察 Elixir 编译器处理的结构。跟踪器是实现trace/2
函数的模块。该函数接收事件名称作为第一个参数和
作为第二个参数,它必须返回 Macro.Env
:ok
。跟踪器尽可能同步地做尽可能少的工作并将大部分工作分派给单独的进程是非常重要的。缓慢的跟踪器会减慢编译速度。
您可以通过
配置跟踪器列表。跟踪器可以使用以下事件:put_compiler_option/2
-
:start
-(从 v1.11.0 开始)在编译器开始跟踪新的词法上下文(例如新文件)时调用。请记住,编译器并行运行,因此多个文件可能会调用:start
并同时运行。宏环境的lexical_tracker
的值,尽管是不透明的,但可用于唯一标识环境。 -
:stop
-(从 v1.11.0 开始)在编译器停止跟踪新的词法上下文(例如新文件)时调用。 -
{:import, meta, module, opts}
- 每当导入module
时跟踪。meta
是导入 AST 元数据,opts
是导入选项。 -
{:imported_function, meta, module, name, arity}
和{:imported_macro, meta, module, name, arity}
- 每当调用导入的函数或宏时进行跟踪。meta
是调用 AST 元数据,module
是导入的模块,然后是导入的函数/宏的name
和arity
。 -
{:alias, meta, alias, as, opts}
- 每当alias
别名为as
时跟踪。meta
是别名 AST 元数据,opts
是别名选项。 -
{:alias_expansion, meta, as, alias}
跟踪先前定义的alias
的别名扩展,即当用户写入扩展为alias
的as
时。meta
是别名扩展 AST 元数据。 -
{:alias_reference, meta, module}
- 只要代码中有别名,即用户在代码中写入MyModule.Foo.Bar
时进行跟踪,无论它是否被扩展。 -
{:require, meta, module, opts}
- 每当需要module
时进行跟踪。meta
是要求 AST 元数据,opts
是要求选项。 -
{:struct_expansion, meta, module, keys}
- 每当module
的结构展开时跟踪。meta
是结构 AST 元数据,keys
是扩展使用的键 -
{:remote_function, meta, module, name, arity}
和{:remote_macro, meta, module, name, arity}
- 每当引用远程函数或宏时进行跟踪。meta
是调用 AST 元数据,module
是调用的模块,然后是name
和arity
。 -
{:local_function, meta, name, arity}
和{:local_macro, meta, name, arity}
- 每当引用本地函数或宏时跟踪。meta
是调用 AST 元数据,后跟name
和arity
。 -
{:compile_env, app, path, return}
- 每当调用Application.compile_env/3
Application.compile_env!/2
app
是原子,path
是要在应用程序环境中遍历的键列表,而return
是{:ok, value}
或:error
。 -
{:on_module, bytecode, :none}
-(自 v1.11.0 起)在定义模块时跟踪。这等效于@after_compile
回调,并在给定模块中的任何@after_compile
之后调用。第三个元素目前是:none
,但将来可能会提供更多元数据。最好暂时忽略它。
:tracers
编译器选项可以与:parser_options
编译器选项结合使用,以丰富上述跟踪事件的元数据。
将来可能随时添加新事件,因此建议trace/2
函数具有"catch-all" 子句。
下面是一个打印所有远程函数调用的示例跟踪器:
defmodule MyTracer do
def trace({:remote_function, _meta, module, name, arity}, env) do
IO.puts "#{env.file}:#{env.line} #{inspect(module)}.#{name}/#{arity}"
:ok
end
def trace(_event, _env) do
:ok
end
end
相关用法
- Elixir Code.prepend_path用法及代码示例
- Elixir Code.compiler_options用法及代码示例
- Elixir Code.quoted_to_algebra用法及代码示例
- Elixir Code.put_compiler_option用法及代码示例
- Elixir Code.ensure_compiled用法及代码示例
- Elixir Code.format_string!用法及代码示例
- Elixir Code.required_files用法及代码示例
- Elixir Code.get_compiler_option用法及代码示例
- Elixir Code.Fragment.cursor_context用法及代码示例
- Elixir Code.available_compiler_options用法及代码示例
- Elixir Code.ensure_loaded?用法及代码示例
- Elixir Code.eval_quoted用法及代码示例
- Elixir Code.require_file用法及代码示例
- Elixir Code.Fragment.container_cursor_to_quoted用法及代码示例
- Elixir Code.Fragment.surround_context用法及代码示例
- Elixir Code.delete_path用法及代码示例
- Elixir Code.append_path用法及代码示例
- Elixir Code.ensure_loaded用法及代码示例
- Elixir Code.unrequire_files用法及代码示例
- Elixir Code.fetch_docs用法及代码示例
- Elixir Code.string_to_quoted_with_comments用法及代码示例
- Elixir Code.eval_string用法及代码示例
- Elixir Config.config_env用法及代码示例
- Elixir Config.config用法及代码示例
- Elixir Config.Reader用法及代码示例
注:本文由纯净天空筛选整理自elixir-lang.org大神的英文原创作品 Code。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。