Как я могу использовать дерево YAML с помощью Perl YAML:: Tiny?

У меня есть документ YAML:

---
version: 1
rootdirectory:
  - subdirectory:
    - file1
    - file2
  - subdirectory2

что я загружаю объект YAML:: Tiny следующим образом:

$configuration = YAML::Tiny->read($configuration_file)

Я вижу из вызова script с отладчиком Perl то, что я получаю, это набор вложенных хэшей и массивов, которые отражают структуру источника YAML:

0  YAML::Tiny=ARRAY(0x84e3ba4)
   0  HASH(0x80627dc)
      'rootdirectory' => ARRAY(0x84e3d3c)
         0  HASH(0x84352b0)
            'subdirectory' => ARRAY(0x84e3df0)
               0  'file1'
               1  'file2'
         1  'subdirectory2'
      'version' => 1

Итак, я могу без проблем выполнить следующие действия:

print $configuration->[0]->{version}

и получите ожидаемый ответ "1". Аналогично, я также могу:

print $configuration->[0]->{rootdirectory}->[0]->{subdirectory}->[0]

и получите ожидаемый ответ "file1".

Моя проблема связана со всеми априорными знаниями, которые мне нужно получить в моем примере. Поскольку я пытаюсь разрешить пользователям моего script описывать произвольную структуру каталогов в конфигурации YAML, это недостаточно. Мне нужно иметь возможность "ходить" по дереву из "rootdirectory".

Итак, я бы предположил, что мог бы сделать что-то вроде этого:

print keys($configuration->[0])

который я бы ожидал вернуть "rootdirectory, version"... и т.д., итерации по массивам и хэшам, пока я не ходил по дереву.

Когда я пытаюсь запустить приведенный выше пример, я получаю:

Type of arg 1 to keys must be hash (not array element)

В этот момент я застрял. Насколько я понимаю, $configuration → [0], будучи элементом массива, является элементом, содержащим хеш, который, я считаю, должен иметь возможность вызвать функцию keys.

Что мне здесь не хватает?

+5
источник поделиться
2 ответа

Попробуйте

print "$_\n" for keys %{ $configuration->[0] };

Вам нужно принудительно ввести элемент массива "$configuration->[0]" в хэш-ref с помощью "%{...}"

Итак, чтобы перебрать их:

for my $key ( keys %{ $configuration->[0] } ){
  my $value = $configuration->[0]{$key};

  print "$key => $value\n";
}
+5
источник

YAML::Tiny создает довольно сложную структуру данных:

ссылка на массив  полный ссылок на хэши      полный ссылок на массивы          полный ссылок на хэши               ....

когда $a является ссылкой на массив, вы получаете доступ ко всему массиву как @$a и элементы как $$a[0], $$a[1],... или, альтернативно, как $a->[0], $a->[1]

когда $b является ссылкой на хэш, вы получаете доступ к всему хэшу как %$b и элементы при $$b{'somekey'}, $$b{'somekey'},.... или, альтернативно, как $b->{'somekey'}, $b->{'somekey'}

когда $configuration является ссылкой на массив, полный ссылок на хэши вы получаете доступ к всему массиву как @$configuration, первый элемент как $configuration->[0]. Вы можете просто скопировать это в другую переменную

$firstconfig = $configuration->[0]

а затем получить доступ ко всему хешу как

%$firstconfig

но если вы хотите сделать это за один раз, вам нужно написать довольно сложную

%{ $configuration->[0] }

Я думаю, что это одна из вещей, которые были удалены для Perl 6.

+3
источник

Посмотрите другие вопросы по меткам или Задайте вопрос