$_
充当Perl中许多函数的默认参数,它是一个普通的词法变量或包包吗?我以为它是前者,但我也看到_
在符号表%main::
中。
答案 0 :(得分:7)
有一些符号总是在包main中查找,而不是在当前包中查找,其中_
是一个。 (这意味着整个*_
glob:$_
,%_
,sub _
等。进行国际化的人定期跳过最后一个。)
其他此类符号包括:INC,ENV,SIG,ARGV,STDIN,STDOUT,STDERR,ARGVOUT以及任何不以标准标识符起始字符开头的内容(包括所有标点符号和${^...}
变量)
以下打印123
然后打456
:
package foo;
$_ = 123;
$foo::_ = 456;
package bar;
print $_;
print $foo::_;
但它是一个包变量。 (虽然有一个实验可以让my $_;
使词汇量成为我认为已被弃用的范围,并且在5005线程之下,它可能也是一个词汇,我不记得确实。)
答案 1 :(得分:2)
是。除了尝试引入my $_;
能力失败之外,所有标点符号变量 [1] 都是包变量。
例如,常见的错误是在sub中使用以下内容:
while (<$fh>) { ... }
以上代码是
的缩写while (defined($_ = <$fh>)) { ... }
正如你所看到的,那些咒骂者$_
。一个人应该使用
while (local $_ = <$fh>) { ... }
或
while (my $line = <$fh>) { ... }
错误的原因是$_
经常与另一个变量混淆。
$ perl -e'
use strict;
use warnings;
sub f {
my ($qfn) = @_;
open(my $fh, "<", $qfn) or die $!;
while (<$fh>) {
# ...
}
}
my @files = qw( a.txt b.txt );
for (@files) {
f($_);
}
print("Successfully processed @files.\n");
'
Use of uninitialized value $files[0] in join or string at -e line 18.
Use of uninitialized value $files[1] in join or string at -e line 18.
Successfully processed .
$_
有一些有趣的东西:它是一种“超级全球化”。这意味着,不合格的$_
(或@_
或%_
)在当前包中引用$main::_
而不是$_
。
$ perl -le'
$_ = $x = "main";
$Foo::_ = $Foo::x = "foo";
package Foo;
print($_);
print($Foo::_);
print($x);
'
main
foo
foo
我认为我从未需要这些知识。
$_
,$.
,$]
,$1
等,或者它们的名称开头使用^
(例如$^V
,$^X
,${^TAINT}
等)。我的所有示例都是标量,但同样适用于其他变量类型。