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