elt547
What is the most idiomatic way to construct structs with complex default values?
I have a struct representing a session request with only two fields, email and bytes. Basically the struct should either be passed around as immutable or created with a default value as a function return value. I have a function random_bytes which I want to be the default value of bytes.
Since you can’t declare it like this:
defstruct [:email, bytes: random_bytes()]
Someone suggested making a “new” function:
def new(email) do
%__MODULE__{email: email, bytes: random_bytes()}
end
But to me this feels very non-idiomatic. It feels like shoehorning an object oriented pattern into a functional language.
What is the best way to build a strict with a complex default value in elixir?
Most Liked
tomkonidas
why not add another function to handle that?
def with_random_bytes(%Email{} = email) do
Map.put(email, :bytes, random_bytes())
end
Then in your context or anywhere else you need it can always just call it like:
%Email{}
|> Email.with_random_bytes()
|> ...
zachallaun
There’s no difference, really.
def with_random_bytes(struct) do
Map.put(struct, :bytes, random_bytes()
end
…
%MyStruct{email: email}
|> MyStruct.with_random_bytes()
However, I think new is the way to go. Don’t overcomplicate things. Document that new structs should be created using the initializer in order to set dynamic defaults.
msimonborg
Are Map.new, Range.new, and MapSet.new non-idiomatic? ![]()
100% agree, Session.new(email) or Session.new(opts) with documentation feels right IMO.







