Глава 6.10. Встроенные функции (продолжение)

6.10.1. Функции работы с массивами и списками

Функция Описание
grep Проверяет заданное выражение для каждого элемента списка.
join Объединяет элементы списка в одну строку.
map Вычисляет заданное выражение для каждого элемента списка.
pop Выталкивает последний элемент массива.
push Вталкивает элементы в конец массива.
reverse Переставляет элементы списка в обратном порядке.
shift Выталкивает первый элемент массива.
sort Сортирует список.
splice Удаляет или заменяет часть элементов массива.
unshift Вталкивает элементы в начало массива.

Функция grep

Синтаксис: grep аргумент, список
Аргументы: аргумент — выражение или блок
           список — список выражений
Результат: список значений

Функция grep просматривает элементы списка, поочередно присваивая их переменной $_, для каждого элемента вычисляет значение аргумента и возвращает список тех элементов, для которых это значение истинно. В скалярном контексте возвращает количество элементов списка, для которых значение аргумента истинно. Помните, что возвращаемый список состоит из синонимов элементов исходного списка, поэтому изменение значений его элементов влечет изменение соответствующих элементов исходного списка. Следующий пример удаляет все комментарии из списка:

@x = ('aaa', '#comment1', 'bbb', '#comment2')
@y = grep {!/^#/} @x; # 'aaa', 'bbb'
@y = grep(!/^#/, @x); # то же самое

Функция join

Синтаксис: join разделитель, список
Аргументы: разделитель — строковое выражение
           список — список выражений
Результат: строковое значение

Функция join возвращает новую строку, состоящую из всех элементов списка, между которыми вставлено значение разделителя. Пример:

print join(': ', 'aaa', 'bbb', 'ccc');	# 'aaa: bbb: ccc'

Функция map

Синтаксис: map аргумент, список
Аргументы: аргумент — выражение или блок
           список — список выражений
Результат: список значений

Функция map просматривает элементы списка, поочередно присваивая их переменной $_, для каждого элемента вычисляет значение аргумента и возвращает список полученных значений. В скалярном контексте возвращает размер списка, сгенерированного таким образом. Следующий пример преобразует числовые элементы массива в соответствующие символы:

@nums = (97, 98, 99);
@chars = map(chr, @nums); # ('a', 'b', 'c')

Функция pop

Синтаксис: pop массив
Аргументы: массив — именованный массив
Результат: скалярное значение

Функция pop удаляет из массива его последний элемент и возвращает его в качестве результата. Если аргумент опущен, то массив принимается равным переменной @ARGV в главной программе и @_ в подпрограммах. Если массив пуст, то эта функция возвращает undef. Пример:

@a = (1, 2, 3, 4, 5);
print pop @a; # 5
print @a;     # (1, 2, 3, 4)

Функция push

Синтаксис: push массив, список
Аргументы: массив — именованный массив
           список — список выражений
Результат: числовое значение

Функция push добавляет элементы списка в конец массива и возвращает количество добавленных элементов. Пример:

@a = (1, 2, 3);
push @a, 4, 5;
print @a; # (1, 2, 3, 4, 5)

Функция reverse

Синтаксис: reverse список
Аргументы: список — список выражений
Результат: список значений

Функция reverse возвращает список, состоящий из элементов исходного списка, расположенных в обратном порядке. В скалярном контексте она объединяет все элементы списка в строку и возвращает эту строку в обратном порядке символов. Примеры:

@a = (1, 2, 3);
@b = reverse @a; # (3, 2, 1)
$s = reverse @a; # '321'

Функция shift

Синтаксис: shift массив
Аргументы: массив — именованный массив
Результат: скалярное значение

Функция shift удаляет из массива его первый элемент и возвращает его в качестве результата. Если аргумент опущен, то массив принимается равным переменной @ARGV в главной программе и @_ в подпрограммах. Если массив пуст, то эта функция возвращает undef. Пример:

@a = (1, 2, 3, 4, 5);
print shift @a; # 1
print @a;       # (2, 3, 4, 5)

Функция sort

Синтаксис: sort аргумент, список
Аргументы: аргумент — подпрограмма или блок
           список — список выражений
Результат: список значений

Функция sort сортирует элементы списка и возвращает новый отсортированный список. Порядок сортировки задается аргументом. Если он опущен, то производится сортировка в лексикографическом порядке. В противном случае аргумент должен быть либо именем подпрограммы, либо блоком, задающим безымянную подпрограмму. Эта подпрограмма принимает два аргумента $a и $b и должна возвращать отрицательное число, если $a < $b, нуль, если $a = $b, и положительное число, если $a > $b. Следующий пример сортирует массив строк без учета регистра символов:

@sorted = sort {uc($a) cmp uc($b)} @array;

Функция splice

Синтаксис: splice массив, начало, длина, список
Аргументы: массив — именованный массив
           начало, длина — числовые выражения
           список — список выражений
Результат: числовое значение

Функция splice удаляет элементы массива, начиная с индекса начало и в количестве длина. Если задан список, то его элементы вставляются вместо удаленных. Функция возвращает список удаленных элементов, а в скалярном контексте — последний удаленный элемент или undef, если ничего не удалено.

Если начало отрицательно, то оно отсчитывается от конца массива. Если длина опущена, то удаляются элементы до конца массива; если она отрицательна, то она складывается с длиной массива. Если и начало, и длина опущены, то удаляются все элементы массива.

Пример: следующие операторы эквивалентны по своему результату:

push(@a, $x, $y)       splice(@a, @a, 0, $x, $y)
pop(@a)                splice(@a, -1)
shift(@a)              splice(@a, 0, 1)
unshift(@a, $x, $y)    splice(@a, 0, 0, $x, $y)
$a[$x] = $y            splice(@a, $x, 1, $y)

Функция unshift

Синтаксис: unshift массив, список
Аргументы: массив — именованный массив
           список — список выражений
Результат: числовое значение

Функция unshift добавляет элементы списка в начало массива и возвращает количество добавленных элементов. Пример:

@a = (1, 2, 3);
unshift @a, 4, 5;
print @a; # (4, 5, 1, 2, 3)

6.10.2. Функции работы с ассоциативными массивами

Функция Описание
delete Удаляет элемент(ы) массива или ассоциативного массива.
each Итерация ассоциативных массивов.
exists Проверяет наличие элемента в массиве или ассоциативном массиве.
keys Возвращает список ключей ассоциативного массива.
values Возвращает список значений ассоциативного массива.

Функция delete

Синтаксис: delete аргумент
Аргументы: аргумент — выражение
Результат: значение или список значений

Функция delete удаляет элемент или вырезку массива или ассоциативного массива, заданные аргументом и возвращает их (или undef, если ничего не удалено). Если удаляются элементы в конце массива, то длина массива соответственно уменьшается; если же удаляются элементы в середине массива, то им присваивается неопределенное значение, и размер массива не изменяется. Примеры:

@a = (1, 2, 3, 4, 5);
@b = delete @a[1..2];	# @b = (2, 3)
%colors = (black => 0x000000, red => 0xff0000, blue => 0x0000ff, green => 0x008000);
@x = delete @colors{'black', 'red'}; # @x = (0x000000, 0xff0000)

Функция each

Синтаксис: each аргумент
Аргументы: аргумент — ассоциативный массив
Результат: список (ключ, значение)

Функция each предназначена для итеративного просмотра ассоциативного массива. При каждом вызове она возвращает список (ключ, значение) для очередного элемента аргумента (в скалярном контексте возвращается ключ очередного массива). Когда ассоциативный массив просмотрен полностью, возвращается пустой список или undef в скалярном контексте. Для каждого ассоциативного массива создается один итератор, который сбрасывается по завершении итерации массива или при вызове функции keys или values. Типичный цикл просмотра ассоциативного массива имеет вид:

%colors = (red => 0xff0000, blue => 0x0000ff, green => 0x008000);
while (($key, $value) = each %colors) {
  print "$key = $value\n";
}

Функция exists

Синтаксис: exists аргумент
Аргументы: аргумент — выражение
Результат: логическое значение

Функция exists проверяет существование элемента массива или ассоциативного массива, заданного аргументом. Она возвращает истину, если такой элемент когда-либо был инициализирован, даже если сейчас он имеет неопределенное значение. Примеры:

print "Существует\n" if exists $array[$index];
print "Существует\n" if exists $hash{$key};

Функция keys

Синтаксис: keys аргумент
Аргументы: аргумент — ассоциативный массив
Результат: список ключей

Функция keys возвращает список ключей данного ассоциативного массива. (в скалярном контексте возвращается количество элементов массива). Порядок ключей в этом списке не определен, но гарантируется, что он тот же, что и в функциях each или values. Следующий пример выводит на экран содержимое системного окружения в алфавитном порядке.

foreach $key (sort(keys %ENV)) {
  print $key, '=', $ENV{$key}, "\n";
}

Функция values

Синтаксис: values аргумент
Аргументы: аргумент — ассоциативный массив
Результат: список значений

Функция values возвращает список значений данного ассоциативного массива. (в скалярном контексте возвращается количество элементов массива). Порядок значений в этом списке не определен, но гарантируется, что он тот же, что и в функциях each или keys. Следующий пример выводит на экран содержимое системного окружения.

@keys = keys %ENV;
@values = values %ENV;
while (@keys) {
  print pop(@keys), '=', pop(@values), "\n";
}

6.10.3. Функции работы с временем

Функция Описание
gmtime Преобразует время UTC в список значений.
localtime Преобразует местное время в список значений.
time Возвращает текущее время.
times Возвращает список времен работы процесса.

Функция gmtime

Синтаксис: gmtime время
Аргументы: время — значение функции time
Результат: список числовых значений

Функция gmtime преобразует время UTC, возвращенное функцией time, в список из восьми числовых значений и возвращает его. Результирующий список состоит из следующих элементов:

Номер элемента Описание
0 Секунды (0 — 59).
1 Минуты (0 — 59).
2 Часы (0 — 23).
3 День месяца (1 — 31).
4 Месяц (0 = январь, …, 11 = декабрь).
5 Номер года минус 1900.
6 День недели (0 = воскресенье, …, 6 = суббота).
7 День года (0 — 365).

Если аргумент опущен, то возвращает указанный список значений для текущего времени. В скалярном контексте возвращает строку, содержащую текстовое представление времени UTC. Примеры:

($sec, $min, $hour, $mday, $mon, $year, $wday, $yday) = gmtime(time);
print scalar(gmtime); # "Friday Jun 22 05:09:20 2001"

Функция localtime

Синтаксис: localtime время
Аргументы: время — значение функции time
Результат: список числовых значений

Функция localtime преобразует местное время, возвращенное функцией time, в список из девяти числовых значений и возвращает его. Результирующий список состоит из следующих элементов:

Номер элемента Описание
0 Секунды (0 — 59).
1 Минуты (0 — 59).
2 Часы (0 — 23).
3 День месяца (1 — 31).
4 Месяц (0 = январь, …, 11 = декабрь).
5 Номер года минус 1900.
6 День недели (0 = воскресенье, …, 6 = суббота).
7 День года (0 — 365).
8 Истинно, если действует переход на летнее время.

Если аргумент опущен, то возвращает указанный список значений для текущего времени. В скалярном контексте возвращает строку, содержащую текстовое представление местного времени. Примеры:

($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
print scalar(localtime); # "Friday Jun 22 11:09:20 2001"

Функция time

Синтаксис: time
Результат: числовое значение

Функция time возвращает текущее время в виде числа, равного количеству секунд от точки отсчета, определенной операционной системой (00:00:00 1 января 1904 г. в MacOS и 00:00:00 UTC 1 января 1970 г. в большинстве других ОС). Для преобразования полученного числа во время и дату используются функции gmtime и localtime.

Функция times

Синтаксис: times
Результат: список числовых значений

Функция times возвращает список из четырех числовых значений. В Unix эти значения таковы:

Номер элемента Описание
0 Пользовательское время процесса в секундах.
1 Системное время процесса в секундах.
2 Пользовательское время дочернего процесса в секундах.
3 Системное время дочернего процесса в секундах.

В Windows элемент списка с индексом 0 содержит время работы процесса, а остальные элементы равны нулю. Пример:

($user, $system, $cuser, $csystem) = times;

6.10.4. Прочие функции общего назначения

Функция Описание
caller Возвращает информацию о контексте вызова подпрограммы.
defined Проверяет, определено ли значение аргумента.
die Фатальное завершение программы.
eval Выполняет аргумент как PERL-программу.
exit Завершение работы программы.
ref Проверяет, является ли аргумент ссылкой.
reset Сбрасывает значения заданных переменных.
scalar Преобразует аргумент в скаляр.
undef Делает значение переменной неопределенным.
warn Выводит сообщение на stderr.

Функция caller

Синтаксис: caller аргумент?
Аргументы: аргумент — скалярное выражение
Результат: список значений

Функция caller возвращает контекст вызова текущей подпрограммы. В скалярном контексте она возвращает имя пакета, вызвавшего текущую подпрограмму, или undef, если функция вызвана не из подпрограммы или eval. В списочном контексте возвращается список

($package, $filename, $line) = caller;

где $package — имя вызвавшего подпрограмму пакета, $filename — имя соответствующего файла, $line — номер строки файла, в которой произошел вызов.

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

($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext,
$is_require, $hints, $bitmask) = caller($n);

Здесь $hasargs истинно, если подпрограмма вызвана с аргументами, а $hints и $bitmask содержат внутренние флаги компилятора, описывающие процесс компиляции подпрограммы.

Если n-ый элемент фрейма — это подпрограмма, то $subroutine содержит ее имя, а $evaltext и $is_require не определены.

Если же n-ый элемент фрейма — это eval, то $subroutine равно '(eval)', $evaltext содержит текст eval-выражения, а $is_require истинно, если фрейм создан функциями require или use. В частности, для операции eval блок $filename равно '(eval)', но $evaltext не определено.

При использовании расширенной формы этой функции, помните, что в процессе компиляции оптимизатор кода может удалять избыточные, по его мнению, фреймы вызова подпрограмм. Это означает, что при n > 1 нельзя быть уверенным в том, информацию о какой подпрограмме вернет caller(n).

Функция defined

Синтаксис: defined выражение
Аргументы: выражение — любое выражение
Результат: логическое значение

Функция defined возвращает истину, если значение выражения отлично от undef. Если аргумент опущен, то выражение принимается равным значению переменной $_. Примеры:

print "$val\n" while defined($val = pop(@array));
$debug = 0 unless defined $debug;

Применение этой функции к массивам и ассоциативным массивам является морально устаревшим. Вместо этого рекомендуется просто проверять их размер:

if (@array) { ... }
if (%hash)  { ... }

Функция die

Синтаксис: die список
Аргументы: список — список выражений

Функция die выводит значения списка на устройство stderr и завершает работу программы. При этом код завершения программы берется из переменной $!. Если значение этой переменной равно нулю, то код завершения равен ($? >> 8). Если и это значение равно нулю, то код завершения равен 255.

Если сообщение об ошибке не заканчивается символом '\n', то после него выводится название файла и номер строки в нем, содержащих эту функцию. Например, сценарий

$name = 'list.txt';
open(MYFILE, $name) or die 'File ', $name, ' not found';

выведет на консоль строку вида File list.txt not found at test.pl line 2.

Если список пуст и переменная $@ содержит значение, то выводится значение этой переменной с добалением строки "\t...propagated", имени файла и номера строки. Если же и переменная $@ пуста, то сообщение об ошибке имеет вид "Died at file.pl line nnn".

Внутри eval() эта функция заносит сообщение об ошибке в переменную $@ и завершает eval с неопределенным значением. Это позволяет использовать ее для генерации исключений. Пример:

$a = 1; $b = 0;
eval { die "Zero divide" if $b == 0; $answer = $a / $b; };
die if $@;

Этот сценарий завершится с сообщением:

Zero divide at test.pl line2.
        ...propagated at test.pl line3.

Функция eval

Синтаксис: eval аргумент
Аргументы: аргумент — выражение или блок

Если аргумент является выражением, то его значение вычисляется в скалярном контексте, компилируется и исполняется как PERL-сценарий. Если аргумент опущен, то вычисляется значение пераменной $_. Эта форма функции eval позволяет динамически строить фрагменты PERL-программы.

Если аргумент является блоком, то он компилируется во время компиляции самой функции eval, а исполняется в контексте текущей программы. Обратите внимание, что такой вызов не считается вырожденным циклом и к нему не применимы операторы last, next и redo. Эта форма функции обычно используется для обработки исключений.

И в значении выражения, и в блоке последний символ точка с запятой может быть опущен.

В обоих случаях функция eval возвращает значение последнего вычисленного в ней выражения. Можно использовать и оператор return, так же, как в подпрограммах. ВОзвращаемое значение вычисляется в зависимости от контекста, в котором вызвана функция eval (подробнее об этом см. описание wantarray).

Если произошла ошибка компиляции или была вызвана функция die(), то eval возвращает неопределенное значение, а в переменную $@ заносится сообщение об ошибке. Если ошибок не возникло, то в $@ заносится пустая строка.

Пример использования eval для обработки исключения:

$a = 1; $b = 0;
eval { $answer = $a / $b };
warn $@ if $@;

Примеры использования eval для динамического вычисления выражений:

eval $x;       # 1
eval "$x";     # 2
eval '$x';     # 3
eval { $x };   # 4

Выражения 1 и 2 компилируют PERL-программу, содержащуюся в переменной $x и выполняют ее. Выражения 3 и 4 просто возвращают значение переменной $x.

Функция exit

Синтаксис: exit выражение
Аргументы: выражение — любое выражение

Функция exit вычисляет значение выражения и завершает работу программы с полученным кодом завершения. Если аргумент опущен, то код завершения равен нулю (по системным соглашениям, это означает нормальное завершение программы). Важно понимать, что работа программы не завершается немедленно; перед этим будут вызваны деструкторы всех загруженных пакетов и деструкторы всех созданных объектов. Пример:

while (1) {
  $ans = <STDIN>;             # принимаем строку с клавиатуры
  exit 0 if $ans =~ /^[Xx]/;  # завершаем работу, если она начинается с X
}

В тех случаях, когда необходимо немедленное завершение программы без вызова деструкторов, нужно пользоваться функцией POSIX:_exit(), например:

use POSIX;
  . . .
POSIX:_exit 0;
}

Функция ref

Синтаксис: ref выражение?
Аргументы: выражение — любое выражение
Результат: строка или неопределенное значение

Функция ref проверяет, является ли выражением ссылкой. Если аргумент опущен, то выражение принимается равным значению переменной $_. Если выражение не является ссылкой, то возвращается неопределенное значение. В противном случае возвращается строка, означающая тип данных, на который ссылается выражение, в соответствии со следующей таблицей:

Строка Значение
"SCALAR" Ссылка на скалярную переменную.
"ARRAY" Ссылка на массив.
"HASH" Ссылка на ассоциативный массив.
"CODE" Ссылка на подпрограмму.
"REF" Ссылка на ссылку.
"GLOB" Ссылка на typeglob.
"LVALUE" Ссылка на выражение, допускающее присваивание.

Если ссылка была преобразована функцией bless в на объект, то возвращается строка, содержащая имя пакета. Примеры:

print "x не является ссылкой\n" unless ref($x);

print ref(\$x);               # "SCALAR"
print ref(\@a);               # "ARRAY"
print ref(\%h);               # "HASH"
print ref(\&mysub);           # "CODE"
print ref(\\$x);              # "REF"
print ref(\*x);               # "GLOB"
print ref(\substr($x, 0, 1)); # "LVALUE"

Функция reset

Синтаксис: reset выражение?
Аргументы: выражение — список букв

Функция reset используется в блоке continue операторов цикла для сброса значений переменных в конце цикла. Все переменные и массивы текущего пакета, имена которых начинаются с букв, заданных выражением, получают неопределенное значение. Сбрасывается значение только глобальных переменных; локальные переменные, объявленные функцией my(), не изменяют своего значения. Если выражение опущено, то сбрасывается статус единственного сопоставления с образцом. Примеры:

reset 'XY';   # сбрасывает все переменные, чьи имена начинаются с X или Y
reset 'a-z';  # сбрасывает переменные, чьи имена начинаются со строчной буквы
reset;        # разрешает единственное сопоставление с образцом

Не следует использовать вызов reset 'A-Z', поскольку он сбросит значения специальных переменных @ARGV, @INC и %ENV.

Функция scalar

Синтаксис: scalar выражение
Аргументы: выражение — любое выражение
Результат: скалярное значение

Функция scalar вычисляет значение выражения в скалярном контексте и возвращает его. Иными словами:

  • для скалярного выражения она возвращает его значение;
  • для массива или списка она возвращает его длину;
  • для ассоциативного массива она возвращает строку вида "m/n", где m — количество заполненных пар, а n — общее количество пар в массиве.

Для вычисления значения выражения в контексте списка аналогичной функции не предусмотрено. Чтобы его получить, можно использовать конструкцию @{[(выражение)]}, хотя в большинстве случаев достаточно использовать (выражение). Следующий пример

@nums = (1, 2, 3);
print "Size of my array is ".scalar(@nums)."\n";

keys(%colors) = 16;
%colors = (red => 0xff0000, blue => 0x0000ff, green => 0x008000);
print "Size of my hash is ".scalar(%colors)."\n";

print "My sub returned @{[mysub(1,2,3)]}\n";

sub mysub { @_ }

выведет на экран текст:

Size of my array is 3
Size of my hash is 3/16
My sub returned 1 2 3

Функция undef

Синтаксис: undef выражение?
Аргументы: выражение — любое выражение, допускающее присваивание
Результат: неопределенное значение

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

undef $x;
undef @array;
undef %hash;
undef &mysub;
undef *xyz;   # сбрасывает значения $xyz, @xyz, %xyz, &xyz

Функция warn

Синтаксис: warn список
Аргументы: список — список выражений

Функция warn выводит значения списка на устройство stderr. Если список не задан и переменная $@ содержит непустую строку, то выводится ее содержимое с добавлением строки "\t...caught at file.pl line nnn". Если же переменная $@ пуста, то выводится сообщение "Warning: Something's wrong at file.pl line nnn".