Unexpected generated module name when playing with AST

That is wrong. It seems that this is equivalent but it isn’t.

defmodule Foobar do
  def test do
    IO.inspect(__MODULE__, label: :a)
    IO.puts("b: #{__MODULE__}")
    module = inspect(__MODULE__)
    IO.inspect(module, label: :c)
    IO.puts("d: #{module}")

    name = "Search"

    module_name = "#{module}.#{name}"
    IO.inspect(module_name, label: :module_name)
    IO.puts("module_name: #{module_name}")

    module_concat = Module.concat([module, name])
    IO.inspect(module_concat, label: :module_concat)
    IO.puts("module_concat: #{module_concat}")
  end
end
iex(1)> Foobar.test
a: Foobar
b: Elixir.Foobar
c: "Foobar"
d: Foobar
module_name: "Foobar.Search"
module_name: Foobar.Search
module_concat: Foobar.Search
module_concat: Elixir.Foobar.Search

So, if your macro returns defmodule Elixir.SomeModule ... the module will be generated in the Elixir namespace when it returns defmodule SomeModule it will work as nested module. In my code the generated module name is Elixir.ControllerA.MiniParams.Search.

Edit: :thinking: - My last sentence isn’t 100% correct. I think there is one point I am missing.

1 Like