$last_index = $#array; # индекс последнего элемента @array
Так, например, можно выбрать элемент массива с помощью встроенного генератора случайных чисел rand, который возвращает дробное число от 0 до числа, указанного ему в качестве аргумента. Ограничим случайные числа номером последнего индекса в массиве и будем округлять их до целых значений функцией int:
$random_element = $array[int(rand($#array))];
В $#array можно присвоить новое значение последнего индекса, при этом размер массива изменится. Но такое действие обычно не требуется, так как массив при необходимости увеличивается автоматически. Размер массива в Perl не ограничивается, то есть массив может занимать всю отведенную программе память.
В операции присваивания отдельные элементы массива рассматриваются как обычные скаляры. Ниже приведены примеры, по-разному выполняющие одно и то же присваивание элементам массива:
$birthday[0] = 18; $birthday[1] = 12; $birthday[2] = 1987;
($birthday[0], $birthday[1], $birthday[2]) = (18, 12, 1987);
(Хотя более естественно для подобного присваивания воспользоваться срезом массива: @birthday[0, 1, 2] = (18, 12, 1987), но о срезах пойдет речь чуть позже в этой лекции.)
Если попытаться присвоить значение элементу с индексом больше текущего размера массива, массив автоматически увеличивается до необходимой длины, а добавленные элементы получают неопределенное значение:
$birthday[5] = 'Perl'; # размер @birthday теперь 5
# значение $birthday[3] и $birthday[4] не определено
При попытке обратиться к элементу массива с несуществующим индексом будет возвращено неопределенное значение, но ошибки во время выполнения программы не возникнет.
$array[$#array+100] # неопределенно
При использовании в качестве индекса массива дробного числа будет взята его целая часть, то есть $array[3.5] рассматривается как $array[3].
Часто требуется последовательно перебрать все элементы массива, от первого до последнего, для обработки или вывода их значений. Это можно сделать вполне традиционным образом, с помощью цикла for, как это записывается в языках C или Java, а именно:
for (my $i = 0; $i < scalar @array; $i++) {
print "$array[$i] ";
}
Perl предлагает для подобных действий более удобный способ с использованием цикла foreach, в котором все элементы массива поочередно совмещаются с указанной скалярной переменной. Эта переменная на время выполнения цикла становится синонимом очередного элемента массива, поэтому ее значение доступно не только для чтения, но и для изменения. Только что приведенный пример можно переписать так:
foreach my $element (@array) { # $element это синоним
print "$element "; # очередного элемента $array[$i]
}
Можно то же самое записать еще более кратко с помощью модификатора foreach, который поочередно перебирает все элементы массива, рассматривая специальную переменную $_ как синоним текущего элемента массива (то есть переменная $_ совмещается с очередным элементом массива):
print "$_ " foreach @array;
Так что каждый Perl-программист выбирает свой способ перебора всех элементов массива в полном соответствии с лозунгом TIMTOWTDI.
Обратите внимание, что значения элементов массива, будучи обычными скалярами, интерполируются в строках, заключенных в двойные кавычки. Целые массивы тоже интерполируются, если имя массива появляется в строке, обрамленной двойными кавычками. При этом значения элементов массива разделяются символом, хранящимся в специальной переменной $" (по умолчанию - пробелом). Вот еще один способ напечатать значения всех элементов массива, разделяя их двоеточиями:
$" = ':'; # установим разделитель элементов
print "@array";
С помощью индексов можно обращаться не только к элементам массива, но и к элементам списка, в том числе и литерального. Для этого после закрывающей скобки списка указывается значение индекса в квадратных скобках:
$fifth = (10..15)[5]; # то же, что $fifth = 15;
Обращение по индексу к элементу в списке констант приобретает смысл, если индекс динамически вычисляется при выполнении программы. Вот, например, один из способов преобразовать десятичное число в шестнадцатеричное:
$hex = (0..9,'A'..'F')[$dec]; # при $dec==12 в $hex будет 'C'
Подобным же образом удобно обращаться к элементу списка, возвращаемого функцией. Например, так можно извлечь день месяца, зная, что у него 3-й индекс в результирующем списке функции localtime: