Hello!
I recently completed the book and highly recommend it to anyone looking to deepen their understanding of OTP (especially if you’re relatively new to Elixir and Erlang, as I am).
Now, onto my question The authors’ approach to integrating the persistence layer using a poncho project—where a persistence_fn function is passed to the core project—raised an interesting thought for me.
The original implementation of the :answer_question
handler creates a new Response
, uses it to advance the Quiz
(by calling answer_question
and select_question
), and concludes the quiz
if no questions remain. Here’s the code:
def handle_call({:answer_question, answer, fun}, _from, {quiz, email}) do
response = Response.new(quiz, email, answer)
quiz
|> Quiz.answer_question(response)
|> Quiz.select_question()
|> maybe_finish(email)
end
defp maybe_finish(nil, _email), do: {:stop, :normal, :finished, nil}
defp maybe_finish(quiz, email) do
{
:reply,
{quiz.current_question.asked, quiz.last_response.correct},
{quiz, email}
}
end
After incorporating the poncho project and modifying the handler to expect an external function, the implementation changes as follows:
def handle_call({:answer_question, answer, fun}, _from, {quiz, email}) do
fun = fun || fn r, f -> f.(r) end
response = Response.new(quiz, email, answer)
fun.(response, fn r ->
quiz
|> Quiz.answer_question(r)
|> Quiz.select_question()
end)
|> maybe_finish(email)
end
defp maybe_finish(nil, _email), do: {:stop, :normal, :finished, nil}
defp maybe_finish(quiz, email) do
{
:reply,
{quiz.current_question.asked, quiz.last_response.correct},
{quiz, email}
}
end
By default, fun
retains the original behavior, but now the user can pass a custom fun
. If the passed fun
does nothing, Quiz.answer_question
and Quiz.select_question
will no longer execute, preventing the quiz from progressing.
Am I correct in understanding that this integration effectively allows a “third party” (the poncho project) to interfere with the core business logic? Or am I overlooking something?
PS: I haven’t contacted the authors to paste that code in here. If it’s against the rules, I am happy to take it down.