walkr

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

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

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

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. :slight_smile:

Where Next?

Popular in Questions Top

Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
vac
Hi, I’m quite new in Elixir and I’m trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and I...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New

Other popular topics Top

vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43487 311
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 31013 112
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43757 214
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement