perl 在代码深处使用的未声明变量的作用域是什么?

djmepvbi  于 2023-01-21  发布在  Perl
关注(0)|答案(1)|浏览(160)
# my @arr;   
for (1..100)
{
    for (1..100)
    {
        for (1..100)
        {
            push @arr, 1;
        }
    }
}

@arr的作用域是什么?它是否与顶部注解行中声明的作用域相同?

kse8i1jr

kse8i1jr1#

@arr是一个全局变量,在解析器第一次遇到它时创建,然后在整个包中看到它。

use warnings;
#use strict;

for (1..3) {
    #my @arr;
    for ( qw(a b c) ) {
        push @arr, $_;
    }   
}

print "@arr\n";

它打印

a b c a b c a b c

这是全局变量的缺点之一,全局变量"辐射"整个代码。
启用use strict;后,我们得到

Possible unintended interpolation of @arr in string at scope.pl line 11.
Global symbol "@arr" requires explicit package name at scope.pl line 7.
Global symbol "@arr" requires explicit package name at scope.pl line 11.
Execution of scope.pl aborted due to compilation errors.

由于strict只是强制声明,这意味着@arr是全局的(因此在代码中随处可见)。
在本例中,声明变量时将my放在顶部会产生相同的效果,但它与未声明的全局变量不同。my变量是词法变量,具有作用域,即最近的封闭块(此处为文件)。From my
my声明列出的变量是封闭块、文件或eval的局部变量(词法上)。如果列出了多个变量,则必须将列表放在括号中。
此外,词法也不在符号表中。
所以当它在第一个循环中声明时(注解掉的行),下面的push @arr...引用了 * that * 变量,它不存在于那个循环的块之外(所以在最后看不到),最后一行引用了另一个变量,一个全局的@arr,†它从来没有被赋值。

Possible unintended interpolation of @arr in string at scope.pl line 11.
Name "main::arr" used only once: possible typo at scope.pl line 11.

大约空main::arr使用过一次,打印后为空行。
另请参见通过perlsub中的my()访问私有变量
†在编译时,解析器第一次看到它时

相关问题