为什么我在if/elsif树中的同一范围警告中得到重复声明?

Oes*_*sor 9 perl

为什么以下代码会发出警告?$ match的范围限定为if块,而不是包含while块.

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;
}
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,它抱怨第18行没有定义$ match,但它也抱怨if块中$ match的重新声明.版本略有过时但并非如此可怕; 这是最新的草莓版本:

This is perl 5, version 12, subversion 3 (v5.12.3) built for MSWin32-x86-multi-thread
Run Code Online (Sandbox Code Playgroud)

mob*_*mob 14

第一个$match声明的范围是整个if-elsif-else块.这可以让你做这样的事情:

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
Run Code Online (Sandbox Code Playgroud)

如果我们要声明my $foo这个块中的任何其他地方,包括在elsif (...)子句中,那将是同一范围内的重复声明,并且我们会收到警告消息.

  • 不完全:`if(my $ foo){my $ foo}`没有警告.`if`创建两个范围:一个用于整个语句(包括条件),一个用于每个body块.第二个范围是第一个范围的子节点,因此"then"块可以查看条件中声明的变量. (2认同)