Pattern matching structs (why order is important)
When pattern matching structs with maps, many people don't consider the consequences of order.
Say we have a user:
defmodule User do; defstruct [:name, :age] end
This will match just fine:
iex()> %{name: nil, age: nil} = %User{}
%User{age: nil, name: nil}
While the reverse will not:
iex()> %User{} = %{name: nil, age: nil}
Bug Bug ..!!** (MatchError) no match of right hand side value: %{age: nil, name: nil}
If you care to know why:
When pattern matching maps, the right side value must contain all the keys. In our example above, it appears they do:
iex()> inspect(%User{})
"%User{age: nil, name: nil}"
But looks can be deceiving:
iex()> inspect(%User{}, structs: false)
"%{__struct__: User, age: nil, name: nil}"
With our newfound knowledge, lets try again:
iex()> %User{} = %{name: nil, age: nil, __struct__: User}
%User{age: nil, name: nil}
🎉
Tweet