Using Module.register_attribute
and accumulate: true
lets us collect the values of annotations in our module for later use. Observe:
In the above example, we’re collecting annotations that are named @greet
.
We can then specify a @before_compile
callback from the same Greetify
module that will be called before whatever downstream module that use
Greetify
compiles.
@before_compile
provides a hook that will be invoked before the module is compiled. This makes it possible to inject functions inside the module exactly before compilation. You can think of it as anafter_*
callback in Rails.
Now let’s see how this works in action:
When the above Human
module is loaded, we see:
Note that our Greetify
module calls IO.puts
to print these messages before the compilation of Human
is complete, because of @before_compile
.
Note that you can pass in any Elixir term as arguments to your annotations. In the example above, we pass in a tuple.
To sum up, annotations enables you to have your library users to declaratively add or modify behaviour without modifying any actual code.