ca1989
Do I need a macro to do this, or can I go away with something else?
Hi all,
I have many components (about ~50) that have 3 common attributes, now I am going to add a couple more, and before I do that I am seeking some advice.
attr :class, :string, default: ""
attr :id, :string, default: nil
attr :rest, :global
Currently, I have repeated those ~50 times.
- is there a way to avoid repeating those all the times?
- is a macro the tool I want (I know nothing about macros)?
- I would love to keep the
classandidattrs separated from therestfor documentation purposes
Thank you
Cheers!
Marked As Solved
dimitarvp
I am not seriously suggesting it, I am saying it’s one of the potentially viable solutions just to illustrate that it would be too much to use macros here.
That would be a good candidate for a macro. Have that parent have defmacro __using__(opts \\ []) macro and inject code through it.
That way you can have all your 50+ components only have this line at the top:
use Parent, option_1: true, option_2: ["hello", "there"], option_3: :duh
…and the rest will be just their specific parts.
Or, if you are REALLY convinced that this is a strict parent-children relationship and that this will not change – i.e. you will never need multiple parents per one child – then you can just use Elixir’s protocols and apply a little violence.
Also Liked
D4no0
I would avoid going this path, as the benefit you gain (1 line of code vs 3 lines of code) is not worth it, because it will make the code much less readable.
D4no0
Actually I would avoid using here __using__ as it is not necessary. I would something like this:
defmodule Attributes do
defmacro generic_attributes() do
quote do
attr :class, :string, default: ""
attr :id, :string, default: nil
attr :rest, :global
end
end
end
And using it inside of components by:
require Attributes
Attributes.generic_attributes()
The advantages are:
- Much more readability, as you can document the macro and have a clear understanding where you use it, opposed to use;
- Macro defined in this way can only inject code, to avoid people coming later and adding their “smart” ideas.
dimitarvp
You are not wrong but I would be completely okay if one module’s only job was to inject code in others. Having huge modules doing many things with many code-injection macros is not exactly a win for readability and maintainability.
In the end it’s your call, and the difference can be easily handled.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









