Добрый день. Я сейчас прохожу курс повышения квалификации - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?
|
Подпрограммы
Объявление подпрограмм
При необходимости можно объявить подпрограмму до ее использования (forward declaration), а определение ее отнести в конец программного файла. При объявлении тело подпрограммы не записывается. Например:
sub factorial; # вычислить факториал числа
В объявлении подпрограмм могут указываться прототипы, о которых речь пойдет немного позднее в этой лекции.
Вызов подпрограмм
Подпрограммы в Perl вызываются, когда их имя употребляется в каком-либо выражении. В этот момент выполняются определенные в подпрограмме действия, а выражение получает возвращенный подпрограммой результат. Хотя довольно часто возвращаемое подпрограммой значение игнорируется. Про такое обращение к подпрограмме говорят, что она вызвана в пустом контексте (void context). Минимальное выражение для вызова подпрограммы состоит из одного имени подпрограммы, и это выражение превращается в предложение программы, когда после него стоит точка с запятой. Вот пример выражения, состоящего только из вызова подпрограммы в пустом (безразличном) контексте:
yellow_submarine('We all live in a');
Кстати, в пустом контексте можно употреблять любые другие выражения, хотя, конечно, смысл в этом есть далеко не всегда:
2 * 2; # результат отброшен, есть смысл, если стоит... 'Истина где-то рядом'; # ...в конце подпрограммы $x++; # используется ради побочного эффекта
Обращение к подпрограмме может записываться различными способами - главное, чтобы компилятор Рerl мог определить, что встретившийся идентификатор - это имя вызываемой подпрограммы. Дать подсказку об этом компилятору можно по-разному. В ранних версиях Perl при вызове перед именем подпрограммы требовался разыменовывающий префикс &. Например:
&sub_without_parameters; # вызов подпрограммы без параметров &sub_with_parameters($arg1, $arg2); # и с параметрами
В современном Perl эта устаревшая форма вызова с префиксом & допустима и иногда используется. Гораздо чаще обращение к подпрограмме обозначается использованием круглых скобок после имени подпрограммы, даже если она вызывается без параметров. Как в этих примерах:
format_c(); # вызов подпрограммы без параметров format_text($text, $font, $size); # и с параметрами
Чтобы обращаться к пользовательской подпрограмме в стиле встроенных функций без круглых скобок, нужно чтобы определение или объявление подпрограммы было известно компилятору раньше ее вызова.
sub circle; # объявление пользовательской функции $area_of_circle = circle $radius; # вызов функции sub circle { # определение пользовательской функции return 3.141592653*$_[0]*$_[0]; # площадь круга }
В Perl эффективно реализована рекурсия, поэтому традиционные рекурсивные алгоритмы можно оформлять в виде вызова в подпрограмме самой себя. Например, как в классической функции вычисления факториала:
sub factorial ($) { # вычислить N! my $n = shift; return ($n <= 1) ? 1 : $n * factorial($n-1); }
Контекст вызова
Для разработки универсальных подпрограмм программисту нужно знать, в каком контексте была вызвана подпрограмма - какого возвращаемого значения от нее ожидают. Для этого в Perl предусмотрена функция wantarray(). Она возвращает истинное значение, если подпрограмма вызвана в списочном контексте, ложное значение, если подпрограмма вызвана в скалярном контексте, и неопределенное значение, если подпрограмма вызвана в пустом контексте. Проверка ожидаемого значения в подпрограмме и примеры ее вызова могут выглядеть так:
sub list_or_scalar { my @result = fill_result(); # формируем результаты if (!defined wantarray) { # пустой контекст - return; # не возвращаем значения } elsif (wantarray) { # списочный контекст - return @result; # возвращаем список } else { # скалярный контекст - return "@result"; # возвращаем скаляр } } list_or_scalar(); # вызов в пустом контексте my @list = list_or_scalar(); # вызов в списочном контексте my $scalar = list_or_scalar(); # вызов в скалярном контексте