__ENV__
Bring Elixir-style __ENV__ macro into Erlang via parse transform.
Installation
Add macro_env to your rebar.config:
{deps, [
{macro_env, "0.1.0"}
]}.Usage
Apply the parse transform to your module:
-compile({parse_transform, '__ENV__'}).
Then use __ENV__ anywhere in your code:
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 |
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:
-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 compileTest
$ rebar3 eunitLicense
Apache 2.0 — see LICENSE.md.