OK, I found the issue. When the student checks or submits the answer, the error message about the the student's answer being a formula is generated while the individual entries are being collected and processed into the matrix object, and because an error was produced, the student's matrix is not produced, and no further checking is done. But in preview mode, that message is not produced (the type checking is not performed), and so the student answer *is* created (as a Formula object returning a matrix value), and the rest of the answer checking is performed. One of the actions taken for matrix answer checking is a test to see if the student matrix is the same size as the correct answer matrix. That is done by calling the matrix's `dimensions`

method. But when the student answer contains the *x*, that answer is a Formula, not a Matrix object, and so doesn't have a `dimensions()`

method to call. That causes the answer checker to die (apparently silently), without returning the requires AnswerHash object, which is the source of the error you are seeing.

The checking of the dimensions is in Matrix object's `cmp_preprocess()`

method. There is a check there that the student's answer is a Matrix, but the check is actually that its return type is a Matrix, whereas it probably should be that the object's *class* is a Matrix (since that is what guarantees the presence of the `dimensions()`

method). So one possible fix is to change

return if $student->type ne 'Matrix';

to

return if $student->classMatch('Matrix');

at line 1033 of `pg/lib/Value/AnswerChecker.pm`

.

Another would be to add a `dimensions()`

method to the Formula object that returns the dimension of the matrix result (if it is a matrix), and a reasonable value for other things (like the size of a vector, or the length of a list, or 1 for a number). But that would suggest that it would be reasonable to have a `dimensions()`

method for all MathObjects. That would be a reasonable addition, but the `cmp_preprocess()`

fix is easier to do as a work-around, so I present that below.

One way to do it would be to add

package my::Matrix;
our @ISA = ('Value::Matrix');
sub cmp_preprocess {
my $self = shift; my $ans = shift;
my $student = $ans->{student_value};
return if !$student->classMatch('Matrix');
return $self->SUPER::cmp_preprocess($ans);
}
package main;
Context("Matrix");
Context->{value}{Matrix} = 'my::Matrix';

to your problem file. This defines a subclass of `Value::Matrix`

that has the patched `cmp_preprocess()`

function.

Of course, you don't want to have to do this for every file containing matrices, and since it is a general problem, you may want to work around it for *all* problems involving matrices. You can do that by using the File Manger to create a file in your course's `templates/macros`

folder named `parserCustomization.pl`

that contains

package my::Matrix;
our @ISA = ('Value::Matrix');
sub cmp_preprocess {
my $self = shift; my $ans = shift;
my $student = $ans->{student_value};
return if !$student->classMatch('Matrix');
return $self->SUPER::cmp_preprocess($ans);
}
package main;
$context{Matrix} = Context("Matrix");
Context->{value}{Matrix} = 'my::Matrix';
Context("Numeric");

This file will be loaded by every problem that loads the `MathObjects.pl`

file. It makes a local copy of the Matrix context that will be used whenever `Context("Matrix")`

is called and patches it to include the patched matrix subclass. That should take care of it for now until it is fixed in WeBWorK.