`alias` all modules of a project, as a good baseline for a project-root's .iex.exs

How can I alias all modules of a project?

Mix.Project.apps_paths 
|> Map.keys
|> Enum.flat_map(&:application.get_key(&1, :modules) |> elem(1)) 

I’m eyeing Code.eval_string, but not sure how to use it. I could continue above pipeline with, say

|> Enum.map(&IO.inspect "alias #{&1}") 
|> Enum.join("\n")

but still lost.

(Above is a bit half-baked, but would be grateful if anyone immediately sees the solution.)

Why do you want to alias all modules? What are you aiming to do?

1 Like

Ah yes. To avoid the XY problem: I’d like to have a ‘good enough’ and uniform solution for aliasing in the project’s root .iex.exs file, across disparate projects. This would serve as a quick mean to get to the ‘leaves’ of namespaces.

And if the ordering might be off, f.e., if the above automated ‘batch aliasing’ would effectively do

alias Foo.Bar
alias Foo.Bar.Bar

but I’d like the direct access to the first Bar, I can still override it with an additional/manual alias:

alias Foo.Bar

I came up with this code block that allows me to load all project aliases for the quick terminal usage

defmodule Console do
  defmacro aliases(expression) do
      {:ok, modules} = :application.get_key(:<YOUR_APP>, :modules)
  
      modules =
        for module <- modules do
          quote do
            alias unquote(module)
          end
        end
  
      quote do
        unquote(modules)
        unquote(expression)
      end
  end
end

So now I can execute something like this:

iex(10)> require Console
iex(11)> Console.aliases Repo.all(Room)
[
  %Tarragon.Battles.Room{
    __meta__: #Ecto.Schema.Metadata<:loaded, "battle_rooms">,
    id: 1,
...
1 Like