如何使用 Perl 的 YAML::Tiny 遍历 YAML 树?
我有一个像这样的 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] 虽然是数组的一个元素,但它是一个包含哈希的元素,我相信我应该能够调用其键函数。
我在这里缺少什么?
I have a YAML document like this:
---
version: 1
rootdirectory:
- subdirectory:
- file1
- file2
- subdirectory2
that I am loading into a YAML::Tiny object like this:
$configuration = YAML::Tiny->read($configuration_file)
I see from invoking the script with the Perl debugger that what I end up with is a set of nested hashes and arrays that reflect the structure of the YAML source:
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
So, I can do things like the following without problem:
print $configuration->[0]->{version}
and receive the expected answer of '1'. Likewise, I can also do:
print $configuration->[0]->{rootdirectory}->[0]->{subdirectory}->[0]
and receive the expected answer of 'file1'.
My problem comes from all of the a priori knowledge I need to derive my filename in the above example. As I am trying to allow the users of my script to describe an arbitrary directory structure in the YAML configuration this isn't good enough. I need to be able to "walk" the tree from 'rootdirectory'.
So, I would have imagined I could have done something like this:
print keys($configuration->[0])
which I would have expected to have returned 'rootdirectory,version' ... and so on, iterating over the arrays and hashes until I had walked the tree.
When I attempt to run the above example, I get:
Type of arg 1 to keys must be hash (not array element)
At this point I am stuck. As I understand it, $configuration->[0], whilst being an element of an array, is an element containing a hash that I believe I should be able to invoke the keys function against.
What am I missing here?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试
您必须将数组元素“
$configuration->[0]
”强制转换为带有“%{...}
”的哈希引用,以便迭代它们:
Try
You have to force the array element "
$configuration->[0]
" into a hash ref with "%{...}
"So to iterate over them:
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]
。 您可以将其复制到另一个变量,然后访问整个散列,
但如果您想一次性完成它,则必须编写相当棘手的内容,
我认为这是 Perl 6 中已删除的内容之一。
YAML::Tiny
creates a rather complex data structure:a reference to an array
full of references to hashes
full of references to arrays
full of references to hashes
....
when
$a
is a reference to an array,you access the whole array as @$a
and the elements as
$$a[0], $$a[1],
...or alternatively as
$a->[0], $a->[1]
when
$b
is a referenc to a hash,you access the whole hash as
%$b
and the elements as $
$b{'somekey'}, $$b{'somekey'},
....or alternatively as
$b->{'somekey'}, $b->{'somekey'}
when
$configuration
is a reference to an array full of references to hashesyou access the whole array as
@$configuration
,the first element as
$configuration->[0]
. You could just copy that to another variableand then access the whole hash as
but if you want to do it in one go you have to write the rather tricky
I think this is one of the things that has been removed for Perl 6.