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.

Reply via email to