A forma especial with fornece uma maneira de te concentrares no "caminho ideal" de uma série de passos que podem falhar e tratar das falhas mais tarde.
with {:ok, id} <- get_id(username),
{:ok, avatar} <- fetch_avatar(id),
{:ok, image_type} <- check_valid_image_type(avatar) do
{:ok, image_type, avatar}
else
:not_found ->
{:error, "invalid username"}
{:error, "not an image"} ->
{:error, "avatar associated to #{username} is not an image"}
err ->
err
end
A cada passo, se uma cláusula corresponder, a cadeia continua até que o bloco do seja executado. Se uma correspondência falhar, a cadeia para e a cláusula que não corresponde é devolvida. Tens a opção de usar um bloco else para apanhar correspondências falhadas e modificar o valor devolvido.
O teu passaporte está prestes a expirar, por isso tens de passar pelo escritório da cidade para o renovares. Sabes, por experiência própria, que o teu escritório da cidade não é propriamente o mais fácil de lidar, por isso decides fazer o teu melhor para te focares sempre no "caminho feliz".
Imprimes o formulário de que precisas para obter o novo passaporte, preenchê-lo, saltas para o carro, dás uma volta ao quarteirão, estacionas e diriges-te ao escritório.
Todas as tarefas seguintes vão exigir que implementes e expandas a função get_new_passport/3.
Acontece que o edifício só está aberto à tarde, e não à mesma hora todos os dias.
Chama a função enter_building/1 com a hora atual (que te é dada como primeiro argumento de get_new_passport/3). Se o edifício estiver aberto, a função devolve um tuplo com :ok e um timestamp de que vais precisar mais tarde; caso contrário, devolve um tuplo com :error e uma mensagem. Para já, o caminho feliz pode devolver o tuplo :ok.
Se receberes um tuplo :error, usa o bloco else para o devolveres.
O balcão de informações é famoso por fazer longas pausas para o café. Se tiveres a sorte de encontrar lá alguém, essa pessoa dá-te um manual de instruções que explica a que guiché tens de ir, consoante a tua data de nascimento.
Chama a função find_counter_information/1 com a hora atual. Vais receber ou um tuplo com :ok e um manual, representado por uma função anónima, ou um tuplo com :coffee_break e mais instruções. No teu caminho feliz, em que recebes o manual, aplica-o à tua data de nascimento (segundo argumento de get_new_passport/3). Este devolve o número do guiché onde tens de ir. Devolve um tuplo :ok com esse número de guiché.
Se receberes uma mensagem :coffee_break, devolve um tuplo com :retry e um NaiveDateTime que aponta para 15 minutos depois da hora atual. Como antes, se receberes um tuplo :error, devolve-o.
Por alguma razão, guichés diferentes exigem formulários de cores diferentes. Claro que imprimiste o primeiro que encontraste no site, por isso focas-te no teu caminho feliz e esperas pelo melhor.
Chama a função stamp_form/3 com o timestamp que recebeste à entrada, o guiché e o formulário que levaste (último argumento de get_new_passport/3). Vais receber ou um tuplo com :ok e uma checksum que será usada para verificar o teu número de passaporte, ou um tuplo com :error e uma mensagem. Faz com que o teu caminho feliz devolva um tuplo :ok com a checksum. Se receberes um tuplo :error, devolve-o.
Por fim, tens todos os documentos de que precisas.
Chama get_new_passport_number/3 com o timestamp, o guiché e a checksum que recebeste antes. Vais receber uma string com o teu número de passaporte final; só falta devolveres essa string num tuplo com :ok e ires para casa.
Inscreve-te no Exercism para aprenderes e dominares Elixir com 58 conceitos168 exercícios, e mentoria humana real, tudo grátis.