I'm not sure that it is documented anywhere. During our MAA PREP workshop on authoring problems in WebWork, Davide Cervone said that every answer blank should have a unique MathObject associated to it. Here's my understanding of how answer blanks work and the rationale behind Davide's statement:
- Answer blanks are either created by \{ ans_rule() \} in a BEGIN_TEXT / END_TEXT block or by [____] in a BEGIN_PGML / END_PGML block.
- In html mode, every answer blank generates html source code that includes a form input box with a unique name such as AnSwEr0001 that is automatically generated (it is also possible to manually generate the name, but that's rarely done).
- Best PG coding practices (as established by Davide Cervone) say that every answer blank should have a MathObject associated to it. For instance, the MathObject $answer1 = Compute("sin(x)"); can be associated with an answer blank using \{ $answer1->ans_rule() \} in a BEGIN_TEXT / END_TEXT block or by using [_____]{$answer1} in a BEGIN_PGML / END_PGML block. Doing this assures that the student answer typed into the html form input box is associated with the MathObject $answer1 because the student answer becomes part of the "data" of the object $answer1.
- When the student enters their answer in the html form input box and clicks "Submit Answers", WeBWorK needs to take the student answer from the html form and route it to the proper answer checker. In PGML, this is done entirely by the code [____]{$answer1}, so a PGML problem author does not need to do anything additional.
In non-PGML, the problem author has to include both \{ $answer1->ans_rule() \} to create the answer blank and also ANS( $answer1->cmp() ); after the BEGIN_TEXT / END_TEXT block to do answer checking. In non-PGML, the order in which the answer blanks are created should be the same as the order in which the answers are checked. By using $answer1->ans_rule(), the student answer becomes part of the "data" in the object $answer1, and the answer comparison method $answer1->cmp() can easily access that "data" in the object $answer1, i.e., the method ->cmp() can easily get the student answer from the data stored in $answer1 by the method ->ans_rule(). - Why should every answer blank have a unique MathObject answer? It's so that the pipeline that connects the correct answer with the student answer and the answer checker does not get broken. I think it's intuitively clear that having a bijective correspondence between MathObjects that are the correct answers and the answer blanks is a good idea. It's also clear that implementing this bijective correspondence in Perl should be done using a pipeline that preserves the bijective correspondence. In short, every answer blank should have a unique MathObject associated to it.
I'm sure there's a better (more concise and clearer) technical answer that Davide Cervone could give. If "Euler is the master of us all" in the realm of mathematics, then the same could be said of Davide in the realm of WeBWorK (and MathJax, and ...).
Best regards,
Paul Pearson