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

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

Жанры

Язык программирования 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

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

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

Катарсис

Таран Михаил
Фантастика:
боевая фантастика
постапокалипсис
6.25
рейтинг книги
Катарсис

Вечный зов (Том 2)

Иванов Анатолий Михайлович
Научно-образовательная:
история
7.50
рейтинг книги
Вечный зов (Том 2)

Суженая из другого мира

LitaWolf
1. Суженая из другого мира
Любовные романы:
любовно-фантастические романы
6.25
рейтинг книги
Суженая из другого мира

Пушкин

Лотман Юрий Михайлович
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Пушкин

Перевертыш. Часть 3

Гаркавый Владимир Александрович
Вселенная EVE Online
Фантастика:
боевая фантастика
5.00
рейтинг книги
Перевертыш. Часть 3

Наследник $$$ уровня. Трилогия

Еслер Андрей
Технофеодализм.inc
Фантастика:
городское фэнтези
фэнтези
попаданцы
5.00
рейтинг книги
Наследник $$$ уровня. Трилогия

Неучтенный элемент. Том 10

NikL
10. Антимаг. Вне системы
Фантастика:
фэнтези
5.25
рейтинг книги
Неучтенный элемент. Том 10

Дозор (5 романов)

Лукьяненко Сергей
Фантастика:
альтернативная история
фэнтези
8.22
рейтинг книги
Дозор (5 романов)

Белая Башня. Хроники Паэтты. Книга I

postsabbath
1. Хроники Паэтты
Фантастика:
фэнтези
5.00
рейтинг книги
Белая Башня. Хроники Паэтты. Книга I

Избранное. Компиляция. Книги 1-11

Пулман Филип
Фантастика:
фэнтези
героическая фантастика
5.00
рейтинг книги
Избранное. Компиляция. Книги 1-11

Чинди

Макдевит Джек
3. Космоархеологи
Фантастика:
космическая фантастика
6.40
рейтинг книги
Чинди

Я до сих пор царь. Книга XXXII

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

Осажденная крепость. Нерассказанная история первой холодной войны

Млечин Леонид Михайлович
Научно-образовательная:
история
5.00
рейтинг книги
Осажденная крепость. Нерассказанная история первой холодной войны

Холодное Сердце Железных Королевств

Кросскун / Krosskun
Проза:
современная проза
5.00
рейтинг книги
Холодное Сердце Железных Королевств