# `__ENV__`
Bring Elixir-style `__ENV__` macro into Erlang via parse transform.
## Installation
Add `macro_env` to your `rebar.config`:
```erlang
{deps, [
{macro_env, "0.1.0"}
]}.
```
## Usage
Apply the parse transform to your module:
```erlang
-compile({parse_transform, '__ENV__'}).
```
Then use `__ENV__` anywhere in your code:
```erlang
io:format("~p~n", [__ENV__])
```
`__ENV__` expands to a map matching the `Elixir.Macro.Env` struct with the
following fields populated at compile time:
| Field | Value |
|--------------------|-----------------------------------------------|
| `__struct__` | `'Elixir.Macro.Env'` |
| `file` | Absolute path to the source file (binary) |
| `line` | Line number of the `__ENV__` reference |
| `module` | The current module atom |
| `function` | `{FunctionName, Arity}` tuple |
| `context` | `nil` |
| `functions` | List of `{Module, [{Fun, Arity}]}` from `-import` attributes |
| `aliases` | `[]` |
| `lexical_tracker` | `nil` |
| `macro_aliases` | `[]` |
| `versioned_vars` | `#{}` |
| `tracers` | `[]` |
| `requires` | `[]` |
| `macros` | `[]` |
| `context_modules` | `[CurrentModule]` |
## Calling Elixir macros from Erlang
Elixir macros look like ordinary functions but are compile-time AST
transformations. You cannot call them with a plain remote call like
`'Elixir.Logger':info(<<"hello">>)` — that will fail because `Logger.info/1`
is a macro, not a function.
With `__ENV__` available you can invoke Elixir macros directly:
```erlang
-compile({parse_transform, '__ENV__'}).
-define(APPLY_MACRO(Module, Macro, Args),
'Elixir.Code':eval_quoted(
Module,
list_to_atom(string:concat("MACRO-", atom_to_list(Macro))),
[__ENV__ | Args]
)
).
example() ->
?APPLY_MACRO('Elixir.Logger', info, [<<"hello from Erlang">>]).
```
## Build
```
$ rebar3 compile
```
## Test
```
$ rebar3 eunit
```
## License
Apache 2.0 — see [LICENSE.md](LICENSE.md).