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.

Reply via email to