代码之家  ›  专栏  ›  技术社区  ›  pdoherty926

为什么不把两个间隔的yaml解析成四个间隔的yaml?

  •  3
  • pdoherty926  · 技术社区  · 8 年前

    在解析使用两个空格缩进创建的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 回复  |  直到 8 年前
        1
  •  2
  •   David Birks Zane Bien    7 年前

    问题是你不能简单地用四个空格替换每两个空格。这是因为在这对线中:

      - shell:
        panes:
    

    第二行的这两个空格:

        panes:
      ^^
    

    是上面行中“-”的缩写。如果第二行没有缩写,那么这两行将是:

      - shell:
      - panes:
    

    所以当缩进加倍时,第二行应该只有第一对空格加倍,而不是第二对。这将产生对的正确缩进:

        - shell:
          panes:
    

    因此,如果只展开“panes:”行中的第一对空格,则会得到:

    windows:
        - shell:
          panes:
              - git status
    

    正确解析为预期结果。

        2
  •  7
  •   flyx    8 年前

    虽然韦恩的解决方案是正确的,但解释似乎有点离题,所以我要把我的解释加进去:

    在Yaml中, - 对于块序列项(如 ? : 对于块映射)处理 作为缩进 ( spec ):

    是不是?_157;和_156;:_157;用于表示块集合条目的字符被人们视为缩进的一部分。这是由相关生产部门逐案处理的。

    此外,所有块集合(序列和映射)都从其第一个项获取缩进(因为没有显式的起始指示符)。所以在排队 - shell: , the - 定义新启动序列的缩进级别,同时, shell: - 被视为用于定义映射的缩进级别的缩进。

    现在,回顾您的第一个示例:

    windows:
      - shell:
        panes:
          - echo hello
    

    panes: 与处于同一级别 壳牌: . 这意味着yaml将其解析为 钥匙 由开始的映射 壳牌: ,也就是说 shell 具有空值。隐式键的映射值(如果不在同一行上)必须始终缩进大于对应的映射键( spec ):

    块节点的属性可以跨越几行。在这种情况下,不管块集合项的缩进如何,它们都必须至少比块集合缩进一个空间。

    Otoh,在第二个示例中:

    windows:
        - shell:
            panes:
                - echo hello
    

    窗格: 壳牌: . 这意味着它被解析为 价值 钥匙的

    最后,记住从 - 作为压痕的一部分处理, “缩进两个空格” 也可能意味着:

    windows:
    - shell:
        panes:
        - echo hello
    

    注意如何 - spec 说:

    由于人们将“指示器”视为缩进,因此嵌套的块序列可以缩进一个较小的空间来补偿,当然,如果嵌套在另一个块序列中(块出上下文vs.块入上下文),则除外。

    推荐文章