$ _与命名输入或循环参数有何不同?

mat*_*ull 3 perl perlvar

因为我使用$ _很多,我想更好地理解它的用法.就我所理解和使用它而言,$ _是隐含值的全局变量.

因为$ _似乎是设置的,除了可读性之外,有没有理由在$ _上使用命名循环变量?

在什么情况下,重要的是_ _是一个全局变量?

所以,如果我使用

for (@array){
    print $_;
}
Run Code Online (Sandbox Code Playgroud)

甚至

print $_ for @array;
Run Code Online (Sandbox Code Playgroud)

它具有相同的效果

for my $var (@array){
    print $var;
}
Run Code Online (Sandbox Code Playgroud)

但它的工作方式是否相同?我想这不完全是,但实际的差异是什么?

更新:

在这个例子中,似乎$ _甚至是正确的范围.它不再是全球性的吗?我正在使用5.12.3.

#!/usr/bin/perl
use strict;
use warnings;

my @array = qw/one two three four/;
my @other_array = qw/1 2 3 4/;

for (@array){
    for (@other_array){
        print $_;
    }
    print $_;
}
Run Code Online (Sandbox Code Playgroud)

正确打印1234one1234two1234three1234four.

对于全球$ _我本来预期1234 4 1234 4 1234 4 1234 4 ..或者我错过了一些明显的东西?

什么时候是$ _ global呢?

更新:

好的,在仔细阅读了各种答案和perlsyn后,我得出了一个结论:

除了可读性之外,最好避免使用$ _,因为必须知道$ _的隐式本地化并考虑到否则可能会遇到意外行为.

感谢您澄清此事.

gee*_*aur 8

使用$_(隐式或显式)作为循环变量的经典失败模式是

for $_ (@myarray) {
  /(\d+)/ or die;
  foo($1);
}

sub foo {
  open(F, "foo_$_[0]") or die;
  while (<F>) {
    ...
  }
}
Run Code Online (Sandbox Code Playgroud)

其中,因为for/中的循环变量foreach绑定到实际的列表项,意味着while (<F>)覆盖@myarray从文件中读取的行.


tad*_*dmc 8

are there reasons to use named loop variables over $_ besides readability?
Run Code Online (Sandbox Code Playgroud)

问题不在于它们是否被命名.问题是它们是"包变量"还是"词汇变量".

请参阅Perl"Coping with Scoping"中使用的2个变量系统的非常好的描述:

http://perl.plover.com/FAQs/Namespaces.html

包变量是全局变量,因此应该避免出于所有常见原因(例如,远处的动作).

避免包变量是"正确操作"或"更难注入错误"的问题,而不是"可读性"的问题.

In what cases does it matter $_ is a global variable?
Run Code Online (Sandbox Code Playgroud)

到处.

更好的问题是:

In what cases is $_ local()ized for me?
Run Code Online (Sandbox Code Playgroud)

有几个地方Perl会为你本地()ize $ _,主要是foreach,grep和map.所有其他地方都要求你自己本地()使用它,因此当你不可避免地忘记这样做时,你会注入一个潜在的错误.:-)