Modeling with Structs in Elixir
Notes
Tasty Sugar
So, in terms of collections, we have lists, maps, tuples, and now keyword lists? Well, kinda. Keyword lists are actually just a tiny dose of syntactic sugar.
For example, here’s the keyword list we passed to the defstruct macro:
[ method: "", path: "", resp_body: "", status: nil ]Internally, keyword lists are represented as a list of tuples containing two values: an atom (the key) and the associated value. Here’s what that looks like for the keyword list above:
[ {:method, ""}, {:path, ""}, {:resp_body, ""}, {:status, nil} ]So keyword lists aren’t yet another collection, but rather a tasty mashup of lists and tuples.
Keyword lists are most commonly used as a simple list of options. In contrast, maps are the go-to data structure for storing key/value pairs.
Updating Structs
In the video, we changed the pattern in the route function heads to verify that the argument is a Conv struct. For example:
def route(%Conv{ method: "GET", path: "/wildthings" } = conv) do
%{ conv | status: 200, resp_body: "Bears, Lions, Tigers" }
endWe didn’t need to change the expression in the function body because the syntax for updating a struct is just like updating a map.
However, we could have changed the update syntax to stipulate a Conv struct, like so:
%Conv{ conv | status: 200, resp_body: "Bears, Lions, Tigers" }The difference is this verifies that the value being updated (conv) is indeed a struct of the type Conv, not a generic map. In this particular case, the extra check doesn’t gain us anything since the pattern in the function head requires the argument to be a Conv type. But sometimes it’s worth adding that extra type safety check.
To see what happens if we try to update a plain map, try this in an iex session:
iex> map = %{method: "GET", path: "/wildthings"}
%Servy.Conv{ map | status: 200, resp_body: "Bears, Lions, Tigers" }
** (BadStructError) expected a struct named Servy.Conv, got: %{method: "GET", path: "/wildthings"}This is yet another compile-time check that comes with using a struct as compared to a map.
Code So Far
The code for this section is in the structs directory found within the video-code directory of the code bundle
Why always me?