Для применения подпрограммы ее необходимо
определить либо в текущем модуле (файле), либо во внешнем модуле (файле).
Подпрограммы определяются и декларируются следующим образом:
- sub имя; - Только декларация. Определение
ниже.
- sub имя (прототипы); - То же но с декларацией
параметров.
- sub имя блок; - Декларация и определение.
- sub имя (прототипы) блок; - То же, но с
параметрами.
Для определения динамической анонимной подпрограммы
можно указать:
Для импортирования подпрограмм из других модулей используйте:
- use модуль qw(подпрограмма1 подпрограмма2 );
Вызов подпрограммы:
имя(список параметров);# символ '&' можно
не указывать.
имя список; # Если подпрограмма уже
декларирована.
&имя; # Параметры в @_
Все параметры передаются подпрограмме как массив @_.
Соответственно $_[0] - первый параметр, $_[1] - второй и т.д. Массив
@_ - локальный, но он содержит адреса параметров, поэтому можно изменять
значение параметров. Возвращаемое значение подпрограммы - результат
последнего оператора. Это может быть как скаляр так и массив. Можно
принудительно возвращать результат используя функцию return().
Подпрограмму можно вызвать, используя префикс '&' перед
именем подпрограммы. Если подпрограмма предварительно продекларирована,
то префикс и скобки можно опустить.
Private переменные.
Для применения переменных доступных только внутри блока
или подпрограммы необходимо определить их с помощью функции my(список).
Если переменная одна, то скобки можно опустить.
my() декларирует private переменные в пределах текущей
подпрограммы, блока, функции eval() или do/require/use файлов. Private
переменные аналогичны auto переменным в С.
Пример:
# Программа вычисления факториала.
print fact(3); # вычислить факториал 3*2*1
sub fact # Определяем подпрограмму.
{ my $m; # private переменная
но не local !
$m = $_[0];
return 1 if $m <= 1;
return($m * fact($m -1));
}
Можно указывать начальные значения private переменных
как:
Так для вышеприведенного примера лучше было написать:
Переменные типа local.
В общем лучше использовать private переменные,
т. к. это надежней и быстрее. private переменные обеспечивают лексическую
область применения (видимости), а local - динамическую. Обычно это переменные
форматов, значение которых должно быть видимо из вызываемых подпрограмм.
Применение функции local() нецелесообразно в циклах, так как она вызывается
каждый раз и таким образом заметно увеличивает время выполнения цикла.
Прототипы (prototypes).
Для краткого описания типа передаваемых
подпрограмме параметров можно применять прототипы. В Perl существуют
следующие прототипы:
| Декларация
| Пример вызова |
| 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 |
Здесь:
- \'символ' - параметр с типом 'символ'
- '@' или '%' - все оставшиеся параметры
как список
- '$' - скаляр
- '&' - безымянная подпрограмма
- '*' - ссылка на таблицу имен
- ';' - разграничитель обязательных и не
обязательных параметров.
Ссылка как параметр.
Иногда нужно в качестве параметра передать
подпрограмме не значение элемента массива, а ссылку на него, чтобы подпрограмма
могла изменить значение элемента. Для этого в Perl к имени переменной
добавляется символ '*' Подобное выражение называют 'type glob' так же
как в Unix символом '*' обозначают "все возможные значения". Поэтому
'*' для массива означает "все элементы массива". Для скаляров употреблять
'*' не имеет смысла, т.к. они и так передаются ссылкой и вы можете изменять
значение параметра, изменяя, например, переменную $_[0].
Переопределение встроенных
функций.
Большинство встроенных функций Perl
можно переопределить своими собственными. Обычно это делают для удобства
совместимости Perl для разных платформ систем.
Для этого нужно перечислить имена этих функций в виде:
- use subs 'функция1', 'функция2' ....;
и далее в модуле определить сами функции.
Автозагрузка.
Если вы попытаетесь вызвать несуществующую функцию,
то Perl немедленно выдаст сообщение об ошибке. Но если вы определите
подпрограмму с именем 'AUTOLOAD', то она будет вызвана с теми же параметрами,
а переменная $AUTOLOAD будет содержать имя несуществующей подпрограммы.
Данный механизм очень удобен для средств отладки.