I've seen that recommendation often but I still dislike it, since it falls apart whenever you need to do the same logic on multiple pieces of data. It only makes sense if every single with-clause is doing something hugely different.
A simple example:
with {:ok, cleaned_first} <- sanitize(data.first),
{:ok, cleaned_middle} <- sanitize(data.middle),
{:ok, cleaned_last} <- sanitize(data.last),
{:ok, final} <- combine(first, middle, last) do:
{:ok, "Name is" <> final}
else
{:error, :illegal_character} ->
{:error, :illegal_first_name_or_middle_name_or_last_name}
other ->
other
end
The above sucks because it's not clear which data was bad or which step failed.
So let's talk about the alternatives...
__________________
First, the "Lots Of Methods" approach, where you just add as many different private methods as you need, where each one works almost the same except for a distinctly different error:
I feel that sucks because it's tedious, error-prone boilerplate, even if they're just wrappers around a sanitize/1 that does the real work. Also any new error-atoms being introduced are scattered down the file rather than near where you might want to match/test them.
__________________
Second, the "Augment One Method With Causal Data" version:
This is a marginal improvement, but we're still contaminating methods like "sanitize" with junk they don't actually need to know in order to do so their job, passing a piece of opaque data down and up the stack unnecessarily.
__________________
Third, what if we carefully isolate the concerns/complexity to the with-statement... Hey! We're right back to where we started!
The "Augment The With Clauses" approach, which I argue is least-bad:
A simple example:
The above sucks because it's not clear which data was bad or which step failed.So let's talk about the alternatives...
__________________
First, the "Lots Of Methods" approach, where you just add as many different private methods as you need, where each one works almost the same except for a distinctly different error:
I feel that sucks because it's tedious, error-prone boilerplate, even if they're just wrappers around a sanitize/1 that does the real work. Also any new error-atoms being introduced are scattered down the file rather than near where you might want to match/test them.__________________
Second, the "Augment One Method With Causal Data" version:
This is a marginal improvement, but we're still contaminating methods like "sanitize" with junk they don't actually need to know in order to do so their job, passing a piece of opaque data down and up the stack unnecessarily.__________________
Third, what if we carefully isolate the concerns/complexity to the with-statement... Hey! We're right back to where we started!
The "Augment The With Clauses" approach, which I argue is least-bad: