这是我发现的有关变量范围的信息:
my
如果在块中使用,声明非常清晰和直接。如果在任何块外的 main 中使用,它们会有所不同,这意味着my
即使在从同一文件内的任何位置调用的函数内部,只要在同一文件中定义这些函数,在块外声明的变量也是可见的。但是,如果在块内声明,即使从同一个块调用,它们对函数也不可见。所有my
变量似乎都存在于堆栈中。并且:您不能使用local
.
our
变量存在于堆上。即使你有一个my
同名的变量,我们的变量仍然可以通过 访问${'var'}
,它在符号表中查找该名称的变量并取消引用它。my
另一方面,变量没有符号表条目。
local
在我看来,变量就像以前 Perl 版本的遗物。它们只是重新分配给our
具有块作用域的全局 ( ) 变量,并在块终止后恢复它们以前的值。我看不出使用它们的真正意义。
我在下面的小程序展示了所有这些,它显示了除了众所周知的 defined() 测试之外,declared() 测试的缺失有多严重,无法识别未声明的变量。
#!/usr/bin/perl
use strict;
### This is about variable scoping with my, our and local
my $fsv = "file scope"; # visible for all code in this file
our $gsv = "global scope"; # not different from my $fsv, except in packages
our $lsv = "global"; # global scope, but localized in subsequent block
{
my $bsv = "lex scope"; # visible only inside this block, not even in subs called from here
$gsv = "visible everywhere";
local $lsv = "global, but localized val";
print "This is variable \$bsv with value $bsv inside block\n";
print "This is variable \$fsv with value $fsv inside block\n";
print "This is variable \$lsv with value $lsv inside block\n\n";
print_vars("calledfromblock");
}
print_vars("calledfromoutside");
no strict 'vars'; # needed if testing variable for declaredness rather than definedness
if ( defined $bsv ) {
print "\$bsv as defined outside braces: $bsv\n"
} else {
print "\$bsv not defined outside braces\n";
}
print "This is variable \$lsv with value $lsv outside block\n";
# use strict 'vars'; # no strict 'vars' effective even in sub print_vars unless switched back on
sub print_vars
{
my $whence = shift;
my $gsv = "my variable";
no strict 'refs'; # needed to access the global var $gsv using ${'gsv'} despite the my declaration
if ( $whence eq "calledfromblock" ) {
print "\t print_vars called from within the block:\n";
( defined $bsv ) ? print "\$bsv is $bsv inside sub\n" : print "\$bsv not defined inside sub\n";
( defined $fsv ) ? print "\$fsv is $fsv inside sub\n" : print "\$fsv not defined inside sub\n";
( defined ${'gsv'} ) ? print "\$gsv is ${'gsv'} inside sub\n" : print "\$gsv not defined inside sub\n";
( defined ${'lsv'} ) ? print "\$lsv is ${'lsv'} inside sub\n" : print "\$lsv not defined inside sub\n";
} else {
print "\t print_vars called from outside the block:\n";
( defined $bsv ) ? print "\$bsv is $bsv inside sub\n" : print "\$bsv not defined inside sub\n";
( defined $fsv ) ? print "\$fsv is $fsv inside sub\n" : print "\$fsv not defined inside sub\n";
( defined $gsv ) ? print "\$gsv is $gsv inside sub\n" : print "\$gsv not defined inside sub\n";
( defined $lsv ) ? print "\$lsv is $lsv inside sub\n" : print "\$lsv not defined inside sub\n";
}
print "\n";
}