पाठ 4 / 25

The Match Operator and Pattern Matching

Use = as a match, destructure data and pin values.

= is a match, not assignment

In Elixir, = is the match operator: the left side is a pattern that must match the value on the right, binding any variables in it. x = 1 binds x, but 1 = x is also valid and asserts that x is 1, raising MatchError otherwise. Patterns destructure tuples ({:ok, user} = fetch()), lists ([first | rest] = items), maps (%{city: city} = order, which matches any map containing that key) and binaries (<<"INV-", number::binary>> = "INV-42"). The underscore _ ignores a value, and _name documents an ignored variable. The pin operator ^ matches against an existing variable's value instead of rebinding: ^expected = actual. Pattern matching is everywhere in Elixir: in function heads, case, with, receive and comprehensions. A common idiom is matching on tagged tuples such as {:ok, value} and {:error, reason}, so successful and failed results are handled explicitly rather than with exceptions.

Matching shapes

The pattern on the left must fit the value's shape; variables capture the matching parts.

A stencil with holes on the left lined up over a structured block on the right, with the parts showing through the holes highlighted.
Figure 2.1 — A pattern destructuring a value.

Pattern matching in practice

Tuples, lists, maps, binaries and the pin operator.

{:ok, user} = {:ok, %{name: "Asha", tier: :gold}}
IO.puts(user.name)

[first | rest] = ["pen", "ink", "pad"]
IO.inspect({first, rest})                    # {"pen", ["ink", "pad"]}

%{city: city} = %{id: "o-1", city: "Pune", total: 1200}   # extra keys are fine
IO.puts(city)

<<"INV-", number::binary>> = "INV-2026-42"
IO.puts(number)                              # 2026-42

expected = "o-1"
%{id: ^expected} = %{id: "o-1", total: 99}   # pin: must equal the existing value

try do
  {:ok, _} = {:error, :timeout}
rescue
  e in MatchError -> IO.puts("no match: #{inspect(e.term)}")
end

{_ignored, second, _} = {1, 2, 3}
IO.puts(second)

A shape sorter toy

Pattern matching is a child's shape sorter: a block only goes through the hole with the same shape. If you try the star block in the circle hole, it does not fit, and Elixir tells you with a MatchError.

त्वरित जाँच: What does the pin operator ^ do in a pattern?

  • Rebinds the variable
  • Makes the variable global
  • Matches against the variable's existing value instead of rebinding it
  • Ignores the value
Answer

Matches against the variable's existing value instead of rebinding it — Pinned variables are compared, not rebound.