在解析使用两个空格缩进创建的YAML(使用Ruby 2.5 / Psych)时,我看到了奇怪的行为。同样的文件,每行缩进四个空格 - 在我看来 - 正如预期的那样。
两个空格:
windows:
- shell:
panes:
- echo hello
导致以下哈希:
{"windows"=>[{"shell"=>nil, "panes"=>["echo hello"]}]}
使用四个空格缩进:
windows:
- shell:
panes:
- echo hello
结果:
{"windows"=>[{"shell"=>{"panes"=>["echo hello"]}}]}
我只是浏览了the spec并没有看到任何与此问题相关的内容。
预计会出现这种情况吗?如果是这样,我非常感谢资源链接解释原因。
答案 0 :(得分:5)
虽然Wayne的解决方案是正确的,但解释似乎有些偏差,所以我会投入我的:
在YAML中,块序列项的-
(如块映射的?
和:
)被视为缩进(spec ):
用于表示块集合条目的“ - ”,“?”和“:”字符被人们认为是缩进的一部分。这是由相关作品逐案处理的。
此外,所有块集合(序列和映射)都从它们的第一个项目中缩进(因为没有明确的起始指示符)。因此,在- shell:
行中,-
定义了新启动的序列的缩进级别,同时shell:
定义了新启动的映射的缩进级别,即序列项的内容。请注意-
如何被视为缩进以定义映射的缩进级别。
现在,重新审视你的第一个例子:
windows:
- shell:
panes:
- echo hello
panes:
与shell:
处于同一级别。这意味着YAML将其解析为shell:
开始的映射的 key ,这意味着键shell
具有空值。映射隐式键的值(如果不在同一行上)必须始终缩进多于相应的映射键(spec):
块节点的属性可能跨越多行。在这种情况下,它们必须缩进至少比块集合多一个空格,而不管块集合条目的缩进。
OTOH,在第二个例子中:
windows:
- shell:
panes:
- echo hello
与panes:
相比, shell:
处于更深的缩进级别。这意味着它被解析为键shell
的 value ,从而启动一个新的嵌套块映射。
最后,请注意,由于-
被视为缩进的一部分,“缩进两个空格”也可能意味着:
windows:
- shell:
panes:
- echo hello
注意-
如何缩进而不是映射键。这是有效的,因为spec说:
由于人们将“ - ”指示符视为缩进,嵌套的块序列可以缩进一个较少的空间来补偿,当然,除非嵌套在另一个块序列中(阻挡上下文与块上下文相关)
答案 1 :(得分:2)
麻烦的是你不能简单地用四个空格替换每两个空格。那是因为在这对线中:
- shell:
panes:
第二行中的这两个空格:
panes:
^^
" - "的缩写?在上面的行。如果第二行没有缩写,那么这对行将是:
- shell:
- panes:
因此,当缩进加倍时,这些行中的第二行应仅使其第一对空格加倍,而不是第二对。这将为该对产生正确的缩进:
- shell:
panes:
所以,如果你只展开"窗格中的第一对空格:"你知道:
windows:
- shell:
panes:
- git status
正确解析预期结果。