Errata: 10/15/2018
Unless otherwise noted, all corrections have been made to all versions.

Thank you for purchasing The Little Elixir & OTP Guidebook. Please post any errors, other than those listed below, in the book's Author Online Forum. We'll update this list as necessary. Thank you!


Page 10, Listing 1.1

...use GenServe4r...
should be:
...use GenServer...

Page 15-16, Section 2.2.3

This correction hasn't been made to avoid introducing new errors.

The Dict module has been deprecated in favor of Map. Therefore the examples might display a Warning this module is deprecated warning. Simply replace Dict with Map.

Page 23, Section 2.4

In the example, the extra space should be removed to eliminate a "unexpected parentheses" warning:

MeterToLengthConverter.convert(:feet, "smelly")

Page 42, Section 3.2.1, Installing the Dependencies

Certain dependencies in Elixir must be started in a specific way; such dependencies are declared in the application function.

Page 79, Listing 4.15

The reset_stats function definition is missing a closing ):

GenServer.cast(@name, :reset_stats) 

Page 92, Section 5.1.5

In order for the example to work, the reader must start from a fresh shell session. Therefore, the first paragraph should be:

Let's try to link a dead process to see what happens. First, make sure that you are starting from a fresh shell session. Then, create a process that exits quickly:

Section 5.1.8

In the second callout, it should read:

Handles a message to detect :EXIT messages

Page 100, Callout Box

The key can be retrieved like so:

should be:

The value can be retrieved like so:

Page 110, Section 5.4

Right after the listing, the sentence should read:

You begin by creating a supervisor:

Also, the pid of the supervisor is wrong. It should have been #PID<0.84.0>.

Page 121, Section 6.2.5

If you're supervising a Supervisor, then use supervise/3.

Should be:

If you're supervising a Supervisor, then use supervisor/3.

Page 126, Listing 6.6

The defstruct listing on the second line should be removed.

Page 128, Section 6.3.5, The two flavors of Supervisor.start_child/2

In the last paragraph, Supevisor should be Supervisor.

Page 132, Listing 6.9

There's an extra trailing A on the following line:

monitors = :ets.new(:monitors, [:private])

Page 132, Listing 6.9

The updated defstruct has been omitted:

defstruct sup: nil, worker_sup: nil, monitors: nil, size: nil, workers: nil, mfa: nil,

Page 151, Section 7.1.9

... and paste the implementation of Pooly.Server version 2 to Pooly.PoolyServer.

should be:

... and paste the implementation of Pooly.Server version 2 to Pooly.PoolServer.

Page 155, Listing 7.10

This correction hasn't been made.

worker_opts should be worker_opts = [shutdown: 5000, function: f]. The original options would have caused the workers not to retstart.

Page 158, Listing 7.14

This correction hasn't' been made.

The State struct is missing a waiting field:

defstruct pool_sup: nil, ..., waiting: nil, overflow: nil, max_overflow: nil

Page 159, Listing 7.2.2

This correction hasn't been made.

There is reference to a non-existent waiting field of the State struct. See fix for Page 158, Listing 7.14

Page 169, right before Section 7.3

... became available and was handled to ...

should be

... became available and was handled by ...

Page 174, Listing 8.1

This correction hasn't been made.

In mix.exs, a description of adding the :mod option has been left out in the application/0 function. Omitting this would cause a ** (EXIT) no process error when attempting to start the application.

Page 174, Section 8.2.2

There is an extraneous colon:

override: true:

Page 175, Listing 8.2

The text mentions that func is an optional parameter, though the code has no mention of this. It is safe to ignore that entire paragraph.

Also, because of a change in API in the Timex library, all references to Timex.measure/1 should be changed to Duration.measure instead.

Page 177, Listing 8.3

Most of the code uses Blitzy.Worker.start/1 instead of Blitzy.Worker.start/3. Please use this version:


                        defmodule Blitzy.Worker do
                            use Timex
                            require Logger

                            def start(url) do
                                {timestamp, response} = Duration.measure(fn -> HTTPoison.get(url) end)
                                handle_response({Duration.to_milliseconds(timestamp), response})
                            end

                            defp handle_response({msecs, {:ok, %HTTPoison.Response{status_code: code}}})
                            when code >= 200 and code <= 304 do
                                Logger.info "worker [#{node}-#{inspect self}] completed in #{msecs} msecs"
                                {:ok, msecs}
                            end

                            defp handle_response({_msecs, {:error, reason}}) do
                                Logger.info "worker [#{node}-#{inspect self}] error due to #{inspect reason}"
                                {:error, reason}
                            end

                            defp handle_response({_msecs, _}) do
                                Logger.info "worker [#{node}-#{inspect self}] errored out"
                                {:error, :unknown}
                            end
                        end
                        

Page 186, Listing 8.11

This correction hasn't been made.

The nodes parameter should be omitted:

defp process_options(options) do
...
end
                        

Page 206

This correction hasn't been made.

There is a step missing. In order to start the Chucky application in iex, the mod option has to be filled up in application/0 in mix.exs:

def application do
    [applications: [:logger],
              mod: {Chucky, []}]
end
                        

Page 235, Listing 11.3

This correction hasn't been made.

The example omits the following helper functions:


                        def key do
                          oneof([int, real, atom])
                        end

                        def val do
                          key
                        end

                        def map do
                          lazy do
                            oneof [{:call, Map, :new, []},
                                   {:call, Map, :put, [map_2, key, val]}]
                          end
                        end
                        

Page 236, Section 11.1.3

At the bottom of the page, the code should be:

forall {i, l} <- {int, list(int)}

Page 240, Section 11.1.6

In the example at the bottom of the page, ! should be wrapped in double quotes like so:

join(["everything", "is", "awesome", "!"], [?|])

Page 245, Listing 11.6

The third line of the code should be:

vector(len, frequency([{3, one_of(:lists.seq(?a, ?z))},

Instead of:

vector(len, frequency([{3, one of(:lists.seq(?a, ?z))},

Page 253, Section 11.2.3

In the last line of the section, the command to make sure that GraphViz is properly installed should be dot -V. The remaining part, dot - graphviz version 2.38.0 (20140413.2041), is the expected response.