Skip to content

Instantly share code, notes, and snippets.

@christhekeele
Last active May 27, 2023 00:42
Show Gist options
  • Save christhekeele/e858881d0ca2053295c6e10d8692e6ea to your computer and use it in GitHub Desktop.
Save christhekeele/e858881d0ca2053295c6e10d8692e6ea to your computer and use it in GitHub Desktop.
Metaprogramming Elixir module usage: A simple way to know what modules a module has used in Elixir.
# For more elaborate use cases, see the IndirectUsesTracker instead:
# https://gist.github.com/christhekeele/fc4e058ee7d117016b9b041b83c6546a
###
# A way to know, at runtime, what modules a module has used at compile time.
# In this case, you include `UsesTracker` into a module. When that module gets
# used in some other module, it registers itself with the other module.
##
defmodule UsesTracker do
defmodule Registry do
defmacro __before_compile__(_) do
quote location: :keep do
def uses do
@uses
end
end
end
end
defmacro __using__(module) do
quote location: :keep do
@before_compile Registry
Module.register_attribute(__MODULE__, :uses, accumulate: true)
Module.put_attribute(__MODULE__, :uses, unquote(module))
end
end
end
defmodule A do
defmacro __using__(_) do
quote location: :keep do
use UsesTracker, unquote(__MODULE__)
# Your code here...
end
end
end
defmodule B do
defmacro __using__(_) do
quote location: :keep do
use UsesTracker, unquote(__MODULE__)
# Your code here...
end
end
end
defmodule C do
use A
end
defmodule D do
use A
use B
end
C.uses #=> [A]
D.uses #=> [B, A]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment