For comparison, this:
defmodule Person do
defstruct [:name, :age]
end
struct = %Person{name: "Kelvin", age: 26}
Would be something like this:
defmodule Person do
use Ecto.Schema
import Ecto.Changeset
embedded_schema do
field :name, :string
field :age, :integer
end
def new(attrs) do
%Person{}
|> cast(attrs, [:name, :age])
|> apply_changes()
end
end
struct = Person.new(%{name: "Kelvin", age: 26})
Of course it’s not fair to compare because the second one actually would handle a lot more of cases, like maps with string keys, and even would properly cast "26"
to 26
on the age attribute. But if the one that is giving you these data is yourself (or another programmer), why bother about casting or string keys?
And even if you needed to guarantee the person would have the correct type, I would then first do something like:
defmodule Person do
defstruct [:name, :age]
def new(%{name: name, age: age}) when is_bitstring(name) and is_integer(age) do
%Person{name: name, age: age}
end
end
This way, if the programmer make the mistake, he/she will get a FunctionClauseError
, instead of just ignoring his mistake of giving a string for the person age.