Home > Software engineering >  I need to refactor an ancient piece of Perl code with defined(@array) and defined(%hash)
I need to refactor an ancient piece of Perl code with defined(@array) and defined(%hash)

Time:11-12

I'm running an ancient version of Movable Type that works just fine for me. However, I began to receive the following server errors:

defined(@array) is deprecated at /home/public_html/cgi-bin/mt/extlib/Locale/Maketext.pm line 623.
defined(%hash) is deprecated at /home/public_html/cgi-bin/mt/extlib/Locale/Maketext.pm line 623.

I found the line in question:

if defined(%{$module . "::Lexicon"}) or defined(@{$module . "::ISA"});

Is the following the correct way to refactor this line?

if %{$module . "::Lexicon"} or @{$module . "::ISA"};

If so, why? If not, why not? I'd like to understand better what happened to defined(@array) and defined(%hash).

UPDATE: I also found a similar issue on line 367 of CGI.pm:

if (defined(@QUERY_PARAM) && !defined($initializer)) {

I rewrote this as follows but I'm still not sure if it's right:

if (@QUERY_PARAM && $initializer) {

I can see how @QUERY_PARAM could confirm that it exists, but I'm probably not setting the second condition that $initializer does not exist, and I'm not quite sure how to do this.

CodePudding user response:

$ perl -w -Mdiagnostics -e 'print defined(@array)'

Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at -e
        line 1 (#1)
    (F) defined() is not useful on arrays because it
    checks for an undefined scalar value.  If you want to see if the
    array is empty, just use if (@array) { # not empty } for example.

Uncaught exception from user code:
        Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at -e line 1.

$ [perldoc -f defined](http://metacpan.org/pod/perlfunc#defined)

...

Use of "defined" on aggregates (hashes and arrays) is no longer
supported. It used to report whether memory for that aggregate
had ever been allocated. You should instead use a simple test
for size:

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

The defined(@array) construction never did what users expected it to do, and what it actually did was not that useful, so it was removed from the language (and deprecated in the version of Perl you are using). The way to fix it, as the diagnostics and docs suggest, is to just use @array rather than defined(@array) in boolean context.

  • Related