home
Elixir: A Case for Less /case/
In Elixir one has a wonderful `case` statement to use:
@spec check_calendar(date()) :: {[date_slot()], [info_atom()]}
def check_calendar(date) do
case Calendar.check(date) do # Reads from database adds some more logic
:free -> Calendar.show_day(date)
:off -> {[], [:day_off]}
{:available, slots} when slots < 3 -> {Calendar.grab_slots(date), [:busy]}
{:available, slots} when slots > 10 -> {Calendar.grab_slots(date), [:recommended]}
{:available, slots} -> {Calendar.grab_slots(date), []}
end
end
It’s a perfectly good function, but I have few issues with it.
From looking at it, I don’t know what happens when Database adapter error happens. Do I need to catch it? Of course, I could assume it won’t due to lack of “!” but unfortunatelly I cannot have any guarantees for that.
Second is, that if I’d like to test the logic (I would like to
question - what happens when I receive {:available, -1} which is an obvious error, but hey, could happen - I can’t.
This function relies on side effect.
But I’d like to propose a simple change:
def check_calendar(date), do: check_calendar_result(date, Calendar.check(date))
def check_calendar_result(date, :free), do: {Calendar.build_slots(date), []}
def check_calendar_result(_, :off), do: {[], [:day_off]}
def check_calendar_result(date, {:available, slots}) when slots < 3,
do: { Calendar.grab_slots(date), [:busy] }
def check_calendar_result(date, {:available, slots}) when slots > 10,
do: { Calendar.grab_slots(date), [:busy] }
def check_calendar_result(date, {:available, _}),
{ do: Calendar.grab_slots(date), [] }
Logic remains the same, few benefits:
- I can unit test logic function easier
- Dialyzer can pick up function headers and catch potential errors
- It’s very easy to separate behavior that can even further ease testing, e.g
# ...
def check_calendar_result(date, {:available, _}),
{ do: calendar_impl().grab_slots(date), [] }
def calendar_impl do
Application.fetch_env(:my_application, :calendar_impl, Calendar)
end
Przemysław Alexander Kamiński
vel xlii vel exlee
Powered by hugo and hugo-theme-nostyleplease.