Kernel.SpecialForms.case

You're seeing just the macro case, go back to Kernel.SpecialForms module for more information.
Link to this macro

case(condition, clauses)

View Source (macro)

Matches the given expression against the given clauses.

Examples

case File.read(file) do
  {:ok, contents} when is_binary(contents) ->
    String.split(contents, "\n")

  {:error, _reason} ->
    Logger.warning "could not find #{file}, assuming empty..."
    []
end

In the example above, we match the result of File.read/1 against each clause "head" and execute the clause "body" corresponding to the first clause that matches.

If no clause matches, an error is raised. For this reason, it may be necessary to add a final catch-all clause (like _) which will always match.

x = 10

case x do
  0 ->
    "This clause won't match"

  _ ->
    "This clause would match any value (x = #{x})"
end
#=> "This clause would match any value (x = 10)"

Variable handling

Note that variables bound in a clause do not leak to the outer context:

case data do
  {:ok, value} -> value
  :error -> nil
end

value
#=> unbound variable value

Variables in the outer context cannot be overridden either:

value = 7

case lucky? do
  false -> value = 13
  true -> true
end

value
#=> 7

In the example above, value is going to be 7 regardless of the value of lucky?. The variable value bound in the clause and the variable value bound in the outer context are two entirely separate variables.

If you want to pattern match against an existing variable, you need to use the ^/1 operator:

x = 1

case 10 do
  ^x -> "Won't match"
  _ -> "Will match"
end
#=> "Will match"

Using guards to match against multiple values

While it is not possible to match against multiple patterns in a single clause, it's possible to match against multiple values by using guards:

case data do
  value when value in [:one, :two] ->
    "#{value} has been matched"

  :three ->
    "three has been matched"
end