Использование ссылок
При построении хеш-массива %months воспользуемся вспомогательным хеш-массивом %OrderedMonths, который будем использовать для задания порядка сортировки:
# вспомогательный массив %OrderedMonths %OrderedMonths =("January" › 0, "February" › l, "March" › 2, "April" › 3, "Мау" › 4, "June" › 5, "July" › 6, "August" › 7, "September" › 8, "October" › 9, "November" › 10, "December" › ll); # формирование структуры for $month (sort {$OrderedMonths{$a}< › $OrderedMonths{$b}} keys %OrderedMonths) { $i = $OrderedMonths{$month}; $months{$month}=$months[$ i];' }; # Вывод элементов хеш-массива %months for $month (sort {$OrderedMonths{$a}< › $OrderedMonths{$b}} keys %OrderedMonths) { print "$month\n"; $i = $OrderedMonths{$month); for $DayName (sort WeekOrder keys %{$months{$month}}) { print " $DayName @{$months[$i]{$DayName}}\n"; } };
В результате выполнения примера 9.3 будет распечатан календарь на 2000 год в виде:
January Monday 3 10 17 24 31 Tuesday 4 11 18 25 Wednesday 5 12 19.26 Thursday 6 13 20 27 Friday 7 14 21 28 Saturday 1 8 15 22 29 Sunday 2 9 16 23 30
Рассмотренные примеры иллюстрируют подход, используемый в Perl для построения сложных структур данных. Читатель может сравнить возможности, предоставляемые языком Perl, с возможностями распространенных языков программирования, таких как Pascal или С. Любая сложная структура в Perl на "верхнем" уровне представляет собой массив или ассоциативный массив, в который вложены ссылки на массивы или хеш-массивы следующего уровня и т. д. В этой иерархии ссылки на массивы и хеш-массивы могут чередоваться в произвольном порядке. При помощи такого подхода средствами Perl можно представить любую структуру С или запись языка Pascal. Perl позволяет с легкостью создавать структуры, которые в других языках создать трудно или невозможно, например, структуру, эквивалентную массиву, состоящему из элементов разных типов:
@аггау = (1, 2.3, ("опе" › 1, "two" › 2}, \sfunc, 4, 5};
Читатель может поупражняться в построении таких структур и открыть для себя новые нюансы применения этого гибкого и мощного подхода.
В заключение несколько слов о фрагментах массивов. Для доступа к элементам массива мы имеем специальную нотацию, состоящую из префикса $, имени массива и индекса элемента в квадратных скобках, например, $аггау[7]. Если здесь вместо индекса поместить список индексов, а префикс $ заменить префиксом @, то такая запись будет обозначать фрагмент массива, состоящий из элементов с индексами из заданного списка. Подобную нотацию можно использовать в выражениях, например:
Ssubarrayl = @array[7..12]; @subarray2 = @array[3.5.7];
Массив @subarrayi является фрагментом массива garray, состоящим из элементов со значениями индекса от 7 до 12. Массив @subarray2 является фрагментом массива @аггау, состоящим из элементов со значениями индекса 3, 5 и 7. В первом случае список индексов задан при помощи операции "диапазон", во втором случае – перечислением.
Для многомерного массива понятие "фрагмент" обобщается и означает подмножество элементов, получающееся, если для некоторых индексов из диапазона их изменения выделить список допустимых значений. Для выделения одномерных фрагментов можно воспользоваться приведенной выше нотацией. Например, для выделения из массива @caiendar фрагмента, содержащего календарь на первую неделю апреля, можно использовать запись:
@april_first_week = @{'$calendar [3] } [0.. 6];
Если выделяемый фрагмент является многомерным, то для его обозначения специальной нотации не существует. В этом случае следует сформировать новый массив, являющийся фрагментом исходного массива. Например, для выделения из массива @caiendar календаря на первый квартал можно воспользоваться циклом:
for $i (0..2) {. for $j (0..$#{$calendar[$i]}) { $quarter.l[$i] [$j] = $ calendar [$i] [$j ]; } ' };