Inspecting AST is a good way to learn about elixir macros.
Executing AST can also be instructional, but it is a little more nuanced than
directly executing elixir code.
This post covers executing AST with Code.eval_quoted().
Note that outside of experimentation, executing AST with Code.eval_quoted()
is probably the wrong thing to do.
This is a single file example of a naive solution that does not work.
Put the following in ast.exs.
Make the script executable.
This is the expected outputed.
This is the actual output.
What happened?
Directly invoking the macro works as expected.
The naive expectation is that the AST should just execute because the code
is the same as the direct invocation.
The problem is that context is missing.
The AST evaluates as process_macro([“Args:” | args]) which expands to
process_function([“Args:” | args]).
process_function is defined in the MacroLibrary module.
The macro library is included in the Script module.
That information is stored in the current context.
Without the context, Code.eval_quoted does not know where to find
process_function.
Change line 44 to the following:
There is another problem.
When executing the macro directly, args resolves properly.
Bindings are not part of the environment context and need to be passed in
separately.
Change line 44 to the following:
This did not fix the problem.
The macro can be directly invoked with process_macro([“Args:” | args]),
but executed AST needs to use var!() to access variables.
This means that the direct macro call and the executable AST need to be
slightly different.