alias, require, import, use & Module Attributes

Imports are lexically scoped (can be inside a function).

19.1 alias

defmodule MyApp.Accounts do
  alias MyApp.Accounts.User                 # now User
  alias MyApp.Repo, as: R                   # R
  alias MyApp.{Billing, Mailer}             # multi-alias
end

19.2 import

Imports are lexically scoped (can be inside a function).

import Enum, only: [map: 2, filter: 2]
import String, except: [split: 1]
import MyHelpers, only: :functions          # or :macros, :sigils
map([1, 2], &(&1 + 1))

19.3 require

Required to use macros from another module:

require Logger
Logger.info("hello")
require Integer
Integer.is_odd(3)

19.4 use

use Module, opts calls Module.__using__(opts) macro which injects code:

Use use sparingly; prefer explicit import/alias.

defmodule MyTest do
  use ExUnit.Case, async: true
end

19.5 Module attributes

Special attributes: @moduledoc, @doc, @spec, @type, @typep, @opaque, @callback, @macrocallback, @behaviour, @impl, @derive, @enforce_keys, @compile, @deprecated, @before_compile, @after_compile, @on_definition, @on_load, @external_resource, @dialyzer, @vsn.

Accumulating attributes:

Runtime vs compile time: @attr is evaluated at compile time. For runtime config use Application.get_env/3 or Application.compile_env/3 (explicitly compile-time).

defmodule Config do
  @moduledoc "Configuration helpers."
  @default_timeout 5_000                    # compile-time constant
  @supported ~w(json xml)a

  @doc "Returns the default timeout."
  @spec timeout() :: pos_integer()
  def timeout, do: @default_timeout

  def supported?(fmt), do: fmt in @supported
end
Module.register_attribute(__MODULE__, :routes, accumulate: true)
@routes "/a"
@routes "/b"