sezaru

sezaru

Proposal: Support for __PARENT_MODULE__ (or some other better name)

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.

Most Liked

sodapopcan

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.

jswanner

jswanner

To expand upon this with examples…

Module A.B.C is not contained within module A.B nor A, they are completely separate modules whose names start the same.

Even when writing code such as:

defmodule A do
  defmodule B do
    def b, do: "b"
  end

  def a, do: B.b()
end

Module A.B is still not truly contained within module A (A.B is not a child of A) but the above works as a convenience.

sodapopcan

sodapopcan

Your example of alias __MODULE__, as: User would definitely make grepping harder, though that is really only because of the :as. Personally I think :as should 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:

defmodule Foo.Bar do
  # ... many line
  def something(%Foo.Bar{} = bar) do
    # ...
  end
end

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.

Where Next?

Popular in Proposals: Ideas Top

beno
There appears to be no way to escape whitespace in word lists, so sigil_w (and sigil_W) can only be used for lists of single words. Of co...
New
andypearson
Hey all, I have been working on some performance improvements for the Phoenix application I work on. As part of this, through trial and...
New
sevensidedmarble
All the pieces are there to execute arbitrary JS commands from the server. You can put them on a data property and call them from the cli...
New
sevensidedmarble
Hello all, Apologies if this has been proposed before I guess, but I have a very simple one: With the increasing importance of LV, I th...
New
BartOtten
I’d like to propose that we refrain from using the term "DeadView" as the opposite of “LiveView” and instead choose an alternative. A new...
New
Matsa59
Lets start by a story, I work with a team on a pretty big CMS with lots of modules. We split the cms using umbrella apps. So we have comp...
New
i-n-g-m-a-r
When debug_errors: true javascript can be executed. <html> <body> <form id="xss" action="https://domain.com/NateMai...
New
superchris
Currently there is no out of the box way to support DOM Custom Events in phoenix. I’ve created a separate library to do this, but I’d lov...
New
dibok
Hi, I’m trying to use phoenix.js in my Qt QML project which has it’s own buildin JavaScript engine. Problem is that (what I googled so f...
New
MatinDevs
Currently, there are ongoing discussions about enhancing Phoenix LiveView, particularly focusing on improving performance and user experi...
New

Other popular topics Top

TunkShif
This post is an instruction guide to help you setup your Neovim for Elixir development from scratch. It includes general information on h...
274 41539 114
New
chrismccord
Phoenix 1.4.0 released Phoenix 1.4 is out! This release ships with exciting new features, most notably with HTTP2 support, improved deve...
688 30877 112
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43622 214
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
boundedvariable
I am going through the kafka architecture. All the features what the kafka is providing are already in Erlang. I would like hear your opi...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New

We're in Beta

About us Mission Statement