WeBWorK Main Forum

passing a subroutine reference to withPostFilter

passing a subroutine reference to withPostFilter

by Michael Shulman -
Number of replies: 3
Sometimes when I try to pass a named subroutine reference to withPostFilter, I get the following error:

The evaluated answer is not an answer hash : ||.

...
  • Use of uninitialized value $new_rh_ans_evaluation_result in concatenation (.) or string at /opt/webwork/pg/lib/WeBWorK/PG/Translator.pm line 1337
I haven't been able to figure out when this happens and when it doesn't. But it happens with something as simple as this:

sub test { return $_[0]; }
ANS( str_cmp( 'FALSE' )->withPostFilter(\&test) );

whereas the following works fine:

sub test { return $_[0]; }
ANS( str_cmp( 'FALSE' )->withPostFilter(sub { return test(@_); }) );

Is there maybe something about namespacing or evals going on so that the subroutine "test" is visible to the "sub" closure but not via a direct reference?

In reply to Michael Shulman

Re: passing a subroutine reference to withPostFilter

by Michael Gage -
I suspect the problem is   \&test  

If you are typing this in a .pg problem file you need to write it as 
~~&test

That's because the backslash is reserved for tex commands, of which there 
are many, and in order to reference a perl object you use ~~ instead. 

(The technical version:  each .pg file is processed to replace all incidences of \ with \\. Then the incidences of ~~ are replaced with \. When this new version of the file is processed the double backslashes are replaced by single backslashes during the interpolation process and then interpreted as TeX commands.  

In .pl files for macros (which are not preprocessed) all TeX commands have to be written with double backslashes:  \\par  etc. but \&test would work fine. )
In reply to Michael Gage

Re: passing a subroutine reference to withPostFilter

by Michael Shulman -
Yikes! So while a .pg file looks like Perl code, it isn't actually. Are there any other gotchas like this?
In reply to Michael Shulman

Re: passing a subroutine reference to withPostFilter

by Michael Gage -
This might help. http://webwork.maa.org/wiki/Basic_Perl_syntax  It's pretty hold so it may not be comprehensive, but PG hasn't changed that much.

PG is a DSL (domain specific language). PG is to perl kind of like LaTeX is to TeX.  LaTeX is written in TeX and mostly extends the language, although sometimes it changes the underlying language a bit. (LaTeX used to be much worse in this regard when it was first written.)  

PG behaves much the same way and in fact was loosely modeled on the LaTeX/TeX relationship. For the most part it uses the perl parser but it overlays this with some preprocessing and with a large number of "macros", subroutines that extend the power of perl in ways that are useful writing math questions.

You can look through the code in this file to get an overview of how a .pg file is processed.