Пожалуйста, объясните, что именно разница $_
и @_
находится в Perl.
Когда использовать, который указан в примере кода.
В чем отличие использования специальной переменной $_ и @_ в Perl?
Ответ 1
Когда в подпрограмме массив @_
дает аргументы, переданные данной подпрограмме. Например:
use strict;
use warnings;
sub print_em
{
foreach my $arg (@_)
{
print "You passed in $arg.\n";
}
}
print_em("foo","bar","baz");
Выходной сигнал
You passed in foo.
You passed in bar.
You passed in baz.
Скаляр $_
обычно используется как переменная в цикле. Например:
use strict;
use warnings;
# Note that we are not declaring a variable
# that takes on the values 1 through 5.
foreach(1..5)
{
print "$_\n";
}
Вывод:
1
2
3
4
5
Аналогично, мы могли бы немного переписать подпрограмму print_em
выше как
sub print_em
{
foreach(@_)
{
print "You passed in $_.\n";
}
}
или даже как более компактный
sub print_em{ print "You passed in $_.\n" foreach(@_);}
Переменная $_
также может использоваться как "аргумент по умолчанию" для определенных функций. Например:
use strict;
use warnings;
$_="foobar";
if(/bar/) #We do not have to write $_=~/bar/
{
print "matched!\n";
}
который, конечно, выводит matched!
.
Взгляните на perldoc perlvar
для получения дополнительной информации об этих и других "волшебных переменных" Perl.
Ответ 2
Ответ Jack Maney охватывает ваш точный вопрос, но я также хотел кое-что отметить: вы не должны быть обмануты только частью названия переменной. Сигал тоже. $_
и @_
являются совершенно разными переменными, такими как $foo
и @foo
, а также $bar
и %bar
. Perl сохраняет их полностью отдельно друг от друга.
Ответ 3
Один из часто встречающихся примеров связан с I/O. Этот код...
while(<>)
{
chomp;
print if(m/^chr1/);
}
... функционально эквивалентен этому коду.
while(my $line = <STDIN>)
{
chomp($line);
print($line) if($line =~ m/^chr1/);
}
Всякий раз, когда у вас есть цикл, переменная $_
заполняется, но есть и более явный синтаксис. Этот код...
foreach(@a)
{
print;
chomp;
push(@b, $_)
}
... функционально эквивалентен этому коду.
foreach my $value(@a)
{
print($value);
chomp($value);
push(@b, $value);
}
Одно дело иметь в виду $_
и другие магические переменные - это то, что они могут быть довольно загадочными для нового программиста. Со временем я использовал их все меньше и меньше в пользу более явного синтаксиса, который (надеюсь) облегчает другим понимание намерения кода.
Ответ 4
Ни $_
, ни @_
не является неотъемлемо особенным. Помимо того, что они являются глобальными, они являются полностью нормальными переменными. Они не волшебны. Ничего особенного не происходит, когда вы назначаете их или читаете с них.
Причина @_
используется так часто, что Perl помещает аргументы функции. Если вы хотите получить аргументы, переданные вашему суб, вам нужно получить доступ к @_
.
sub f {
my ($x, $y) = @_;
...
}
Причина $_
используется так часто, что некоторые операторы Perl присваивают ей по умолчанию, а другие используют ее значение по умолчанию для своего аргумента. Это может привести к сокращению кода, если вы его охватите, но вам никогда не придется его использовать.
for my $x (@x) { say $x; }
vs
for (@x) { say; }