It turns out this is easier than I thought. Here is a little code that does the trick:
package my::Function; our @ISA = ('Parser::Function'); sub new { my $self = shift; my ($equation, $name) = @_; $equation->{functions}{$name} = 1; $self->SUPER::new(@_); } package main; Context("Numeric")->{parser}{Function} = 'my::Function'; $f = Formula("sin(x+sqrt(x+1))"); TEXT(join(', ', keys %{$f->{functions} || {}}));
This subclasses the Parser::Function
object and overrides the new
method so that it marks the names of the functions used in the formula. You could use $f->{functions}{sqrt}
to determine if sqrt()
had been used in the formula.
Note that if you use Compute()
rather than Formula()
, and the result is a constant, you won't get the functions
property because the formula will have been evaluated to the constant, but you can use $f->{equation}{formula}
in that case. In an answer checker, you should be able to use $ansHash->{student_value}
rather than $ansHash->{student_answer}
to access the formula.