sb logoToday I Learned

Using the Keyword module for options

You should consider using Keyword.fetch!/2 and Keyword.get/3 for options to APIs.

Without options

defmodule MyApp do
  def config(name, author \\ "Herminio Torres", description \\ "Description") do
    %{
      name: name,
      author: author,
      description: description
    }
  end
end
iex> MyApp.config
config/1    config/2    config/3
iex> MyApp.config("my_app")
%{
  author: "Herminio Torres",
  description: "Description",
  name: "my_app"
}
iex> MyApp.config("my_app", "Change")
%{
  author: "Change",
  description: "Description",
  name: "my_app"
}
  • Creates a config function with many arities
  • You are forced to pass all paramaters when you intend to change just the last default argument.

With Options

defmodule MyApp do
  def config(opts) do
    name = Keyword.fetch!(opts, :name)
    author = Keyword.get(opts, :author, "Herminio Torres")
    description = Keyword.get(opts, :description, "Description")
    
    %{
      name: name,
      author: author,
      description: description
    }
  end
end
iex> MyApp.config([])
** (KeyError) key :name not found in: []
    (elixir 1.12.3) lib/keyword.ex:420: Keyword.fetch!/2
    iex:3: MyApp.config/1
iex> MyApp.config([name: "my_app"])
%{
  author: "Herminio Torres",
  description: "Description",
  name: "my_app"
}
iex> MyApp.config([name: "my_app", description: "Change"])
%{
  author: "Herminio Torres",
  description: "Change",
  name: "my_app"
}
  • The raised error leads you to which options are required
  • Keyword lists make the arguments named
  • Only one function arity is exposed

Awesome!