Делает ли мои $ _;делать что-либо, если подразумевается $ _ - PullRequest
6 голосов
/ 03 августа 2010

Я думаю, что ответ - да, но я просто хочу убедиться.так что если у меня есть

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

, действительно ли my $_; действительно эффективен при лексизации параметра, переданного в выражение?

В этом конкретном случае я использую DZP ::UnusedVarsTests , и он жалуется, что я не использовал my $_;, и я подозреваю, что это ошибка, так как я использую ее в случае, когда это подразумевается.

1 Ответ

10 голосов
/ 03 августа 2010

Краткий ответ - Да. Это заставляет функции в этой области использовать лексическую область действия $_, а не глобальную $_. Если они вернутся к $_, как в случае s///, у вас будет некоторый уровень контроля урона.

За perldoc perldelta (5.10.0) :

"List::Util::first" ведет себя неправильно в присутствии лексического $_ (обычно вводится "my $_" или неявно "given"). Переменная, которая устанавливается для каждой итерации, является переменной пакета $_, а не лексической $_ [RT # 67694].

Подобная проблема может возникать в других модулях, которые предоставляют функции, которые принимают блок в качестве первого аргумента, например

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

И в perldoc perl591delta он продолжает:

Лексический $ _

Переменную по умолчанию $_ теперь можно лексизировать, объявив ее следующим образом: любая другая лексическая переменная, с простой

     my $_;

Операции, которые по умолчанию для $_ будут использовать версию $_ с лексической областью, когда она существует, вместо глобальной $_.

В блоке "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;

И еще один пример

my $_ = 'foo';

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

something();

say;
...