Why was equal sign used in with statement?

@bennelsonweiss explained it perfectly.

  1. They use with because they want to handle those errors by matching on them in action_fallback like:
def call(conn, {:error, %Ecto.Changeset{} = changeset}) do
    conn
    |> put_status(:unprocessable_entity)
    |> put_view(MyAppWeb.ChangesetView)
    |> render("error.json", changeset: changeset)
end

def call(conn, {:error, something}), do: ...

But Ecto.NoResultsError that can be raised by get_page!, handled by Plug.Exception implicitly and then may be directed to action_fallback, but not in dev environment, because in dev we may want to debug those errors earlier.

  1. You are right! It should be placed outside in this example, if you don’t care about binding scope; as @Sebb said he would limit the scope of page binding, but in this example it does not matter.

  2. cms_page_path(conn, :show, page) just works because it sees page binding, there is no inner scope between with ... do, only between with ... end, if I understood your question.

everywhere = 1

with only_inside_a = 2,
     only_inside_b = 3 do
  IO.puts(everywhere) # 1
  IO.puts(only_inside_a) # 2
  IO.puts(only_inside_b) # 3
end

IO.puts(everywhere) # 1
IO.puts(only_inside_a) # ERROR!
IO.puts(only_inside_b) # ERROR!