Subscribe to access all episodes. View plans →
Published December 11, 2017
Elixir 1.4.5
One of features that makes Elixir such a great language is pattern matching.
In fact, in Elixir, the equals sign is called the match operator.
Let’s see why.
Let’s fire up iex
and start with a simple example and set the string “a” to the variable a
.
> a = "a"
"a"
And then let’s put the string “a” on the left side and our variable a
on the right side.
> "a" = a
"a"
And because these match, meaning the left side equals the right side, the string “a” was returned.
Now let’s see what happens if the two sides are not equal.
> "b" = a
** (MatchError) no match of right hand side value: "a"
Elixir tells us there’s a MatchError
- because both sides of the equals sign don’t match.
While this is a simple example, it does illustrate a good idea to keep in mind when doing pattern matching in Elixir - both sides of the equal sign need to match.
Now explore a few different ways we can use it.
One way we can use it is to pull values from different data structures by matching on them.
Let’s first try it with a map.
We’ll create create a map with some info about a person:
> person = %{name: "bill", age: 25}
%{age: 25, name: "bill"}
Now if we wanted to grab the name
and age
from our person map how could we do that with pattern matching?
Let’s try this - we’ll create a map on the left side, with name
and age
as variables for their respective keys. And if both sides of the equal sign match, our variables will be updated with the corresponding values.
> %{name: name, age: age} = person
%{age: 25, name: "bill"}
And it looks like it worked.
The variable age
has been updated with the age of our person:
> age
25
And the variable name
has been updated with the name:
> name
"bill"
Now let’s test out pattern matching with a list.
We’ll create a list of colors and we use pattern matching to deconstruct the whole list:
> colors = ["red", "blue", "green"]
> [red, blue, green] = colors
["red", "blue", "green"]
And now we see all of our variables have been updated to their corresponding element in the list.
> red
"red"
> blue
"blue"
> green
"green"
You’ll also see pattern matching play a role in another common pattern used in Elixir to break apart lists - specifically to separate the first element, or head, of the list from the remainder, or tail.
Let’s try it with our same list.
> [ head | tail ] = colors
["red", "blue", "green"]
And the head
variable is now the string “red”.
> head
"red"
While the tail
is a list made up of our original list minus the first element.
> tail
["blue", "green"]
As you write more Elixir, you’ll see pattern matching everywhere. And another common example is using an OK/Error tuple.
Let’s see what one looks like.
We’ll create our “OK” tuple where the first element is the atom :ok
, and for the second element, we’ll create a message.
> data = {:ok, "Success"}
{:ok, "Success"}
And the we can grab our message by creating another tuple on the left side, that has the same atom :ok
and then a variable that we can use to assign the second element in the tuple - the message.
> {:ok, msg} = data
{:ok, "success"}
> msg
"success"
And since both sides matched, the msg
variable is now the string “Success”.
Now let’s take this example and build on it.
Imagine we have some movie API that responds with this structure when we try to create a movie with it.
Let’s create a function that will parse the response - grabbing either the success or error message - and return it.
Let’s create a file matcher.exs
Then we’ll create our new module Matcher
And inside we’ll define a function, get_msg
, which will take our APIs response.
Then inside the function we’ll use a case statement to pattern match on the contents of the response.
If the first element in the response tuple is the atom :ok
our first statement will execute.
And if the first element in the response tuple is the atom :error
our second statement will execute.
matcher.exs
defmodule Matcher do
def get_msg(response) do
case response do
{:ok, msg} ->
"Success: #{msg}"
{:error, msg} ->
"Error: #{msg}"
end
end
end
Now let’s go to the command line and since this is a .exs
file we can load it in iex with:
$ iex matcher.exs
Let’s create our success response. Then let’s pass that into our get_msg
function
> success_response = {:ok, "Movie was created"}
{:ok, "Movie was created"}
> Matcher.get_msg(success_response)
"Success: Movie was created"
And it returns our success message.
Now for our error response:
> error_response = {:error, "Problem creating the movie"}
{:error, "Problem creating movie"}
> Matcher.get_msg(error_response)
> "Error: Problem creating movie"
And our error message was returned.
mpchean
5 years agoIt would be nice to have a course guide that points to the episodes in some kind of order. It doesn’t seem meaningful to go from this to Moving to Elixir part 1
Alekx
5 years agoMost of the episodes are a la carte (with a few exceptions), but I think a guide to help get started with Elixir is a great idea.