As I am using it now, the code comes in two parts:
- I load a macro file that subclasses the division, making a weird new meaning for '/'. The code is short:
package bizarro::BOP::divide;
our @ISA = ('Parser::BOP::divide');
#
# Return a/(b^3(2+sin(b)) when bizarroDiv is set
#
sub _eval {
my $self = shift;
my $context = $self->context;
my ($a,$b) = @_;
if ($context->flag("bizarroDiv")) {
return $a/(($b)**3*(2+CORE::sin($b)));}
else {
return $a / $b;
}
}
sub call {(shift)->_eval(@_)}
- Then in the problem, immediately following a context declaration, I have more code to make the context use the bizarro division during answer checking:
Context()->operators->set(
'/' => {class => 'bizarro::BOP::divide', isCommand => 1},
' /' => {class => 'bizarro::BOP::divide', isCommand => 1},
'/ ' => {class => 'bizarro::BOP::divide', isCommand => 1},
'//' => {class => 'bizarro::BOP::divide', isCommand => 1},
);
Context()->{cmpDefaults}{Formula}{checker} = sub {
my ($correct,$student,$ans) = @_;
return 0 if $ans->{isPreview} || $correct != $student;
$student = $ans->{student_formula};
$correct = $correct->{original_formula} if defined $correct->{original_formula};
Context()->flags->set(bizarroDiv=> 1);
delete $correct->{test_values}, $student->{test_values};
my $OK = ($correct == $student); # check if equal when / is replace by bizarro /
Context()->flags->set(bizarroDiv=> 0);
Value::Error("Your answer is not simplified") unless $OK;
return $OK;
};
Now when say, the expected answer is "x/3", and a student answers with "2x/6", they are asked to simplify more.
I am having trouble packaging this - probably I just don't know the right perl. Is there a way for me to put all this code into the same .pl file, and then be able to activate the second part with a single command? I would be able to do something like:
loadMacros(parserBizarroDivision.pl);
...Context("LimitedPolynomial");
ActivateBizarroDivision(); #replacing my second block of code above$ans = Formula("x/3");
...
ANS($ans->cmp());
Note that I want to be able to use this alongside several contexts, so I do not want to make a context macro file to implement this. And I can't simply throw the code in to my existing .pl file, because the context modification parts need to happen after I have declared a context.