【问题标题】:How can I walk a YAML tree with Perl's YAML::Tiny?如何使用 Perl 的 YAML::Tiny 遍历 YAML 树?
【发布时间】:2010-11-19 00:44:24
【问题描述】:

我有一个这样的 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 函数。

我在这里错过了什么?

【问题讨论】:

    标签: perl yaml


    【解决方案1】:

    试试

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

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

    所以要遍历它们:

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

    【讨论】:

    • 太好了,谢谢!据我了解,我基本上需要一些 %{$configuration->[0]} 形式的“语法糖”来强制 Perl 相信 $configuration->[0] 实际上是一个散列而不是发生的数组元素包含一个哈希。这是一个公平的评论吗?
    • 关键字keys() 的定义类似于keys(\%){...},它强制您使用哈希,但不会为您自动取消引用。
    • 优秀。再次感谢您的帮助。
    • 在 Perl 5.14 中,您不必取消引用 %{...}
    【解决方案2】:

    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 中删除的内容之一。

    【讨论】:

    • 其中一些已经改变了,但其中一些仍然存在于 Perl6 中。
    • YAML::Tiny 只是重建了序列化的数据结构。复杂性的根源在于正在解析的 YAML 文档。
    • 这对我帮助很大。我一直在阅读 perlreftut 和 perldsc 并且一直被哈希和数组引用所困扰,并且看不到真实数据。我仍然不完全理解,但至少我可以从答案中获得启发。
    猜你喜欢
    • 1970-01-01
    • 2019-08-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 2013-07-14
    相关资源
    最近更新 更多