Чтение онлайн

на главную - закладки

Жанры

Язык программирования Perl

Шохирев Михаил Васильевич

Шрифт:

format_text($text, $font, $size); # и с параметрами

Чтобы обращаться к пользовательской подпрограмме в стиле встроенных функций без круглых скобок, нужно чтобы определение или объявление подпрограммы было известно компилятору раньше ее вызова.

sub circle; # объявление пользовательской функции

$area_of_circle = circle $radius; # вызов функции

sub circle { # определение пользовательской функции

return 3.141592653*$_[0]*$_[0]; # площадь круга

}

В Perl эффективно реализована рекурсия, поэтому традиционные рекурсивные алгоритмы можно оформлять в виде вызова в подпрограмме самой себя. Например, как в классической функции вычисления факториала:

sub factorial ($) { # вычислить N!

my $n = shift;

return ($n <= 1) ? 1 : $n * factorial($n-1);

}

Для разработки универсальных подпрограмм программисту нужно знать, в каком контексте была вызвана подпрограмма - какого возвращаемого значения от нее ожидают. Для этого в Perl предусмотрена функция wantarray. Она возвращает истинное значение, если подпрограмма вызвана в списочном контексте, ложное значение, если подпрограмма вызвана в скалярном контексте, и неопределенное значение, если подпрограмма вызвана в пустом контексте. Проверка ожидаемого значения в подпрограмме и примеры ее вызова могут выглядеть так:

sub list_or_scalar {

my @result = fill_result; # формируем результаты

if (!defined wantarray) { # пустой контекст -

return; # не возвращаем значения

} elsif (wantarray) { # списочный контекст -

return @result; # возвращаем список

} else { # скалярный контекст -

return "@result"; # возвращаем скаляр

}

}

list_or_scalar; # вызов в пустом контексте

my @list = list_or_scalar; # вызов в списочном контексте

my $scalar = list_or_scalar; # вызов в скалярном контексте

В Perl программисту предоставляется возможность выполнить во время компиляции ограниченную проверку количества и типов параметров у подпрограммы. Это делается с помощью прототипа списка параметров. Для этого в определении и в объявлении подпрограммы после ее имени в круглых скобках указывается прототип. Прототип представляет из себя последовательность разыменовывающих суффиксов, определяющих количество параметров подпрограммы и типы их контекстов. Вот несколько примеров определения подпрограмм с прототипами:

# определение подпрограммы с 1-м параметром-скаляром

sub list_mp3 ($) {

my $path = $_[0];

# ...

}

# определение подпрограммы c 2-мя скалярными параметрами

sub translate ($$@) { # и списком скаляров

my ($from_lang, $to_lang, @words) = @_;

# ...

}

sub generate_test; # объявление подпрограммы без параметров

Для подпрограмм, определенных с прототипами, компилятор контролирует количество передаваемых аргументов и устанавливает ожидаемый подпрограммой контекст для каждого из аргументов. В приведенном далее вызове подпрограммы вместо массива ей будет передано количество элементов массива, поскольку прототип подпрограммы устанавливает скалярный контекст для единственного аргумента:

list_mp3 @dirs; # будет передан 1 скаляр: scalar @dirs

Перечень символов, применяемых для описания прототипов, с примерами определения подпрограмм приведен в таблице 12.1.

Таблица 12.1. Обозначение прототипов подпрограмм

Прототип Требования к параметрам Пример определения / описания Пример вызова
отсутствие аргументов sub mytime mytime;
$ скалярное значение sub myrand ($) sub myrename ($$) myrand 100; myrename $old, $new;
@ список скалярных значений (поглощает остальные параметры, поэтому употребляется последним в списке) sub myreverse (@) sub myjoin ($@) myreverse $a, $b, $c; myjoin ':', $x, $y, $z;
& подпрограмма sub mygrep (&@) mygrep {/pat/} $a, $b, $c;
* элемент таблицы символов (например, дескриптор файла) sub myopen (*$) myopen HANDLE, $name;
\ взятие ссылки на следующий за ней прототип sub mykeys (\%) sub mypop (\@) sub mypush(\@@) mykeys %hash; mypop @array; mypush @stack, $a, $b;
; разделитель обязательных параметров от необязательных (в конце списка) sub mysubstr ($$;$) mysubstr $str, $pos; mysubstr $str, $pos, $length;

Проверки на соответствие прототипам не выполняются, если подпрограмма вызывается устаревшим способом (с префиксом &), а также для методов и подпрограмм, вызываемых через ссылки.

Скалярные переменные могут хранить ссылки не только на данные, но и на подпрограммы. В операции взятия ссылки имя подпрограммы должно использоваться с разыменовывающим префиксом &, как это показано в следующем примере:

$ref2max = \&max; # взятие ссылки на подпрограмму

sub max { # вычисляет максимум из списка значений

my $maximum = shift;

foreach (@_) { $maximum = $_ if ($_ > $maximum); }

return $maximum;

}

print ref($ref2max); # будет выведено: CODE

Первый способ обращения к подпрограмме через ссылочную переменную оформляется аналогично обращению к элементу массива или хэша: после имени переменной, содержащей ссылку на подпрограмму, записывается операция разыменования ссылки (->), за которой обязательно указываются круглые скобки (со списком аргументов или без него), которые показывают, что это обращение к подпрограмме:

Поделиться:
Популярные книги

Запечатанный во тьме. Том 3

NikL
3. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 3

Обрыв

Гончаров Иван Александрович
Проза:
классическая проза
русская классическая проза
8.93
рейтинг книги
Обрыв

Кодекс Крови. Книга VIII

Борзых М.
8. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VIII

Изгой Проклятого Клана. Том 4

Пламенев Владимир
4. Изгой
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Изгой Проклятого Клана. Том 4

Менталист. Революция

Еслер Андрей
3. Выиграть у времени
Фантастика:
боевая фантастика
5.48
рейтинг книги
Менталист. Революция

Одержимый

Джеймс Питер
Top Thriller
Детективы:
триллеры
маньяки
8.67
рейтинг книги
Одержимый

Я еще не царь

Дрейк Сириус
25. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я еще не царь

Матабар

Клеванский Кирилл Сергеевич
1. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар

Кодекс Охотника. Книга VII

Винокуров Юрий
7. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
4.75
рейтинг книги
Кодекс Охотника. Книга VII

Черный Маг Императора 11

Герда Александр
11. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Черный Маг Императора 11

Двойник короля 17

Скабер Артемий
17. Двойник Короля
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Двойник короля 17

Родословная. Том 1

Ткачев Андрей Юрьевич
1. Линия крови
Фантастика:
городское фэнтези
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Родословная. Том 1

Вернувшийся: Новая жизнь. Том I

Vector
1. Вернувшийся
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Вернувшийся: Новая жизнь. Том I

Воронцов. Перезагрузка

Тарасов Ник
1. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фантастика: прочее
5.00
рейтинг книги
Воронцов. Перезагрузка