#Relative aliasing in Elixir

10 messages Β· Page 1 of 1 (latest)

agile linden
#

Hey πŸ‘‹ , I have about a year of experience developing in Elixir, and comming from Python I really wish there was a way to have relative aliases from the current module.

For example, consider this project structure:

# I know elixir modules are independent from the file structure but it's easier to visualize it this way (I think)
.
└── app/
    └── some_module/
        └── some_other_module/
            └── pipeline/ 
                β”œβ”€β”€ pipeline.ex   # App.SomeModule.SomeOtherModule.Pipeline
                β”œβ”€β”€ extract.ex    # App.SomeModule.SomeOtherModule.Pipeline.Extract
                β”œβ”€β”€ transform.ex  # App.SomeModule.SomeOtherModule.Pipeline.Transform
                └── load.ex       # App.SomeModule.SomeOtherModule.Pipeline.Load

If I want to alias Extract inside Pipeline then I would have to do something like:

defmodule App.SomeModule.SomeOtherModule.Pipeline do
    alias App.SomeModule.SomeOtherModule.Pipeline.Extract

    ...
end

Which is fine, but seems redundant. This specially bugs the more levels deep we get into the project.

A Python-esque way of aliasing would be:

defmodule App.SomeModule.SomeOtherModule.Pipeline do
    alias .Extract

    def foo do
        Extract.run()
    end
    ...
end

Which would append the atom to the current module. This obviously doesn't work, but you get what I'm getting at.

Something I've been toying with it's this implementation:

defmodule App.SomeModule.SomeOtherModule.Pipeline do
    def foo do
        __MODULE__.Extract.run()
    end
    ...
end

Which gets the job done, but kind of obscures the fact that I'm using another module.

So I'm wondering if you've had this situation in your projects and if so, how have you tackled it?
Thanks! πŸ™Œ

sharp swan
#

It’s idiomatic in elixir to just alias whole module paths, as you’ve done in your first example.

#

If that’s too much typing, I think you can do alias __MODULE__.Extract

#

But I’ve never seen that done

agile linden
#

I see, so absolute alias it's the official way then.
I'll discuss with my team what they think about the alias __MODULE__.Extract thing, it seems like a good enough approach for our use case πŸ€”
Thank you!

plush gorge
#

Elixir has a very powerful meta programming layer... so here's some fun with macros! (To be clear, alias __MODULE__.Extract is a much better solution imo.)

defmodule RelativeAliases do
  defmacro ralias({:__aliases__, _metadata, mods}) do
    {:alias, [context: __CALLER__.module],
     [{:__aliases__, [alias: false], [__CALLER__.module] ++ mods}]}
  end
end

Then use it:

defmodule SomeModule.SomeOtherModule.Pipeline do
  import RelativeAliases
  ralias Extract

  def foo do
    Extract.run()
  end
end
agile linden
#

That's pretty cool!
I agree that alias __MODULE__.Extract seems to be the better solution.

sharp swan
#

I'd still try to convince the team that explicit aliases are what you want.

#

i have seen some people suggest alias __MODULE__ for use with structs though

#

...but that's not refactor friendly