We can't find the internet
Attempting to reconnect
Something went wrong!
Hang in there while we get back on track
Reject unknown struct keys with struct!/2
almirsarajcic
Use struct!/2 when runtime attributes must contain only fields that belong to the struct.
defmodule Profile do
@enforce_keys [:name]
defstruct [:name, role: :member]
end
attrs = [name: "Ada", roel: :admin]
struct(Profile, attrs)
# => %Profile{name: "Ada", role: :member}
struct!(Profile, attrs)
# ** (KeyError) key :roel not found
struct/2 silently ignores keys the struct does not know. That can be useful when deliberately taking a compatible subset, but it can also turn a typo such as :roel into a successful-looking value that kept the default :role.
struct!/2 emulates struct literal checks at runtime. It rejects unknown fields, and when its first argument is a module, it also enforces fields declared with @enforce_keys. When its first argument is an existing struct, it validates keys like %Profile{profile | role: :admin} does.
String keys are invalid too. Do not solve that by calling String.to_atom/1 on external input. Convert only an explicit allowlist of accepted fields, then pass the result to struct!/2.
copied to clipboard