Elixir: use vs import

User314159 picture User314159 · Feb 13, 2015 · Viewed 21.8k times · Source

What's the difference between use and import?

use is a simple mechanism for using a given module into the current context

https://hexdocs.pm/elixir/Kernel.SpecialForms.html#import/2

Imports function and macros from other modules

Looks like one difference is import let's you pick out the specific functions/macros whereas use brings everything in.

Are there other differences? When would you use one over the other?

Answer

greggreg picture greggreg · Feb 13, 2015

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.