Commencing Our Quizzes
Let’s start adding functions to our responses, templates, and questions.
We'll cover the following...
Responses
Let’s start with a simple example. Nothing in Mastery is more straightforward than a Response
. You might wonder how large a module has to be. The answer is as big as it needs to be to do a single job. On a module basis, we want to keep the external API simple and internal details hidden. That way, the interactions between modules will be simpler. In a sense, we’re building layers inside of layers.
Some of our modules have only data and a constructor, and that’s fine. Responses exist only to be data-holding structs, so all we need is a constructor. Think of a constructor as a convenience function to instantiate a piece of data. We’ll add our constructor to /lib/mastery/core/response.ex
, like this:
def new(quiz, email, answer) do question = quiz.current_question template = question.template%__MODULE__{quiz_title: quiz.title,template_name: template.name,to: question.asked,email: email,answer: answer,correct: template.checker.(question.substitutions, answer),timestamp: DateTime.utc_now}end
We’re using __MODULE__
instead of typing the full name of the module for the following reasons:
-
The code defaults to the current module.
-
We don’t have to refactor code whenever we reorganize the project.
response.ex
Here’s what response.ex
will look like now:
defmodule Mastery.Core.Response dodefstruct ~w[quiz_title template_name to email answer correct timestamp]adef new(quiz, email, answer) do question = quiz.current_question template = question.template%__MODULE__{quiz_title: quiz.title,template_name: template.name,to: question.asked,email: email,answer: answer,correct: template.checker.(question.substitutions, answer),timestamp: DateTime.utc_now}endend
If we were designing our own Mastery component, we might be tempted to put questions and templates together. Still, we chose not to do so because templates and questions are ...