This is common elixir:
defmodule Fizz do
defmacro asdf, do: IO.puts("asdf")
end
defmodule Buzz do
require Fizz
Fizz.asdf
end
However, although you can reference macros in the same context like:
defmodule Fizz do
# ...
defmacro asdf_qwer, do: asdf && IO.puts("qwer")
end
... you can't reference macros in the body of the same module that defined them:
defmodule Fizz do
defmacro asdf, do: IO.puts("asdf")
asdf
end
This raises undefined function asdf/0
.
Is there a workaround for this "problem"? Sometimes I may want to use macros to remove some boilerplate from the module I'm working on, and that macro's functionality may be specific enough not to put it in another module.
Elixir already provides mechanisms to write your everyday code in a simple and readable fashion by using its data structures and functions. Macros should only be used as a last resort. Remember that explicit is better than implicit. Clear code is better than concise code.
__MODULE__ is a compilation environment macros which is the current module name as an atom. Now you know alias __MODULE__ just defines an alias for our Elixir module. This is very useful when used with defstruct which we will talk about next. In the following example, we pass API.
here's a lightweight explanation of 'use' in elixir as I currently understand it. Use is a tool to reuse code just like require, import, and alias. Use simply calls the __using__ macro defined in another module. The __using__ macro allows you to inject code into another module.
The reason that we're getting undefined function
errors here is because at compile time, the asdf
macro does not yet exist.
So we need to notify the compiler that an extra step is required just before compilation is finished.
One option is the @after_compile module callback attribute which lets you invoke some code just after compilation in order to perform a final bit of code generation.
For example:
defmodule M do
@after_compile __MODULE__
def __after_compile__(env, _bytecode) do
IO.inspect env
end
end
Another option is to put your macros in a Fizz.Macros
module.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With