为什么两个间隔的YAML不像四边距YAML一样被解析?

时间:2018-05-30 00:26:28

标签: yaml ruby-2.5

在解析使用两个空格缩进创建的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并没有看到任何与此问题相关的内容。

预计会出现这种情况吗?如果是这样,我非常感谢资源链接解释原因。

2 个答案:

答案 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

正确解析预期结果。