How does the attr macro associate the attribute to a function component?

I’m relatively new to Elixir and Phoenix and I was wondering how the attr macro that’s used to define attributes for a component is able to make the association between the attribute and the function that returns the component. Is it done based on the line where the attribute and the component functions are defined?

When you call use Phoenix.Component the __using__ macro overrides Kernel.def, so it first do some extra work and calls Kernel.def back.

This is part of wide metaprogramming topic and is generally not recommend for beginners. Also it’s recommended to avoid using macros unless they are needed and I would say that it especially applies to overriding the Elixir core API. First of all this is confusing and secondly it’s pretty hard to make it work with other overrides since we do not have API like:

# Sets a call order by overriding the Kernel.def:
# Firstly AnotherLibrary.Kernel.def is called
# Then Phoenix.Component.def is called
# Then YetANotherLibrary.def is called
# Finally Kernel.def is called
use Override.Function, [
  {Kernel, :def, [AnotherLibrary.Kernel, Phoenix.Component, YetAnotherLibrary]},
  …
]

Even if we would have an API like that there is another problem. What if one of the library is not only “decorating” the function/macro, but also wants to make it work differently? What if one of those libraries tries to replace Kernel.def completely, so it should not be called lastly?

This is because you should not take it now. If you are interested in going further with your Elixir skills then read documentation and maybe some books about Macros and Metaprogramming. If you would know the overall topic enough then you should know how overriding works and therefore you would take a look at the source of Phoenix.Component and this question would not be asked.

There are no stupid questions.

Note: As above it’s not about asking the question or not. In my opinion simply by creating you prove yourself that you are not ready for this step. Or in other words: you need to understand topic to know when you need to search the solution.

Helpful resources:

  1. https://elixir-lang.org/getting-started/meta/macros.html
  2. Macro — Elixir v1.16.0
  3. https://medium.com/multiverse-tech/metaprogramming-in-elixir-with-macros-814f2e13b558
  4. How to Override Kernel Macros | Curiosum tils
  5. Metaprogramming Elixir: Write Less Code, Get More Done (and Have Fun!) by Chris McCord
2 Likes