我的$ _; 如果隐含$ _则做任何事情

xen*_*ide 6 perl lexical-scope

我认为答案是肯定的,但我只是想确定一下.所以,如果我有

sub something {
    my $_;
    my @array = ...;
    while ( @array ) {
        say;
    }
}
Run Code Online (Sandbox Code Playgroud)

是否my $_;实际上有效地将传递给参数的参数词汇化?

在这个特殊的情况下,我正在使用DZP :: UnusedVarsTests,它抱怨我没有使用过my $_;,我怀疑它是一个bug,因为我在它隐含的情况下使用它.

Eva*_*oll 10

简短的回答是肯定的.它使该范围内的函数使用词法范围$_,而不是全局$_.如果他们回信$_,就像s///你的情况一样,你会有一定程度的伤害控制.

perldoc perldelta(5.10.0):

" List::Util::first"在词汇存在的情况下行为不端$_(通常由" my $_"或"隐含地" 引入given).为每次迭代设置的变量是包变量$_,而不是词法$_[RT#67694].

在其他模块中可能会出现类似的问题,这些模块提供了将块作为第一个参数的函数,例如

foo { ... $_ ...} list
Run Code Online (Sandbox Code Playgroud)

然后,perldoc perl591delta继续说:

词汇$ _

现在,默认变量$_可以通过简单的方式将其声明为任何其他词法变量

     my $_;
Run Code Online (Sandbox Code Playgroud)

默认的操作$_将使用$_存在时的词法范围版本,而不是全局$_.

在" map"或" grep"块中,如果$_之前my已经编过,那么$_块内部也是词法(并且作用于块).

$_已被词汇化的范围内,您仍然可以$_通过使用$::_"或"更简单地通过用" our $_" 覆盖词法声明来访问全局版本.

例子

我想提供一些使用此功能的原因示例:

my $_ = 'BOOM!';

sub something {
    my $_;                         ## Try running with and without
    my @array = qw/foo bar baz/;
    while ( $_ = pop @array ) {
        say;
    }   
}   

something();

say;
Run Code Online (Sandbox Code Playgroud)

而另一个例子

my $_ = 'foo';

sub something {
  my $_ = $_;  ## Try running with and without
  s/foo/bar/;
  $_;
}

something();

say;
Run Code Online (Sandbox Code Playgroud)