sezaru
When writing my code, I always find __MODULE__ very useful to use as alias of that module “inner dependencies”, ex:
alias __MODULE__.{Impl, Helper, ...}
But one thing that I always find missing is that when I want to get some dependency for a module in the same “level” that my current module, I need to write the full module path, ex:
defmodule My.Big.Module.Path.Something do
alias My.Big.Module.Path.SomethingElse
...
end
I feel that having something like __PARENT_MODULE__ would be useful in these cases. Also, the impact on the existing eco-system would be zero since it doesn’t break any existing code.
Here are more “concrete examples” of when this can come in handy:
When organizing behaviours
The way I organize them is something like this:
# The behaviour module
Some.Module.MyBehaviour
# The modules implementing it
Some.Module.MyBehaviour.Impl1
Some.Module.MyBehaviour.Impl2
Some.Module.MyBehaviour.Impl3
In these cases, I could write something like @behaviour __PARENT_MODULE__ and @impl __PARENT_MODULE__ instead of @behaviour Some.Module.MyBehaviour and @impl Some.Module.MyBehaviour
When organizing gen servers and scoped business logic
If my genservers are getting big or complex, I like to split them into smaller parts, normally what I do is have something like this:
# This module will have the genserver child_spec and public APIS
Some.Module.Path.MyGenServer
# This module will have all the genserver code implementation (handle_call, start_async, etc)
Some.Module.Path.MyGenServer.Server
# This module will have all the genserver business logic
Some.Module.Path.MyGenServer.Impl
# And this module will have the genserver state struct and how to create/update it
Some.Module.Path.MyGenServer.State
Now, for example, the Server module needs to call Impl functions, and the Impl module needs to call State functions. Making the usage of __PARENT_MODULE__ useful here.
I don’t know if that is normally an issue for other people, but the project I work is pretty big and have some pretty big module names, so having something like that would make writing some code way faster for me.
Trending in Proposals: Ideas
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 10- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
sodapopcan
I don’t hate this and have found myself wanting it for cases like your first example. However, there is already confusion around there not actually being a module hierarchy and feel this could make it worse. It’s also something that won’t “just work” when you rename a module referenced by this.
Personally, I’m overall indifferent as I don’t find status quo to be too much of a pain.
sezaru
Can you elaborate on that? I’m not sure I understood the point.
I would argue that you would get an error from the compiler and you would be able to easily fix the issue.
sodapopcan
That module hierarchy in Elixir is an illusion and doesn’t exist. The
Lots of people don’t understand this. Nested
.is lie!defmodules already make this confusing enough.Maybe this one wouldn’t be as bad as I thought. I’d have think more on this one as it feels like it could possibly cause subtle bugs where a rename could result in it calling another function that happens to have the same name, but maybe not
I should add that despite my indifference, I’d more than likely use this if it were available.
jswanner
To expand upon this with examples…
Module
A.B.Cis not contained within moduleA.BnorA, they are completely separate modules whose names start the same.Even when writing code such as:
Module
A.Bis still not truly contained within moduleA(A.Bis not a child ofA) but the above works as a convenience.sezaru
Ah, ok, I got now what you meant, but that is just a technical detail IMO, in the end of the day devs (well, I just speak to myself on that) would read it as a hierarchy regardless.
But yeah, having a
__PARENT_MODULE__would give the wrong idea that the modules are a hierarchy.manhvu
Recently, I work in large repo and must to add alias too much. I wish Elixir has namespace for auto add alias (and maybe support for import/require/use).
Example:
Updated: I brought this into the proposal.
rhcarvalho
I do use
__MODULE__occasionally. Often likeEven though it saves characters when writing, I find it sometimes makes reading code harder, whereas spelling out the name or fully qualified name would have been clearer. Example situations:
grepresults, reviewinggit diff, casually browsing a large file. Those are add the cognitive burden to decode on my head “what module is this?”I guess I’d feel similar about a
__PARENT_MODULE__, with the additional trouble of making moving modules around to organize the illusional hierarchy require consideration for any usage of that shortcut. Depending on where the module name is used, this could pass unnoticed by the compiler, e.g. if the module is referenced as an MFA tuple.rhcarvalho
AFAIK Erlang has a single module/atom namespace, and Elixir inherits that. This idea would be a separate proposal, different than the OP.
You can use the
usemacro to refactor your many requires, imports and aliases and implement something similar to what you are asking in “user land”. In fact, that’s what Phoenix projects are setup like when you scaffold them withphx.new.For example, see: https://github.com/phoenixframework/phoenix/blob/V1.8.1/installer%2Ftemplates%2Fphx_single%2Flib%2Fapp_name_web.ex#L80-L97
In Controllers, Components, LiveViews, HEEx files, etc, the module
Phoenix.LiveView.JSis available to use asJSwithout you having to alias it explicitly in every file.While possible, this “magical” behavior is generally frowned upon, in preference of explicit code.
manhvu
Thank you! My original idea namespace is a macro but need to work in compiler for sharing state or add specific thing.
I wrote to a separated OP.
sodapopcan
Your example of
alias __MODULE__, as: Userwould definitely make grepping harder, though that is really only because of the:as. Personally I think:asshould really only ever be used for getting around naming conflicts.Otherwise for me I find the cognitive burden goes the other way. when I see
__MODULE__I immediately think “current module.” On the other hand:Seeing
%Foo.Bar{}here immediately makes me think “a remote module” and it often takes me many moments to figure it out, which sucks when you’re scanning.