WeBWorK Problems

defined(%hash) is deprecated

defined(%hash) is deprecated

by Geoff Goehle -
Number of replies: 5
After a recent upgrade to Perl I've been seeing a lot of error messages of the form:

defined(%hash) is deprecated at /opt/webwork/pg/lib/WeBWorK/PG/Translator.pm line 1673.
(Maybe you should just omit the defined()?)

The errors come from a wide variety of .pm files making me thing the new version of perl doesn't play nicely with this version of WebWork.

I've tried doing a cvs upgrade to rel-2-4-patches but that didn't fix the problem and I am hesitant to upgrade to the development code in the middle of a semester.

Any suggestions on getting the error messages to go away?
In reply to Geoff Goehle

Re: defined(%hash) is deprecated

by Michael Gage -
Upgrading to the trunk version of the SVN won't solve your problem since it uses the same constructs.

What version of perl are you using?

We'll have to see what is now the recommended method for detecting a %hash.

The SVN trunk version is pretty stable now (it's being used on courses.maa.webwork.org and has been in use on the hosted2.webwork.rochester.edu machine for more than a year.

I'm planning to tag the trunk version of the SVN as rel-2-4-9 as soon as I finish the release notes on the wiki.

That said I would still hesitate to upgrade in the middle of a semester unless I had sufficient time to squash bugs instantly.

On a related issue. Which version of Safe.pm are you using? Are you still at Safe 2.19 or are the very latest versions of Safe once again compatible with MathObjects in WeBWorK?

-- Mike
In reply to Michael Gage

Re: defined(%hash) is deprecated

by Sam Hathaway -
According to the docs in 5.12.2:

Use of defined on aggregates (hashes and arrays) is deprecated. It used to report whether memory for that aggregate has ever been allocated. This behavior may disappear in future versions of Perl. You should instead use a simple test for size:

  1. if (@an_array) { print "has array elements\n" }
  2. if (%a_hash) { print "has hash members\n" }

In reply to Sam Hathaway

Re: defined(%hash) is deprecated

by Michael Gage -
thanks, Sam. I found this also and did some tests. I was worried that not using defined() might cause a warning about using an undefined value but it does not, in this context, on my older version of perl.

I suspect the newest versions of perl are just getting stricter about obeying the language directives. There are only a few cases where this particular error occurs. One in dumpvar() in Translator.pm and two or three other occurrences. Should be pretty easy to correct once I am using a version of perl which actually flags these errors.
In reply to Michael Gage

Re: defined(%hash) is deprecated

by Sam Hathaway -
If this code is running under strict, you'll see a compiler error if the variable doesn't even exist. You can try something like:

my $foo_exists = eval "%foo ? 1 : 0";

And then just don't bother checking $@ for an exception.
In reply to Michael Gage

Re: defined(%hash) is deprecated

by Geoff Goehle -
Hi, sorry for the late reply. I ended up using

find . -name "*.pm" -exec sed -i 's/defined(/([@%][a-zA-Z]*\))/\1/ {} \;

to remove all of the code causing the warnings (my students were using them as an excuse not to do anything.) I probably broke something in the process though, so I dont recommend it.

To answer your questions:
We are currently running, as reported by eix,
-perl version 5.12.2-r1 (the r1 may be gentoo specific).
-perl-safe version 2.19

I havent risked upgrading perl safe since its the middle of the semester. I'll try again after term ends.