Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get a duplicate declaration in same scope warning in an if/elsif tree?

Tags:

perl

Why does the following code warn? $match is scoped to the if block and not the containing while block.

use strict;
use warnings;
use 5.012;

use IO::All;

my $file = io($ARGV[0])->tie;
my $regex = qr//;

while (my $line = <$file>) {
  if (my ($match) = $line =~ $regex) {
    ...
  }
  elsif (my ($match) = $line =~ $regex) {
    ...
  }
  say $match;
}

C:\>perl testwarn.pl test.log
"my" variable $match masks earlier declaration in same scope at testwarn.pl line 15.
Global symbol "$match" requires explicit package name at testwarn.pl line 18.
Execution of testwarn.pl aborted due to compilation errors.

As expected, it complains that $match is not defined at line 18, but it also complains about the redeclaration of $match in the if blocks. Version is slightly out of date but not horribly so; and it's the most recent Strawberry version:

This is perl 5, version 12, subversion 3 (v5.12.3) built for MSWin32-x86-multi-thread
like image 931
Oesor Avatar asked Jun 21 '11 18:06

Oesor


1 Answers

The scope of the first $match declaration is the entire if-elsif-else block. That lets you do things like this:

if ( (my $foo = some_value()) < some_other_value() ) {
    do_something();
} elsif ($foo < yet_another_value()) { # same $foo as in the if() above
    do_something_else();
} else {
    warn "\$foo was $foo\n";   # same $foo
}   # now $foo goes out of scope
print $foo;   # error under 'use strict' => $foo is now out of scope

If we were to declare my $foo anywhere else in this block, including in the elsif (...) clause, that would be a duplicate declaration in the same scope, and we'd get a warning message.

like image 191
mob Avatar answered Nov 16 '22 02:11

mob