6

答えはイエスだと思いますが、確認したいだけです。だから私が持っているなら

sub something {
    my $_;
    my @array = ...;
    while ( @array ) {
        say;
    }
}

my $_;言うに渡されたパラメータを字句化するのに実際に効果的ですか?

この特定のケースでは、DZP :: UnusedVarsTestsを使用していますが、使用していないとの不満があり、my $_;暗黙的に使用しているため、バグであると思われます。

4

1 に答える 1

10

簡単な答えは「はい」です。$_そのスコープ内の関数は、グローバルではなく、字句スコープのを使用します$_。の場合のように、彼らがに書き戻す$_場合s///、あなたはある程度のダメージコントロールを持つことになります。

perldoc perldelta(5.10.0)あたり:

" List::Util::first"は、字句の存在下で誤動作します$_(通常は " my $_"によって、または暗黙的に ""によって導入されgivenます)。反復ごとに設定される変数はパッケージ変数$_であり、字句$_[RT#67694]ではありません。

同様の問題は、最初の引数としてブロックをとる関数を提供する他のモジュールでも発生する可能性があります。

foo { ... $_ ...} list

そして、その中perldoc perl591deltaで次のように述べています。

字句$_

デフォルトの変数$_は、他の字句変数と同じように宣言することで、簡単に語彙化できるようになりました。

     my $_;

デフォルトでオンになっている操作では、グローバルではなく$_、字句スコープのバージョンが存在する場合にそれが使用されます。$_$_

" map"または" grep"ブロックで$_は、以前にmy'edされていた場合$_、ブロック内も字句的です(そしてブロックにスコープされます)。

語彙化されたスコープでは、を使用するか、より簡単に言えば、語彙宣言を「」でオーバーライドすることにより$_、のグローバルバージョンにアクセスできます。$_$::_our $_

この機能が使用される理由の例をいくつか示したいと思います。

my $_ = 'BOOM!';

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

something();

say;

そして、別の例

my $_ = 'foo';

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

something();

say;
于 2010-08-03T01:47:32.133 に答える