Срезы хешей

В полной аналогии со срезами массивов часть элементов хеша тоже может быть выделена в срез хеша. Помните пример с хранением результатов игры в боулинг в хеше %score? Мы можем извлечь эти результаты как в список элементов хеша, так и в срез. Эти два приема эквивалентны (хотя второй работает эффективнее и занимает меньше места):

my @three_scores = ($score{"barney"}, $score{"fred"}, $score{"dino"});
my @three_scores = @score{ qw/ barney fred dino/ };

Срез всегда является списком, и в записи среза хеша это обстоятельство указывается знаком @. Когда вы встречаете в программе Perl конструкцию вида @score{ ... }, сделайте то, что делает Perl, и обратите внимание на знак @ в начале и фигурные скобки в конце. Фигурные скобки означают, что происходит выборка из хеша, а знак @ – что вы получаете список элементов вместо одного (на которое бы указывал знак $). Как и в случае со срезами массивов, знак перед ссылкой на переменную ($ или @) определяет контекст индексного выражения. С префиксом $ выражение вычисляется в скалярном контексте для получения отдельного ключа. Но если в начале стоит знак @, индексное выражение вычисляется в списочном контексте для получения списка ключей.

Возникает логичный вопрос: раз мы говорим о хешах, почему здесь не используется знак %? Этот знак обозначает весь хеш; срез хеша (как и любой другой срез) всегда представляет собой список, а не хеш.


В Perl символ $ всегда обозначает отдельный объект данных, символ @ обозначает список, а символ % обозначает весь хеш. Как вы видели со срезами массивов, срезы хешей могут использоваться вместо соответствующего списка элементов хеша во всех синтаксических конструкциях Perl. Таким образом, мы можем задать результаты некоторых партий в хеше (без изменения других элементов хеша) следующим образом:

my @players = qw/ barney fred dino /;
my @bowling_scores = (195, 205, 30);
@score{ @players } = @bowling_scores;

Последняя строка работает точно так же, как если бы мы выполнили присваивание списку из трех элементов:

($score{"barney"}, $score{"fred"}, $score{"dino"}).

Срезы хешей тоже могут интерполироваться. В следующем примере выводятся результаты для выбранной нами тройки игроков:

print "Tonight's players were: @players\n";
print "Their scores were: @score{@players}\n";

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Perl на эту тему:
Отбор элементов списка
Перехват ошибок в блоках eval
Преобразование элементов списка
Срезы
Срезы массивов

Вернуться в раздел: Perl / 16. Расширенные возможности Perl