$ _是Perl中的包变量吗?

时间:2015-01-29 02:51:49

标签: perl

$_充当Perl中许多函数的默认参数,它是一个普通的词法变量或包包吗?我以为它是前者,但我也看到_在符号表%main::中。

2 个答案:

答案 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. 标点符号变量由一个非字母的单个字符组成(例如$_$.$]$1等,或者它们的名称开头使用^(例如$^V$^X${^TAINT}等)。我的所有示例都是标量,但同样适用于其他变量类型。