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 use
d ModA
it generated an import
statement that was inserted into ModB
.
use
is intended for injecting code into the current module, while import
is used to, well, import functions for use. You can build a use
implementation which automatically imports functions for example, as I do with Timex when you add use Timex
to a module, take a look at timex.ex if you want to know what I mean, it's a very simple example of how to build a module which can be use
'd
See «alias, require, and import» page from the elixir official getting started guide:
# Ensure the module is compiled and available (usually for macros)
require Foo
# Import functions from Foo so they can be called without the `Foo.` prefix
import Foo
# Invokes the custom code defined in Foo as an extension point
use Foo
Require
Elixir provides macros as a mechanism for meta-programming (writing code that generates code).
Macros are chunks of code that are executed and expanded at compilation time. This means, in order to use a macro, we need to guarantee its module and implementation are available during compilation. This is done with the require
directive.
In general a module does not need to be required before usage, except if we want to use the macros available in that module.
Import
We use import
whenever we want to easily access functions or macros from other modules without using the fully-qualified name. For instance, if we want to use the duplicate/2
function from the List
module several times, we can import it:
iex> import List, only: [duplicate: 2]
List
iex> duplicate :ok, 3
[:ok, :ok, :ok]
In this case, we are importing only the function duplicate
(with arity 2) from List
.
Note that import
ing a module automatically require
s it.
Use
Although not a directive, use
is a macro tightly related to require
that allows you to use a module in the current context. The use
macro is frequently used by developers to bring external functionality into the current lexical scope, often modules.
Behind the scenes, use
requires the given module and then calls the __using__/1
callback on it allowing the module to inject some code into the current context. Generally speaking, the following module:
defmodule Example do
use Feature, option: :value
end
is compiled into
defmodule Example do
require Feature
Feature.__using__(option: :value)
end