Skip to content

Bug with AnswerHash.pm #872

Open
Open
@Alex-Jordan

Description

@Alex-Jordan

I first posted about this in the forums.

The following MWE illustrates a bug. If you enter the correct answer, it is not accepted and there is a perl warning "The evaluated answer is not an answer hash : ||."

This came to my attention from an instructor who previously used certain problems in 2.16, and they worked. But now they do not work on 2.17. And this MWE does not work on 2.18. So it is possibly a bug introduced between 2.16 and 2.17.

Note that if you change $ans to a Real, there is no issue. I also tried making $ans an Interval and there was no issue. It seems to have to do with $ans being a NumberWithUnits. Also there is no issue if I remove the withPostFilter or pass an empty hash to AnswerHints. So it also seems to have to do with AnswerHints.

DOCUMENT();
loadMacros(qw(PGstandard.pl PGML.pl parserNumberWithUnits.pl answerHints.pl));
$ans = NumberWithUnits("1 m");
#$ans = Real("1");   # This works.
$cmp = $ans->cmp()->withPostFilter(AnswerHints(2 => "no"));

BEGIN_PGML
Enter [`[$ans]`].

[_]{$cmp}
END_PGML
ENDDOCUMENT();

I have done some sleuthing. First, it does not help to revert the two macro libraries here to earlier (say 2.16) versions. The change in behavior is something deeper. Things go bad inside lib/AnswerHash.pm. There is this loop, where I have inserted warn statements while debugging

        foreach my $i (@post_filters) {
                last if defined($rh_ans->{done}) and $rh_ans->{done} == 1;    # no further action needed
                my @array  = @$i;
                my $filter = shift(@array);    # the array now contains the options for the filter
                warn('A');
                $rh_ans = &$filter($rh_ans, @array);
                warn('B');
                $self->print_result_if_debug('post_filter', $rh_ans, @array);
        }

Running the MWE, I get an "A" without a "B". Something about trying to access &$filter (in the particular case when it is an AnswerHints filter involving a NumberWithUnits as in the MWE) terminates not only this loop, but also the ambient subroutine. That's what leads to the error message; the ambient subroutine then returns nothing at all, which is "not an answer hash".

I can even change warn('A'); to warn('A' . &$filter);, and then I don't even get an "A". This suggests it's not so much something about executing that filter code, but just accessing it at all.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions