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=[]; }
CodePudding user response:
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
CodePudding user response:
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.
CodePudding user response:
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 = [];