walkr
Collect modules that `use` some other module at compile time
Hello,
I need some help with the following problem (Bascially I want to store at compile time all modules using some other module, along with their opts).
defmodule Root do
@modules %{} # Mapping from __MODULE__ to opts
def __using__(opts) do
quote do
@opts unquote(opts)
def hello(), do: "Hello from #{__MODULE__}"
# How do I store __MODULE__ and its @opts
# inside Root.@modules?
# ...
end
end
def modules_using_me: @modules
end
defmodule A do
use Root, id: A1
end
defmodule B do
use Root, id: B1
end
Then to get the modules __using__ Root I would call
iex> Root.modules_using_me()
%{A: [id: A1], B: [id: B1]}
OR
iex> SomeOtherModule.modules_using_root()
%{A: [id: A1], B: [id: B1]}
Could anyone give me some ideas? I already tried to accumulate into a Root attribute all other modules, but obviously it fails since Root module is already compiled.
Thank you!
Most Liked
christhekeele
As you observe, Root cannot know what modules use it at compile time, because it must first be compiled itself. Indeed, at compile time only module A could know if it used Root.
You can leverage module attributes to ask A which modules it has used—example code for that here.
Alternatively, since A knows what it’s used, you could inject that information into other modules that use A if you take control of its __using__ macro. This allows a module that uses both A and B to know what modules they respectively have used. This is pretty abstract and hard to explain—I have example code demoing the concept here.
mbuhot
Your problem sounds similar to protocol consolidation. You might find some inspiration in GitHub - OvermindDL1/protocol_ex: Elixir Extended Protocol · GitHub which has a custom mix compiler task that scans the beam files for modules that declare implemtations of a protocol.
OvermindDL1
I can easily add a function that returns all implementations of the given protocol too (I think I have it in a descriptor but it’s not really ‘public’ stuff?), but if that is the only feature you are needing then the normal elixir protocols already has that feature too.
But yeah, the scanner part itself could easily do that, copy it into your project and just have it be a compiler that generates the information necessary after everything else is already compiled. ![]()
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
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









