Pattern Match Keyword List in Function Def
TIL that you can pattern match a keyword list in a function definition.
Sometimes you'll receive the last argument as an empty keyword list; in this case, we're calling it opts
. You can pattern match key-values by defining the shape in a function.
defmodule Example do
def hello(opts \\ [])
# will match when message is the only keyword included in opts
def hello([message: message]) do
IO.puts("Hello #{message}")
end
# will match when there are multiple keywords but message is the first
def hello([{:message, message} | _rest] = opts) do
IO.puts("Hello #{message}")
end
end
> Example.hello(message: "World")
Hello World
:ok
# could also call in the more verbose way
> Example.hello([message: "World"])
Hello World
:ok
# :message but with other args after
> Example.hello(message: "World", something_else: "hi")
Hello World
:ok
Note: As a TIL reader pointed out, pattern matching Keywords will make your function args order dependent. The following would not work:
> Example.hello(foo: "bar", message: "World")
** (FunctionClauseError) no function clause matching in Example.hello/1
If you need them to be order independent, use a map
or just match on single argument, then check for each option appropriately with the Keyword module.
https://elixir-lang.org/getting-started/keywords-and-maps.html
Tweet