Elixir: use vs import

import Module brings all the Functions and Macros of Module un-namespaced into your module.

require Module allows you to use macros of Module but does not import them. (Functions of Module are always available namespaced.)

use Module first requires module and then calls the __using__ macro on Module.

Consider the following:

defmodule ModA do
  defmacro __using__(_opts) do
    IO.puts "You are USING ModA"
  end

  def moda() do
    IO.puts "Inside ModA"
  end
end

defmodule ModB do
  use ModA

  def modb() do
    IO.puts "Inside ModB"
    moda()     # <- ModA was not imported, this function doesn't exist
  end
end

This will not compile as ModA.moda() has not been imported into ModB.

The following will compile though:

defmodule ModA do
  defmacro __using__(_opts) do
    IO.puts "You are USING ModA"
    quote do          # <--
      import ModA     # <--
    end               # <--
  end

  def moda() do
    IO.puts "Inside ModA"
  end
end

defmodule ModB do
  use ModA

  def modb() do
    IO.puts "Inside ModB"
    moda()            # <-- all good now
  end
end

As when you used ModA it generated an import statement that was inserted into ModB.

Leave a Comment