# Decompilerl
Decompile Elixir/BEAM to Erlang abstract code.
## Why?
When I started working with Elixir, my biggest gripe (coming from the Erlang
world) was that I had no clue what it really compiled to.
This tool aims to provide some answers.
### Sample question: what is a `struct`?
```elixir
defmodule TheStruct do
defstruct foo: 1
alias __MODULE__
def new do
%TheStruct{foo: 2}
end
end
```
```elixir
Decompilerl.decompile(TheStruct)
```
```erlang
%% lots of irrelevant stuff...
'__struct__'() ->
#{'__struct__' => 'Elixir.TheStruct', foo => 1}.
'__struct__'(_@1) ->
{_@6, _@7} = 'Elixir.Enum':reduce(_@1,
{'__struct__'(), []},
fun ({_@2, _@3}, {_@4, _@5}) ->
{maps:update(_@2, _@3, _@4),
lists:delete(_@2, _@5)}
end),
case _@7 of
[] -> _@6;
_ ->
erlang:error('Elixir.ArgumentError':exception(<<"the following keys must also be given "
"when building ",
"struct ",
('Elixir.Kernel':inspect('Elixir.TheStruct'))/binary,
": ",
('Elixir.Kernel':inspect(_@7))/binary>>))
end.
new() ->
#{'__struct__' => 'Elixir.TheStruct', foo => 2,
'__struct__' => 'Elixir.TheStruct'}.
```
There we go! `struct` is an Erlang map with a special key `__struct__ => ?MODULE`
that allows pattern matching further down the line. Noice!
## Command-line interface
You can build `Decompilerl` as a standalone executable (escript).
```
$ mix escript.build
Compiled lib/cli.ex
Compiled lib/decompilerl.ex
Generated escript decompilerl with MIX_ENV=dev
$ ./decompilerl
Decompilerl
usage: decompierl <beam_file> [-o <erl_file> | --output=<erl_file>]
```
## Usage
By default, `Decompilerl.decompile` spits the Erlang abstract code to stdout.
When provided with a second (optional) argument, it'll dump it to a file.
```
$ iex -S mix
iex(1)> Decompilerl.decompile(Decompilerl, "/tmp/foo.erl")
```