Module attributes in Elixir serve three purposes:
- They serve to annotate the module, often with information to be used by the user or the VM.
- They work as constants.
- They work as temporary module storage to be used during compilation.
Typically, if you declare an attribute twice like this:
@unit_of_measure :fathom @unit_of_measure :stone
The second declaration will override the first:
IO.inspect(@unit_of_measure) # :stone
But by registering the attribute by calling
register_attribute you get the opportunity to set the attribute to accumulate. When accumulating, each declaration will push the declared value onto the head of a list.
defmodule TriColarian do @moduledoc false Module.register_attribute(__MODULE__, :colors, accumulate: true) @colors :green @colors :red @colors :yellow def colors do @colors end end TriColarian.colors() # [:yellow, :red, :green]
At compile time, perhaps when executing a macro, you have the opportunity to dynamically build a list.