|
Для применения подпрограммы ее
необходимо определить либо в текущем
модуле (файле), либо во внешнем модуле (файле).
Подпрограммы определяются и декларируются
следующим образом:
- 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 будет содержать имя
несуществующей подпрограммы. Данный
механизм очень удобен для средств отладки.
|