Quick & Easy Elixir Refactorings — Part 1
Over the next few blog posts I’ll be covering some quick easy refactorings that could help you tidy up your Elixir codebase.
We’ll go over some patterns you might find in your code and look at simple techniques you can use to hopefully make your code neater, easier to work with in the future and more readable.
In this first post I’ll cover functions that start with a conditional. In following posts we’ll cover functions that start with similar code but with different ends and functions that have something slightly different in the middle among others.
Functions starting with a conditional
This is a pattern I see a lot with people new to Elixir or pattern matching, especially with a good Ruby background where they already have a great practise of writing small functions.
The first thing to happen in these functions is we check something that was passed in.
defmodule Example do def is_zero?(number) do
if number == 0 do
true
else
false
end
endend
Contrived example for sure and first thing you could do is get rid of the useless if structure like this
defmodule Example do def is_zero?(number) do
number == 0
endend
But lets imagine this was little more complicated. What we can do instead is do the conditional branching using pattern matching in the function signature
defmodule Example do def is_zero?(0), do: true
def is_zero?(_), do: falseend
This is particularly nice if you started with a 8–9 line function where both branches had 3 or so lines of code.
This is also handy for case statements
defmodule Example do def send(message) do
case message.type do
:sms ->
# some SMS send code
:email ->
# email send code
:slack ->
# Slack code
_ ->
# Bad type catch
end
endend
becomes something like
defmodule Example do def send(%{type: :sms}) do
# some SMS send code
end def send(%{type: :email}) do
# some email send code
end def send(%{type: :slack}) do
# Slack code
end def send(_) do
# Bad type catch
endend
or even
defmodule Example do def send(%{type: :sms}), do: # some SMS send code
def send(%{type: :email}), do: # some email send code
def send(%{type: :slack}), do: # Slack code
def send(_), do: # Bad type catchend
If your functions start by inspecting the values passed in and branching from there there’s a good chance you can use pattern matching to tidy things up.
Please click the high fives icon below if you liked this post and follow me here and on Twitter @efexen for the next post where we’ll look at more simple tricks for leveling up your Elixir code 👍