6

我有一个这样的 YAML 文档:

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

我正在像这样加载到 YAML::Tiny 对象中:

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

我从使用 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”的预期答案。

我的问题来自于在上面的示例中派生我的文件名所需的所有先验知识。当我试图允许我的脚本用户在 YAML 配置中描述任意目录结构时,这还不够好。我需要能够从“根目录”“走”树。

所以,我会想象我可以做这样的事情:

print keys($configuration->[0])

我本来希望返回 'rootdirectory,version' ......等等,遍历数组和哈希,直到我走过树。

当我尝试运行上面的示例时,我得到:

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

在这一点上,我被困住了。据我了解,$configuration->[0] 虽然是数组的一个元素,但它是一个包含哈希的元素,我相信我应该能够针对它调用 keys 函数。

我在这里想念什么?

4

2 回答 2

6

尝试

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

您必须将数组元素“”强制为$configuration->[0]带有“ %{...}”的哈希引用

所以要遍历它们:

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

  print "$key => $value\n";
}
于 2009-08-12T16:38:23.953 回答
3

YAML::Tiny创建一个相当复杂的数据结构:

对一个充满了对哈希的引用的数组的引用 对充满对哈希的引用的数组的引用 ....

when$a是对数组的引用,您可以将整个数组作为 @$a 访问,将元素访问为$$a[0], $$a[1],... 或者作为$a->[0], $a->[1]

什么时候$b是一个哈希的引用,你访问整个哈希作为%$b 和元素作为 $ $b{'somekey'}, $$b{'somekey'},.... 或者作为$b->{'somekey'}, $b->{'somekey'}

when$configuration是对一个数组的引用,其中包含对哈希的引用,您将整个数组访问为@$configuration,第一个元素为$configuration->[0]。您可以将其复制到另一个变量

$firstconfig = $configuration->[0]

然后访问整个哈希

%$firstconfig

但是如果你想一口气完成,你必须编写相当棘手的

%{ $configuration->[0] }

我认为这是 Perl 6 中删除的内容之一。

于 2009-08-12T16:56:31.917 回答