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]. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/09fc281a-a77f-44f3-bc48-99169922a1ffn%40googlegroups.com.
