Подтвердить что ты не робот

В чем значение подчеркивания в Perl ($ _, @_)?

Я новичок в Perl, и я использовал их как это

$_

foreach (@list) {
    print "$_\n";
}

@_

sub search {
    my ($no, @list) = @_;
}

Как именно эти переменные подчеркивания работают в Perl? Каковы другие конструкции, в которых они полезны?

4b9b3361

Ответ 1

Это вопрос, который указывает на то, что вы действительно должны читать книгу и, возможно, остальные часто задаваемые вопросы по тегам perl.

Тем не менее, $_ является контекстной переменной, которая неявно создается некоторыми конструкциями и неявно используется некоторыми встроенными функциями. Вот некоторые примеры:

while(<>) {
    next if /^#/;
    last if /^q(?:uit)?$/;
    say "Howdy!" if /^hello$/;
}

Это проделывает большую работу по настройке и проверке переменной $_ и эквивалентно:

while(defined($_ = <>)) {
    next if $_ =~ /^#/;
    last if $_ =~ /^q(?:uit)?$/;
    say "Howdy!" if $_ =~ /^hello$/;
}

Другие конструкции, которые устанавливают $_: циклы foreach, given блоки, операции map и grep, а также блоки catch в Try :: Tiny.

Другие конструкции, которые используют $_: голая print; операторы, оператор подстановки s/// и оператор транслитерации tr///.

Я бы посоветовал: пока вы изучаете Perl, не используйте $_ неявно. Запишите все полностью (как во втором примере выше), чтобы закрепить в уме то, что на самом деле происходит. Точно так же, как когда вы изучаете иностранный язык, вы должны научиться говорить правильно и осторожно, прежде чем вы начнете понимать язык. $_ полезен для написания более короткого и лаконичного кода и может быть на самом деле более понятным, если сосредоточиться на продолжающейся обработке, а не на переменных, для которых он выполняется, но только после того, как вы узнаете в качестве второй природы, какие операции используют $_. В противном случае это просто запутанный беспорядок.

Как уже упоминалось, @_ - это список аргументов для подпрограммы.

Ответ 3

Этот вопрос всегда возникает, потому что это perl auto-magic (я придумал этот термин).

foreach (@array_list){
  print $_ . "\n";
}

Эквивалентно:

foreach my $item (@array_list){
  print $item . "\n";
}

Разница в том, что когда переменная не указана для цикла, perl автоматически устанавливает значение по умолчанию $_ для предоставления каждого элемента.

Аналогично, при вызове подпрограмм (или методов - {подпрограмма в объекте}) perl помещает аргументы в подпрограмму в массиве @_, поскольку аргументы всегда будут списком.

С другой стороны, когда встроенная подпрограмма (или любая хорошо написанная подпрограмма) требует аргументов и вызывается без аргументов, она обычно будет работать с $_ или @_ зависимости от того, ожидает ли она один или несколько аргументов. Некоторые подпрограммы/методы (или функции) могут работать со скалярными или списочными значениями, и они по умолчанию обычно используют скалярный контекст и функционируют в $_ по умолчанию. Иногда имя дает понять, что оно ожидает список (массив или хэш), а затем по умолчанию @_.

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

Для получения дополнительной информации о том, как написать подпрограмму, которая возвращает значения на основе контекста, ознакомьтесь с wantarray а здесь приведена хорошая разбивка этого: https://www.perl.com/pub/2006/02/23/advanced_subroutines.html/