Для применения подпрограммы ее необходимо определить либо в текущем модуле (файле), либо во внешнем модуле (файле).
Подпрограммы определяются и декларируются следующим образом:
Все параметры передаются подпрограмме как массив @_.
Соответственно $_[0] - первый параметр, $_[1] - второй и т.д.
Массив @_ - локальный, но он содержит адреса параметров, поэтому
можно изменять значение параметров.
Возвращаемое значение подпрограммы - результат последнего оператора.
Это может быть как скаляр так и массив. Можно принудительно возвращать
результат используя функцию return().
Подпрограмму можно вызвать, используя префикс '&' перед именем
подпрограммы. Если подпрограмма предварительно продекларирована, то
префикс и скобки можно опустить.
Для применения переменных доступных только внутри блока или подпрограммы
необходимо определить их с помощью функции my(список).
my() декларирует private переменные в пределах текущей подпрограммы,
блока, функции eval() или do/require/use файлов. Private переменные
аналогичны auto переменным в С.
Пример:
Можно указывать начальные значения private переменных как:
В общем лучше использовать private переменные, т. к. это надежней и
быстрее. private переменные обеспечивают лексическую область применения
(видимости), а local - динамическую. Обычно это переменные форматов,
значение которых должно быть видимо из вызываемых подпрограмм.
Применение функции local() нецелесообразно в циклах, так как
она вызывается каждый раз и таким образом заметно увеличивает время
выполнения цикла.
Для краткого описания типа передаваемых подпрограмме параметров
можно применять прототипы. В Perl существуют следующие прототипы:
Иногда нужно в качестве параметра передать подпрограмме не значение
элемента массива, а ссылку на него, чтобы подпрограмма могла изменить
значение элемента. Для этого в Perl к имени переменной добавляется
символ '*' Подобное выражение называют 'type glob' так же как в Unix
символом '*' обозначают "все возможные значения". Поэтому '*' для
массива означает "все элементы массива".
Для скаляров употреблять '*' не имеет смысла, т.к. они и так передаются
ссылкой и вы можете изменять значение параметра, изменяя, например,
переменную $_[0].
Переопределение встроенных функций.
Большинство встроенных функций Perl можно переопределить своими
собственными. Обычно это делают для удобства совместимости Perl для
разных платформ систем.
Если вы попытаетесь вызвать несуществующую функцию, то Perl немедленно выдаст
сообщение об ошибке. Но если вы определите подпрограмму
с именем 'AUTOLOAD', то она будет вызвана с теми же параметрами,
а переменная $AUTOLOAD будет содержать имя несуществующей
подпрограммы. Данный механизм очень удобен для средств отладки.
Подпрограммы.
Для определения динамической анонимной подпрограммы можно указать:
Для импортирования подпрограмм из других модулей используйте:
Вызов подпрограммы:
имя(список параметров); # символ '&' можно не указывать.
имя список; # Если подпрограмма уже декларирована.
&имя; # Параметры в @_
Если переменная одна, то скобки можно опустить.
# Программа вычисления факториала.
print fact(3); # вычислить факториал 3*2*1
sub fact # Определяем подпрограмму.
{ my $m; # private переменная но не local !
$m = $_[0];
return 1 if $m <= 1;
return($m * fact($m -1));
}
Так для вышеприведенного примера лучше было написать:
Здесь:
Декларация Пример вызова sub mylink($$) mylink $old, $new sub myvec($$$) myvec $var, $offset, 1 sub myindex($$;$) myindex &getstring, "substr" sub myreverse(@) myreverse $a, $b, $c sub myjoin($@) myjoin ":",$a,$b,$c sub mypop(\@) mypop @array sub mysplice(\@$$@) mysplice @array, @array, 0, @pushme sub mykeys(\%) mykeys %{$hashref} sub myopen(*;$) myopen HANDLE, $name sub mypipe(**) mypipe READHANDLE, WRITEHANDLE sub mygrep(&@) mygrep { /foo/ } $a, $b, $c sub myrand($) myrand 42 sub mytime() mytime
Для этого нужно перечислить имена этих функций в виде:
и далее в модуле определить сами функции.