Аргументы

Функция larger_of_fred_or_barney станет намного удобнее, если пользователь не будет ограничиваться применением глобальных переменных fred и $barney. Например, чтобы определить большее из значений $wilma и $betty функцией larger_of_fred_or_barney, вам придется сначала скопировать их в $fred и $barney. Если в этих переменных хранятся какие-нибудь полезные данные, их придется временно сохранить в других переменных (скажем, $save_fred и $save_barney), а после вызова функции скопировать обратно в $fred и $barney.

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

$n = &max(10, 15); # Функции передаются два аргумента

Список передается функции, то есть функция может использовать его так, как считает нужным. Конечно, этот список должен гдеQто храниться, поэтому Perl автоматически сохраняет список параметров (другое название списка аргументов) в специальной переменной массива с именем @_ на время всего вызова функции. Функция может обратиться к этой переменной, чтобы узнать как количество аргументов, так и их значения.


Таким образом, первый параметр функции хранится в элементе $_[0], второй – в $_[1] и т. д. Но (очень важный момент!) эти переменные не имеют никакого отношения к переменной $_– не более чем $dino[3] (элемент массива @dino) к переменной $dino (совершенно самостоятельная скалярная переменная). Просто список параметров должен храниться в каком-то массиве, чтобы с ним можно было работать в пользовательской функции, и Perl применяет для этой цели массив @_.

Теперь мы можем записать функцию &max, похожую на &larger_of_ fred_or_barney. Но вместо $fred она использует первый параметр функции ($_[0]), а вместо $barney – второй параметр ($_[1]). И в результате может получиться следующий код:

sub max {
# Сравните с &larger_of_fred_or_barney
if ($_[0] > $_[1]) {
$_[0];
} else {
$_[1];
}
}

Как мы уже сказали, так действовать можно. Но из-за многочисленных индексов код выглядит уродливо, его трудно читать, писать, проверять и отлаживать. Вскоре вы увидите более элегантное решение. К тому же у этой функции есть и другая проблема: ее компактное и симпатичное имя &max не напоминает нам о том, что функция правильно работает только для двух аргументов:

$n = &max(10, 15, 27); # Лишний аргумент !

Лишние аргументы игнорируются; функция просто не обращается к $_[2].


Perl не интересует, есть какоеQнибудь значение в списке аргументов или нет. Недостающие параметры тоже игнорируются – при попытке обратиться к элементу за границей массива @_ вы просто получите undef, как и для любого другого массива. Позднее в этой главе вы увидите, как написать более универсальную версию &max, работающую с произвольным количеством параметров. Переменная @_ является приватной для этой пользовательской функции;1 если @_ содержит глобальное значение, оно сохраняется перед вызовом функции, а затем восстанавливается после возврата управления.

Из этого также следует, что пользовательская функция может передать аргументы другой функции, не рискуя потерять свой массив @_ – вложенный вызов получит собственную копию @_. Даже если функция вызывает сама себя в результате рекурсии, при каждом вызове будет создаваться новая копия @_, поэтому @_ всегда содержит список параметров для текущего вызова.

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Perl на эту тему:
Возвращаемые значения
Вызов пользовательской функции
Вызов функции без &
Директива use strict
Нескалярные возвращаемые значения

Вернуться в раздел: Perl / 3. Пользовательские функции