Для применения подпрограммы ее
необходимо определить либо в
текущем модуле (файле), либо во
внешнем модуле (файле).
Подпрограммы определяются и
декларируются следующим образом:
sub имя; - Только декларация.
Определение ниже.
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 переменных как:
my(список) = выражение;
Так для вышеприведенного примера лучше было написать:
my($m) = $_[0];
Переменные типа 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
будет содержать имя несуществующей
подпрограммы. Данный механизм
очень удобен для средств отладки.
Знаете ли Вы, почему "черные дыры" - фикция? Согласно релятивистской мифологии, "чёрная дыра - это область в пространстве-времени, гравитационное притяжение которой настолько велико, что покинуть её не могут даже объекты, движущиеся со скоростью света (в том числе и кванты самого света). Граница этой области называется горизонтом событий, а её характерный размер - гравитационным радиусом. В простейшем случае сферически симметричной чёрной дыры он равен радиусу Шварцшильда". На самом деле миф о черных дырах есть порождение мифа о фотоне - пушечном ядре. Этот миф родился еще в античные времена. Математическое развитие он получил в трудах Исаака Ньютона в виде корпускулярной теории света. Корпускуле света приписывалась масса. Из этого следовало, что при высоких ускорениях свободного падения возможен поворот траектории луча света вспять, по параболе, как это происходит с пушечным ядром в гравитационном поле Земли. Отсюда родились сказки о "радиусе Шварцшильда", "черных дырах Хокинга" и прочих безудержных фантазиях пропагандистов релятивизма. Впрочем, эти сказки несколько древнее. В 1795 году математик Пьер Симон Лаплас писал: "Если бы диаметр светящейся звезды с той же плотностью, что и Земля, в 250 раз превосходил бы диаметр Солнца, то вследствие притяжения звезды ни один из испущенных ею лучей не смог бы дойти до нас; следовательно, не исключено, что самые большие из светящихся тел по этой причине являются невидимыми." [цитата по Брагинский В.Б., Полнарёв А. Г. Удивительная гравитация. - М., Наука, 1985] Однако, как выяснилось в 20-м веке, фотон не обладает массой и не может взаимодействовать с гравитационным полем как весомое вещество. Фотон - это квантованная электромагнитная волна, то есть даже не объект, а процесс. А процессы не могут иметь веса, так как они не являются вещественными объектами. Это всего-лишь движение некоторой среды. (сравните с аналогами: движение воды, движение воздуха, колебания почвы). Подробнее читайте в FAQ по эфирной физике.