Writing better elixir code
Using typespecs
- helps you reason about your code better, think about all possible paths
Keep everything seperated
- can be easy to write a module with another module in mind and end up returning values or creating logic that fits in the context of that module. i find that to be unhelpful in the long run. while they can interact with each other, keep those return values sepearate
- a crude example
defmodule MyApp.Workers.MyWorker do
use Oban
def process() do
MyWorkerHelper.call(status)
end
end
defmodule MyApp.MyWorkerHelper do
def call(status) do
case status do
# These return values are specific to Oban
:error -> {:cancel, :error}
:processing -> {:snooze, 60}
_ -> :ok
end
end
end
The tuples {:cancel, _} and {:snooze, _} are specific to Oban and let it know how to process the job. While we can have the worker helper return those values directly, what if the helper needs to be repurposed to fit other needs to specific to the worker? I find it better to just have the helper not know about the other modules and return it's own values. This way, it's up to the worker to process the results and act accordingly. Here's a reworked example:
defmodule MyApp.Workers.MyWorker do
use Oban
def process() do
case MyWorkerHelper.call(status) do
{:error, error} -> {:cancel, error}
:processing -> {:snooze, 60}
_ -> :ok
end
end
defmodule MyApp.MyWorkerHelper do
def call(status) do
case status do
# These return values are specific to Oban
:error -> {:error, "some error"}
:processing -> :processing
_ -> :ok
end
end
end
obviously, this code doesn't make total sense but I think it gets my point across.