skip to Main Content

I just setup a new dev environment and went from Centos 7 (perl 5.16 v16) to RHEL 8.5 (perl 5.26.3). With that said, I cannot figure out the new syntax for the define statement in this old sub. Any help with this last line would really be appreciated. I just can’t get it to work:

my $flags_loop = db()->retrieveSet(table => "flags",order=>["flag"],dir=>'DESC');
my $outflags;

foreach my $flag (@$flags_loop) {
    my $flagsize = db()->count(
        table => "songflag", 
        where => { flagid => $flag->{flagid} } );
    $flag->{flagsize} = $flagsize;
    push (@$outflags, $flag);
}

# in case no flags yet defined
# 5.26 incompatible
if (!defined(@$outflags)) { $outflags=[]; }

3

Answers


  1. I get an error message similar to the following:

    Can't use 'defined(@array)' (Maybe you should just omit the defined()?)
    

    When I change:

    if (!defined(@$outflags)) { $outflags=[]; }
    

    to:

    if (!(@$outflags)) { $outflags=[]; }
    

    The error goes away.

    See also: defined

    Login or Signup to reply.
  2. Remove that line and replace

    my $outflags;
    

    with

    my $outflags = [ ];
    

    Explanation follows.


    Checking if an array is defined makes no sense.

    Usually, when someone uses that construct, they want to check if the array is empty. (That’s not quite what it does.) If that were the case here, you would replace

    if (!defined(@$outflags)) { ... }
    

    with

    if (!@$outflags)) { ... }
    

    The error message even suggests this might be the case. But it’s not. @$outflags is never empty, so you’re not trying to check if it’s empty.

    You’re actually trying to ensure that $outflags is always a reference to an array. Without that line, the $outflags would be undef if no flags are found.

    So, specifically, you are trying to check if $outflags is undef. As such, you should replace

    if (!defined(@$outflags)) { ... }
    

    with

    if (!defined($outflags)) { ... }
    

    That said, there’s a simpler approach. Since $outflags is either a reference or undef, we could also check for truth rather than definedness. That means that

    if (!defined($outflags)) { $outflags=[]; }
    

    can be replaced with

    if (!$outflags) { $outflags=[]; }
    

    But we could simply use

    $outflags //= [];
    

    But that’s not the simplest approach! We could avoid that line entirely by initializing $outflags from the start!

    my $outflags = [];
    
    Login or Signup to reply.
  3. The defined on non-scalar things never quite worked how anyone thought, or at least people DWIM-ed a different meaning than defined‘s original intent.

    defined on arrays (and some other things) was deprecated in Perl 5.005, but as with many deprecations, it didn’t actually go away. Eventually, v5.16 (the version you were using previously) got serious about it (no, really this time!) and added a deprecation warning that you get even without enabling warnings. The warning tells you want to do:

    $ perl5.16.3 -e 'defined(@ARGV)'
    defined(@array) is deprecated at -e line 1.
        (Maybe you should just omit the defined()?)
    

    There’s no new syntax: just old syntax you don’t use at all. Perl has been pretty good at deprecation warnings for several versions now because the developers are pretty serious about removing all the things that have been listed for removal for a couple decades.

    Using diagnostics gives a longer explanations of the error, showing you what to do if you want to check that the array is empty.

    defined(@array) is deprecated at -e line 1 (#1)
        (D deprecated) defined() is not usually 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.
    
        (Maybe you should just omit the defined()?)
    

    Even then, this feature was in Perl until v5.22. The warning tells you what to do:

    $ perl5.32.0 -e 'defined(@ARGV)'
    Can't use 'defined(@array)' (Maybe you should just omit the defined()?) at -e line 1.
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search