jonnifyelixir
F3 / F3.05 / defaults

F3.05 · part 2 of 3

Enforcing keys & defaults

A bare defstruct makes every field optional and nil by default. Two additions tighten that: @enforce_keys marks fields that must be given, raising at build time when one is missing, and a keyword form of defstruct sets default values for the rest.

A portal learner has no meaning without an email, so :email is enforced. A new learner is a :student and active until told otherwise, so those carry defaults. Choose what the caller supplies and watch the struct build — or refuse to.

Building with what is given

The struct enforces :email and defaults role: :student and active: true. Each field below is coloured by where its value comes from — supplied by the caller, filled from a default, or missing.

What the caller supplies · select one

FIELDS WHEN BUILDING email: "ada@portal.dev" supplied role: :student default active: true default struct built

      

Defaults remove boilerplate for the common case; @enforce_keys turns a missing essential field into an error at the moment of construction, not a nil discovered later.

Declaring required keys and defaults

@enforce_keys is a module attribute listing the required fields; the keyword form of defstruct pairs the rest with defaults. A field can be enforced or defaulted, not both — a default already guarantees a value.

defmodule Portal.Accounts.User do
  @enforce_keys [:email]
  defstruct [:email, role: :student, active: true]
end

%User{email: "ada@portal.dev"}
# => %User{email: "ada@portal.dev", role: :student, active: true}

%User{role: :admin}
# ** (ArgumentError) the following keys must also be given
#    when building struct Portal.Accounts.User: [:email]

The idea

Some fields are essential and some have a sensible starting value — the contract of a record.

In Elixir

@enforce_keys raises when an essential field is absent; defstruct defaults fill the rest.

Next: matching on a struct's type — using the __struct__ tag to dispatch by shape.

References

Primary sources for this lesson, and where it connects in the course.

Sources

Related in this course