Module.concat semantics?

41 views
Skip to first unread message

Ian Duggan

unread,
Jun 22, 2016, 4:34:17 PM6/22/16
to elixir-lang-talk
Any idea why these are not equivalent?

defmodule Foo do
  defmodule Bar do
    def whoami do
      __MODULE__
    end
  end
end

defmodule Foo do
  defmodule Module.concat([Bar]) do
    def whoami do
      __MODULE__
    end
  end
end

The first defines Foo.Bar.whoami, the second it is Bar.whoami. It seems that if you use Module.concat() you need to give the full path to the module. I can sort of understand why that might be the case with Module.create(), but I don’t get the intuition for Module.concat() since it just spits out Foo.Bar or Bar.

--Ian

Ian Duggan

unread,
Jun 22, 2016, 5:30:42 PM6/22/16
to elixir-lang-talk
Ok, well, I guess I'm still learning my way around the documentation. It has nothing to do with Module.concat() but rather how defmodule deals with dynamic names. I found the below in the Kernel#defmodule docs. Sorry for the noise, and thank you for the great new language!

--Ian


 ## Nesting

  Nesting a module inside another module affects the name of the nested module:
      defmodule Foo do
        defmodule Bar do
        end
      end

  In the example above, two modules - `Foo` and `Foo.Bar` - are created.
  When nesting, Elixir automatically creates an alias to the inner module,
  allowing the second module `Foo.Bar` to be accessed as `Bar` in the same
  lexical scope where it's defined (the `Foo` module).

...


## Dynamic names

  Elixir module names can be dynamically generated. This is very
  useful when working with macros. For instance, one could write:

      defmodule String.to_atom("Foo#{1}") do
        # contents ...
      end

  Elixir will accept any module name as long as the expression passed as the
  first argument to `defmodule/2` evaluates to an atom.
  Note that, when a dynamic name is used, Elixir won't nest the name under the
  current module nor automatically set up an alias.

Reply all
Reply to author
Forward
0 new messages