Is there a way to have multiple aliases, but to use as: acronym for one of them, something like this, but that actually works
alias Guard.Rbac.{Cache, RoleBindingIdentification, as: RBI}
Is there a way to have multiple aliases, but to use as: acronym for one of them, something like this, but that actually works
alias Guard.Rbac.{Cache, RoleBindingIdentification, as: RBI}
What you show in best case could work as:
alias Guard.Rbac, as: RBI
alias Guard.Rbac.{Cache, RoleBindingIdentification}
Thatâs because opts
are on same level as other aliases.
Alternatively Elixir
could support this:
alias Guard.Rbac.{Cache, {RoleBindingIdentification, as: RBI}}
However this looks just ugly and I guess thatâs why it would be not supported at all. If you have an interesting idea how to improve that then feel free to create a proposal, but so far I do not see either a use case nor how it could look good at all.
Also keep in mind that even if such ugly-looking feature would be supported then it would be still formatted into multiple lines, so it would look like:
alias ParentName.{
{ChildA, as: A},
ChildB,
{ChildC, as: C}
}
I believe that keeping aliases work as itâs now is best.
This is exactly what I meant I dont agree that this is âugly lookingâ. Elixir already supports this notation:
alias ParentName.{
ChildA,
ChildB,
ChildC
}
and I donât see how this is any prettier (or less âugly-lookingâ) then the example above where abbreviations are supported.
True, situations where something like this would be needed are rare, but option 1:
alias Guard.Repo.{
RbacUser,
UserGroupBinding,
RbacRole,
{OrgRoleToProjRoleMapping, as: Mapping}
RoleInheritance,
SubjectRoleBinding,
{RoleBindingIdentification, as: RBI}
Permission,
Scope
}
IMO looks cleaner then option 2:
alias Guard.Repo.OrgRoleToProjRoleMapping, as: Mapping
alias Guard.Repo.RoleBindingIdentification, as: RBI
alias Guard.Repo.{
RbacUser,
UserGroupBinding,
RbacRole,
RoleInheritance,
SubjectRoleBinding,
Permission,
Scope
}
I donât understand what thatâs trying to specify. In this case, one is able to guess, though.
For me personally, I enforce the Credo.Check.Readability.AliasAs
and Credo.Check.Readability.MultiAlias
Credo checks for alias
, among others. So the alias ___.{___}
syntax and alias ___, as: ___
are not allowed.
Mutli aliasing is really only useful in very specific scenarios. It makes copying module names harder (impossible rather), and it starts to look ugly and busy when you have a lot of modules that arenât just under a single ânamespaceâ. Simply typing out the shared ânamespaceâ is really not difficult.
I personally feel that alias ___, as: ___
should be used extremely sparingly if not removed from the language. Itâs use is usually an indication that the module it is as
ing is poorly named. And I have certainly seen it heavily abused where the module was essentially renamed with as
.
For the proposed:
alias Guard.Repo.{
RbacUser,
UserGroupBinding,
RbacRole,
{OrgRoleToProjRoleMapping, as: Mapping}
RoleInheritance,
SubjectRoleBinding,
{RoleBindingIdentification, as: RBI}
Permission,
Scope
}
it requires a fair amount of tracing to understand. I would suggest renaming the longer modules. RoleBindingIdentification
could be RoleBindingId
or even just RBI
if you documented it with @moduledoc
and the abbreviation is clear in the context. OrgRoleToProjRoleMapping
should probably just be renamed.
Using rarely, yes. Removing? No!
We have a codebase with more than 600 modules at work.
There are several modules ending in Product
, within Schema
, Dataloader
, and what not prefixes. We do not want to repeat the type in the module name itself, therefore we are happy to be able to use :as
in an alias
.
Removed was a bit of a hyperbole. I know it wonât and probably shouldnât happen in Elixir. Although, certainly several other languages, such as F#, do not have that feature, and I personally donât miss it there. Iâm not aware of it being in Erlang. Is that correct?
For Elixir, I got a bad taste for it at my previous company, where its use was definitely a symptom of poorly named modules. So many modules had such extremely similar names that as: ___
was used to mitigate this in modules and in tests. The moral of the story is that people will often take conveniences and turn them into hazards.
And how do you deal with external librarie modules?
Erlang doesnât have module aliasing at all.
Iâd say the biggest reason why as:
is bad because if you wanted to do a global search and replace during refactoring, it makes it much more difficult.
Same with alias Module.{âŠ}
I use neither in my codebases.
Ya, Iâm not a huge fan of {}
(though it has its uses though wouldnât miss them if they were gone) and never use :as
. I even avoid just plain old alias
a lot of the time unless it provides significant noise-reduction.
One of the big things that drew me to Elixir was the high level of locality that is encouraged through official examples. Iâm even just talking things like, Enum.map
as opposed to import Enum, only: [:map, 2]
. Jumping into a function to gain a bit of context on its caller and being able to see all its dependencies without having to jump any further is a really nice feeling. Of course, itâs a balance, but I feel that often there is a subconscious emphasis put on writeability or even âprettinessâ over readability and, more importantly, âscannabilityâ.
And of course the other thing I really like about Elixir is how relatively small it is and how much thought is put into backwards incompatible changes. Just by that alone, I donât see something like nested :as
es ever making it in (not that you were necessarily suggesting they would be). Take this really well-thought-out proposal for field punningâa featured loved by many in other languages (not me)âthat was rejected, for example.
Yes, there is!
Behold the dark art of context magic in Elixir
alias (alias Guard.Rbac, as: RBI).{Cache, RoleBindingIdentification}
Please do not try this at home
If I understand correctly, in your example RBI.Cache
would âexpandâ to Guard.Rbac.Cache
, and same go for RBI.RoleBindingIdentification
which would expand to Guard.Rbac.RoleBindingIdentification
, right?
How about:
alias Guard.Rbac
alias Rbac.{Cache, Other, Baz}
alias Rbac.SomethingReallyLong, as: Long
alias Long.{Child, Child2}
Itâs a little more but is easy to read.
Yes, thatâs correct