I have trouble understanding the use case too but fwiw compilation tracers to
the rescue! :D
defmodule MyTracer do
def trace({:remote_macro, _, M, :__using__, 1}, env) do
IO.puts "#{inspect(env.module)} called M.__using__/1"
end
def trace(_other, _env) do
:ok
end
end
Code.put_compiler_option(:tracers, [MyTracer])
Code.compile_string("""
defmodule M do
defmacro __using__(_) do
:ok
end
end
defmodule Foo do
use M
end
defmodule Bar do
use M
end
""")
# Outputs:
# Foo called M.__using__/1
# Bar called M.__using__/1
> On 8 Mar 2021, at 19:55, José Valim <[email protected]> wrote:
>
> Hi Adi, I am sorry but I could not understand the use case from your
> description. Can you please provide a more concrete example? Thanks!
>
> On Mon, Mar 8, 2021 at 7:50 PM Adi <[email protected]
> <mailto:[email protected]>> wrote:
> Hi Jose,
>
> Thanks for the quick response!
>
> Having the `require` information in `__ENV__` is definitely useful, but my
> concerns stem from a module not having the knowledge of what it is expected
> to do.
>
> For example, let's say we want to test a module A that uses another module B.
> In order to test A's usage of B, we HAVE to test `B.__using__/1`
> functionality as well. Let's say modules C, D, E use B as well, we will have
> to do the same. And, if in the future B's behavior changes, we will have to
> update the tests for A, C, D and E as well. Having access to the `@__using__`
> attribute will provide a way to test modules A, C, D and E without having to
> test `B.__using__/1`, which should be tested independently. I think by adding
> another abstraction in between module A and B that allows us to know how A
> uses B is a better design.
>
> Let me know what you think of this!
>
> On Monday, 8 March 2021 at 13:03:00 UTC-5 José Valim wrote:
> Hi Adi, thanks for the proposal!
>
> Can you please expand on why this information is useful?
>
> Also, if it helps, all used modules are required, so __ENV__.requires gives
> you a close enough list. :)
>
> On Mon, Mar 8, 2021 at 6:56 PM Adi <[email protected] <>> wrote:
>
> Hi Elixir Team,
>
> Thanks for all your awesome work!
>
> At the moment, there is no way that I know of, to inspect a module and get
> information regarding other modules that it uses. It would add more
> transparency to a module if we could add a persistent module attribute
> `@__using__` which stores that information. The module attribute would store
> information about what modules are being used, along with the options being
> passed to their `__using__/1` macros.
>
> This can be done by updating `Kernel.use/2` macro to do something like this:
>
> ```ex
> defmacro use(module, opts \\ []) do
> calls =
> Enum.map(expand_aliases(module, __CALLER__), fn
> expanded when is_atom(expanded) ->
> quote do
> require unquote(expanded)
> unquote(expanded).__using__(unquote(opts))
>
> # new code begins here #
> Module.register_attribute(__MODULE__, :__using__, accumulate:
> true, persist: true)
> Module.put_attribute(__MODULE__, :__using__, {unquote(expanded),
> unquote(opts)})
> # new code ends here #
> end
>
> _otherwise ->
> raise ArgumentError,
> "invalid arguments for use, " <>
> "expected a compile time atom or alias, got:
> #{Macro.to_string(module)}"
> end)
>
> quote(do: (unquote_splicing(calls)))
> end
> ```
>
> Would love to get more thoughts on this!
>
> Best,
> Adi
>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected] <>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/5cca271b-5d5b-4174-b317-909240bb0db6n%40googlegroups.com
>
> <https://groups.google.com/d/msgid/elixir-lang-core/5cca271b-5d5b-4174-b317-909240bb0db6n%40googlegroups.com?utm_medium=email&utm_source=footer>.
>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected]
> <mailto:[email protected]>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/09fc281a-a77f-44f3-bc48-99169922a1ffn%40googlegroups.com
>
> <https://groups.google.com/d/msgid/elixir-lang-core/09fc281a-a77f-44f3-bc48-99169922a1ffn%40googlegroups.com?utm_medium=email&utm_source=footer>.
>
> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected]
> <mailto:[email protected]>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4JzMH97tXcQCoD5nYGdMo9AM3Ai5EV%2B6u39h-bFfymtbw%40mail.gmail.com
>
> <https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4JzMH97tXcQCoD5nYGdMo9AM3Ai5EV%2B6u39h-bFfymtbw%40mail.gmail.com?utm_medium=email&utm_source=footer>.
--
You received this message because you are subscribed to the Google Groups
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/elixir-lang-core/74621593-A9F6-4F47-AFB8-0F9D5C0020D5%40wojtekmach.pl.