Аргументы
Несомненно, подпрограммы, выполняющие одно определенное действие, полезны, однако перед вами откроются совершенно новые горизонты, когда вы сможете передавать в подпрограмму аргументы.
В Perl после вызова подпрограммы следует список, заключенный в круглые скобки, которые обеспечивают автоматическое присваивание элементов данного списка на период выполнения этой подпрограммы специальной переменной с именем @_. Подпрограмма может обратиться к этой переменной и получить число аргументов и их значения. Например:
sub say_hello_to (
print "hello, $_[0]!\n" # первый параметр }
Здесь мы видим ссылку на $_[0] — первый элемент массива @_. Обратите внимание: несмотря на внешнее сходство, значение $_ [ 0 ] (первый элемент массива @_) не имеет ничего общего с переменной $_ (самостоятельной скалярной переменной). Не путайте их! Из этого кода видно, что подпрограмма приветствует того, чье имя мы указываем в качестве первого параметра. Это значит, что ее можно вызвать так:
say_hello_to("world"); # выдает hello, world $х = "somebody";
say_hello_to($x); # выдает hello, somebody say_hello_to("me")+say_hello_to("you"); # а теперь приветствует себя и вас
В последней строке возвращаемые значения явно использованы не были, однако для определения суммы Perl сначала должен вычислить все ее слагаемые, поэтому подпрограмма была вызвана дважды.
Вот пример с использованием более одного параметра:
sub say (
print "$_[0], $_[!]!\n";
}
say("hello","world"); # опять hello world
say ("goodbye", "cruel world"); # goodbye cruel world - популярная фраза из фильмов
Избыточные параметры игнорируются, т.е. если вы никогда не заглядываете в $_ [ 3 ], языку Perl это абсолютно все равно. Недостающие параметры также игнорируются, и если вы попытаетесь обратиться за пределы массива @_, как и любого другого массива, то просто получите в ответ undef.
Переменная @_ является локальной для подпрограммы. Если для @_ установлено глобальное значение, то оно перед вызовом подпрограммы сохраняется, а после возврата из подпрограммы восстанавливается. Это также означает, что подпрограмма может передавать аргументы в другую подпрограмму, не боясь "потерять" собственную переменную @_; вложенный вызов подпрограммы точно так же получает собственную переменную @_.
Давайте вернемся к программе сложения а и b из предыдущего раздела. Вот подпрограмма, которая складывает любые два значения, а именно два значения, передаваемые в нее как параметры:
sub add_two {
return $_[0] + $_[!];
1
print add_two(3,4); # выводит значение 7
$с = add_two(5,6); # $с получает значение 11
Давайте обобщим эту подпрограмму. Что, если нам нужно сложить 3, 4 или 100 значений? Это можно было бы сделать с помощью цикла, например:
sub add (
$sum = 0; # инициализировать сумму
foreach $_ (@_) {
$sum += $_; # прибавить все элементы
}
return $sum # последнее вычисленное выражение: сумма всех элементов }
$а = add(4,5,6); # складывает 4+5+6=15 и присваивает переменной $а print add(1,2,3,4,5); # выводит 15 print add (1..5); # тоже выводит 15, потому что список 1..5 раскрывается
Что, если бы переменная с именем $sum использовалась у нас раньше? При вызове подпрограммы add мы просто потеряли бы ее значение. В следующем разделе мы увидим, как избежать этого.