2010-05-15 2 views
8

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

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 - это массив, но я не понимаю этот синтаксис: @{ ... }?

ответ

10

Давайте пройдем через него по частям.

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

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

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

Это делает много в одном заявлении.

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

  • perlreftut - Perl ссылки учебник
  • perldsc - структуры данных Perl поваренная книга
  • perllol - Все о массивах массивов
  • perlref - Основная документация по документации Perl
+0

Большое спасибо. Очень полезно. – Uri

+0

perlreftut perlreftut perlreftut :) – hobbs

-1

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

@ {...} означает «de-reference scalar ... as array». Поэтому, если вы так: my $ aref = ['a', 'b']; доступ к @ {$ isf} даст массив ('a', 'b').

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

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

4

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

Синтаксис @{...} принимает скалярное значение и пытается отменить его в массиве. Также есть %{...}, который пытается удалить ссылку в хэш. Колонки не являются обязательными, поэтому вы также можете написать @$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} 
} 
Смежные вопросы