Язык программирования Perl
Шрифт:
Использование return в подпрограммах относится к хорошим привычкам программиста, поскольку делает исходный текст более понятным для того, кто будет читать программу и заниматься ее сопровождением. Ведь хорошо известно, что даже автору потребуются значительное время и усилия, чтобы вспомнить в деталях логику давно написанной им программы.
Помня о том, что списки в Perl - одномерные, становится понятным, что подпрограмма в Perl может возвращать только один список.
Пока что в приведенных примерах подпрограммы использовали значение глобальных переменных, но сама идея применения подпрограмм предполагает применение заложенного в них алгоритма для обработки передаваемых им параметров. Когда подпрограмма вызывается с набором аргументов, ей передается специальный массив с предопределенным именем @_, содержащий список переданных аргументов. В теле подпрограммы переданные значения доступны в виде элементов массива @_, что видно из следующего примера:
Количество переданных аргументов можно выяснить, запросив число элементов массива @_. Для обработки списка аргументов переменной длины часто используется встроенная функция shift, которая извлекает из массива параметров очередное значение, переданное подпрограмме:
Если переданные аргументы заданы переменными, то массив параметров @_ совмещается с переданными аргументами. Это означает, что изменение элементов массива приведет к изменению значений соответствующих переменных в вызывающей программе. Это можно проиллюстрировать следующим (несколько искусственным) примером:
Опыт показывает, что изменение значения аргументов ведет к трудно обнаруживаемым ошибкам и осложняет сопровождение программы, поэтому должно использоваться в исключительных случаях и всегда оговариваться в комментариях. Общепринятым способом работы с параметрами подпрограммы является присваивание значения аргументов списку переменных: это предохраняет аргументы от изменения и позволяет работать не с элементами массива, а с удобно названными переменными. Это видно из следующего примера:
Хотя подпрограмма может изменять значения глобальных переменных в вызывающей программе, требования надежности предписывают всегда передавать исходные данные в подпрограмму в виде аргументов, а результат ее работы получать в виде возвращаемого значения.
По той же причине, по которой подпрограмма не может возвращать несколько списков, она не может получать несколько отдельных списков в виде аргументов. Например, если подпрограмма вызвана так: subr1(@array1, @array2), то ей будет передан объединенный список из элементов двух массивов @array1 и @array2. Поэтому если необходимо передать несколько списочных объектов, то передаются ссылки на них, например: subr1(\@array1, \@array2).
При необходимости можно объявить подпрограмму до ее использования (forward declaration), а определение ее отнести в конец программного файла. При объявлении тело подпрограммы не записывается. Например:
В объявлении подпрограмм могут указываться прототипы, о которых речь пойдет немного позднее в этой лекции.
Подпрограммы в Perl вызываются, когда их имя употребляется в каком-либо выражении. В этот момент выполняются определенные в подпрограмме действия, а выражение получает возвращенный подпрограммой результат. Хотя довольно часто возвращаемое подпрограммой значение игнорируется. Про такое обращение к подпрограмме говорят, что она вызвана в пустом контексте (void context). Минимальное выражение для вызова подпрограммы состоит из одного имени подпрограммы, и это выражение превращается в предложение программы, когда после него стоит точка с запятой. Вот пример выражения, состоящего только из вызова подпрограммы в пустом (безразличном) контексте:
Кстати, в пустом контексте можно употреблять любые другие выражения, хотя, конечно, смысл в этом есть далеко не всегда:
Обращение к подпрограмме может записываться различными способами - главное, чтобы компилятор Рerl мог определить, что встретившийся идентификатор - это имя вызываемой подпрограммы. Дать подсказку об этом компилятору можно по-разному. В ранних версиях Perl при вызове перед именем подпрограммы требовался разыменовывающий префикс &. Например:
В современном Perl эта устаревшая форма вызова с префиксом & допустима и иногда используется. Гораздо чаще обращение к подпрограмме обозначается использованием круглых скобок после имени подпрограммы, даже если она вызывается без параметров. Как в этих примерах: