Что это значит, когда метод Perl возвращает hashref? - PullRequest
8 голосов
/ 15 мая 2010

Я пытаюсь расшифровать код Perl, с которым я не знаком, как-то связанный с HashRef. Я использую Amazon :: S3, но мой вопрос является общим вопросом Perl. Смотрите код ниже:

use Amazon::S3;
my $s3 = Amazon::S3->new( ... );
my $response = $s3->buckets;

Документация (здесь) о s3-> ведрах:

Returns undef on error, else HASHREF of results

Следующая строка работает для меня, но я не понимаю, почему:

for $b in ( @ { $response->{buckets} } ) {
    print "bucket: " . $b->bucket . "\n";
}

Я озадачен каждым оператором в первой строке.

Какого типа $response, $respone->{bucket}. Похоже, что выражение в for является массивом, но я не понимаю этот синтаксис: @{ ... }?

Ответы [ 3 ]

10 голосов
/ 15 мая 2010

Давайте рассмотрим его по частям.

$s3 - это ваш объект S3.$s3->buckets вызывает метод buckets для этого объекта, и мы сохраняем результаты в $response.Как говорят в документах, результаты являются хэш-ссылкой;ссылка - это скаляр, который указывает на другое значение.Если вы знакомы с указателями, идея та же самая.

Если бы у нас был простой хэш %response, мы могли бы получить ключ buckets в хэше, сказав $response{buckets}.Поскольку у нас есть хэш ссылка , нам нужно использовать оператор разыменования (->), чтобы получить ключ, чтобы он стал $response->{buckets}.

Но мы еще не закончилиеще.$response->{buckets} сама по себе ссылка, в данном случае ссылка на массив.Здесь мы видим другую форму разыменования.Мы могли бы, если бы мы хотели получить только один элемент в указанном массиве, скажем, например, $response->{buckets}[0].Но нам нужен весь список, поэтому мы используем оператор @ для разыменования всего массива.Так как наша ссылка на массив содержится в сложной структуре, мы используем curlies, чтобы содержать выражение, которое имеет ссылку.Так что @{ $response->{buckets} } получает нам массив.

Это делает многое в одном выражении.

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

  • perlreftut - Учебное пособие по Perl
  • perldsc - Поваренная книга структур данных Perl
  • perllol - Все о массивах массивов
  • perlref - Theглавная справочная документация по Perl
4 голосов
/ 15 мая 2010

Добро пожаловать в мир ссылок Perl! Вы найдете справочное руководство очень удобным.

Синтаксис @{...} принимает скалярное значение и пытается отменить ссылку на него в массив. Также есть %{...}, который пытается разыменовать хеш. Завитки являются необязательными, поэтому вы также можете написать @$reference или %$reference, чтобы получить тот же эффект. Некоторые люди считают их визуально полезными, когда ссылка находится внутри хеша или массива, как в данном случае.

Чтобы помочь вам немного лучше понять структуру данных, попробуйте использовать что-то вроде Data :: Dumper.

use Data::Dumper;
print Dumper $response;
print Dumper $response->{buckets};
# The docs say that buckets is a hashref.  It also happens that
# you can coerce a hash into an array.  Let's treat it as a hash
# and see what's inside it, manually.  The Dumper call above should
# have already provided the structure to you, though.
foreach my $k (keys %{$response->{buckets}}) {
    print "$k => " . Dumper $response->{buckets}->{$k}
}
0 голосов
/ 15 мая 2010

Вы можете проверить тип переменной с помощью функции ref ().

@ {...} означает «разыменовать скаляр ... как массив». Поэтому, если вы пойдете так: my $ aref = ['a', 'b']; доступ к @ {$ aref} приведет к массиву ('a', 'b').

Аналогично% {...} для хеш-ссылок.

См. Perlreftut для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...