我想看看当elixir被转换成束文件时会发生什么.有没有办法在控制台或文件中打印如何翻译?我想知道这个模块在erlang中会是什么样子.
我在想是否有elixir的调试模式,它将输出上述任何一个.
更具体地说,我有这个例子:
defmodule Test do
def t1(a), do: a
def t1(a, b \\ 2), do: a + b
end
Run Code Online (Sandbox Code Playgroud)
上面的代码提出了一个警告,考虑到我所做的事情,这是不可或缺的.基本上我想了解更多正在发生的事情.
首先,您需要将Elixir模块编译为.beam文件:
$ cat test.ex
defmodule Test do
def t1(a), do: a
def t1(a, b \\ 2), do: a + b
end
$ elixirc test.ex
warning: this clause cannot match because a previous clause at line 2 always matches
test.ex:3
Run Code Online (Sandbox Code Playgroud)
这将产生Elixir.Test.beam
.然后,您可以使用以下escript将此.beam反编译为Erlang源代码(我之前在Stackoverflow上的一些答案中复制了这个.不幸的是我似乎无法找到确切的源代码,但此代码在此处有许多答案,包括此一个.):
$ cat decompile.erl
#!/usr/bin/env escript
main([BeamFile]) ->
{ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(BeamFile,[abstract_code]),
io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).
Run Code Online (Sandbox Code Playgroud)
然后运行它:
$ escript decompile.erl Elixir.Test.beam
-compile(no_auto_import).
-file("test.ex", 1).
-module('Elixir.Test').
-export(['__info__'/1, t1/1, t1/2]).
-spec '__info__'(attributes | compile | exports |
functions | macros | md5 | module |
native_addresses) -> atom() |
[{atom(), any()} |
{atom(), byte(), integer()}].
'__info__'(functions) -> [{t1, 1}, {t1, 2}];
'__info__'(macros) -> [];
'__info__'(info) ->
erlang:get_module_info('Elixir.Test', info).
t1(a@1) -> a@1;
t1(x0@1) -> t1(x0@1, 2).
t1(a@1, b@1) -> a@1 + b@1.
Run Code Online (Sandbox Code Playgroud)
这可能更像是对@Dogbert 以上答案的评论,但为了格式化,我会将其作为单独的答案发布。
不需要创建.ex
文件并在它们上调用编译器来生成梁:
{:module, _, bytecode, _} =
defmodule Elixir.Test do
def t1(a), do: a
def t1(a, b \\ 2), do: a + b
end
# File.write!("Elixir.Test.beam", bytecode)
Run Code Online (Sandbox Code Playgroud)
现在您可能已经编写了一个 Beam 文件(bytecode
顺便说一下,我们将它存储在变量中。)
注意: beam_lib:chunks/2
当且仅当光束包含未加密的调试信息时才有效(默认情况下,灵药光束会这样做。)
此外,您不需要编写反编译的 erlang 代码,您可以直接在那里传递一个二进制文件Elixir
:
:beam_lib.chunks(bytecode, [:abstract_code])
Run Code Online (Sandbox Code Playgroud)
提取代码本身:
{:ok,{_,[abstract_code: {_, code}]}} =
bytecode |> :beam_lib.chunks([:abstract_code])
Run Code Online (Sandbox Code Playgroud)
现在code
包含代码,检查它应该足够了,但是您仍然可以自由使用 erlang 内置插件:
code |> :erl_syntax.form_list
Run Code Online (Sandbox Code Playgroud)
或者:
code |> :erl_syntax.form_list |> :erl_prettypr.format
Run Code Online (Sandbox Code Playgroud)
后者将为您提供二进制字符列表,其中包含 erlang 代码,与@Dogbert 的回答完全相同。使用IO.puts
以进行输出。
归档时间: |
|
查看次数: |
252 次 |
最近记录: |