So I have a situation where I have a function with two named arguments, but if both are used the function needs to die. I'm not sure if this is a bug, or if there's something intrinsic I'm not understanding about Perl variables.
Here's the simplified code:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
foreach my $number (1..5)
{
fooBar(foo => $number);
}
sub fooBar
{
my %args = (
foo => undef,
bar => undef,
@_
);
my $foo = $args{foo} if defined $args{foo};
my @bar = @{$args{bar}} if defined $args{bar};
print Dumper(\@bar);
if (defined $foo)
{
die('fooBar() received both a foo and a bar and didn\'t know which to use!') if @bar;
push(@bar, $foo);
}
print Dumper(\@bar);
return (\@bar);
}
# > $VAR1 = [];
# > $VAR1 = [
# > 1
# > ];
# > $VAR1 = [
# > 1
# > ];
# > fooBar() received both a foo and a bar and didn't know which to use! at ./example.pl line 27.
Here's my solution:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
foreach my $number (1..5)
{
fooBar(foo => $number);
}
sub fooBar
{
my %args = (
foo => undef,
bar => undef,
@_
);
my $foo;
my @bar;
$foo = $args{foo} if defined $args{foo};
@bar = @{$args{bar}} if defined $args{bar};
print Dumper(\@bar);
if (defined $foo)
{
die('fooBar() received both a foo and a bar and didn\'t know which to use!') if @bar;
push(@bar, $foo);
}
print Dumper(\@bar);
return (\@bar);
}
# > $VAR1 = [];
# > $VAR1 = [
# > 1
# > ];
# > $VAR1 = [];
# > $VAR1 = [
# > 2
# > ];
# > $VAR1 = [];
# > $VAR1 = [
# > 3
# > ];
# > $VAR1 = [];
# > $VAR1 = [
# > 4
# > ];
# > $VAR1 = [];
# > $VAR1 = [
# > 5
# > ];
My question is, why does this fix the problem? In the first example, the first time fooBar() is called, @bar is getting initialized despite failing the if condition. The second time through the loop, @bar has somehow retained its information from the first loop, yet it doesn't complain about being reinitialized. It seems to me that either a) @bar should be wiped after the subroutine finishes (which is what I was expecting), b) @bar shouldn't be initialized after it fails the if defined test, or c) @bar should complain that it's being reinitialized the second time through the loop. I'm pretty confused here, is this just a bug?
my ... if. but what actually happens (currently; it is flagged in the doc as subject to change) is thatmyhas both a compile-time an a run time effect; the if can skip the run time effect, keeping perl from knowing it needs to reinitializing the variable at end of scope.perlcritictoo: it says: Variable declared in conditional statement at line 22, column 5. Declare variables outside of the condition. (Severity: 5) (and the same for the line 23)