Копаться в большую структуру довольно просто, если вы знаете правила:
- Обернуть ключи хеша в
{}
- Обернуть индексы массива в
[]
- Если ваша переменная верхнего уровня является справочной, используйте
->
перед первым идентификатором. - После первого набора скобок или скобок дополнительные стрелки (
->
) являются необязательными.
Итак: * $data->{person}{name}
возвращает 'Joe Smith'
* $data->{person}->{name}
также возвращает 'Joe Smith'
* $data->{pets}{cats}[0]{age}
возвращает 6
.
Более подробную информацию по этой теме см. В Perl Data Structures Cookbook (perldoc perldsc)
Когда вы работаете с такими большими структурами, есть некоторые важные вещи, о которых следует помнить.Самый большой из них - autovivification
.Autoviv означает, что Perl автоматически создаст для вас элементы структуры данных, чтобы сделать вашу жизнь проще.К сожалению, это также может усложнить задачу.
Например, autoviv великолепен, когда я делаю это:
my $data;
$data->{horse}[0]{color} = 'brown';
Autoviv волшебным образом превращает $data
в хеш-код, содержащий ключ horse
с массивом ref в качестве значения.Ссылка на массив заполняется ссылкой на хэш.Окончательный хэш ref получает пару ключ-значение color => brown
.
Проблема возникает, когда вы идете по структуре и делаете глубокие тесты на существование:
# Code from above continues:
if( exists $data->{cat}[5]{color} ) {
print "Cat 5 has a color\n";
}
use Data::Dumper;
print Dumper $data;
Здесь, автовивификациясжигает вас, создавая кучу мусора в данных, вот вывод программы:
$ VAR1 = {'cat' => [undef, undef, undef, undef, undef, {}], 'horse' => [{'color' => 'brown'}]};
Теперь вы можете защититься от подобных вещей, тщательно проверяя каждый слой вашей структуры на предмет существования, но это огромная боль в заднице.Вместо этого я предпочитаю использовать Data :: Diver .
use Data::Diver qw( Dive );
my $dog_20_color = Dive( $data, 'dog', 20, 'color' );
print "Dog 20 is $dog_20_color\n" if defined $dog_20_color;
$data
без изменений здесь.
Кроме того, вы, возможно, заметили, что с Dive
берет список ключей или индексов, это означает, что его легко программно составить список ключей / индексов и спуститься по произвольному пути в вашем коде.
Data :: Diver может быть реальным спасателем, когда у вас естьделать много манипуляций с большими, вялыми структурами данных.