为什么Ruby YAML有时在管道字符(|)后添加'2'?

时间:2018-07-02 15:58:50

标签: ruby yaml

在使用Ruby模块YAML时,遇到了一种我不了解的行为。

多行字符串的String#to_yaml有时会在竖线字符“ | 2”之后加上字符“ |”之后添加字符“ 2”。

尤其是在第一行为空时执行此操作。

关于为什么的任何线索?

这是一个例子:

C:\Users\Burdette>irb
irb(main):001:0> RUBY_VERSION
=> "2.2.6"
irb(main):002:0> require 'yaml'
=> true
irb(main):003:0> s = <<EOT
irb(main):004:0" 1
irb(main):005:0" 2
irb(main):006:0" 3
irb(main):007:0" EOT
=> "1\n2\n3\n"
irb(main):008:0> puts s.to_yaml
--- |
  1
  2
  3
=> nil
irb(main):009:0> s = "\n" + s
=> "\n1\n2\n3\n"
irb(main):010:0> puts s.to_yaml
--- |2

  1
  2
  3
=> nil
irb(main):011:0> exit

1 个答案:

答案 0 :(得分:6)

|表示文字标量。其后跟一个Block Scalar Header,它可以指示文字的缩进级别以及是否被“砍掉”。排行是是否删除最后的换行符。例如,当我们删除最后一个换行符时...

2.4.3 :059 > puts "\n1\n2\n3".to_yaml
--- |2-

  1
  2
  3
 => nil 

... YAML添加了-来表示最后的换行符已删除。

类似地,2表示从每行中删除前两个空格。这样可以保留原始字符串中的前导换行符。

2.4.3 :061 > puts "\n  1\n2\n3".to_yaml
--- |2-

    1
  2
  3
 => nil 

通常缩进级别为空,因此您只看到|,并且缩进值是从第一行非空行推断出来的。在此示例中,推断出2。

2.4.3 :062 > puts "1\n2\n3".to_yaml
--- |-
  1
  2
  3
 => nil 

但是,如果第一行包含歧义,则必须明确。这是有关该规范的完整文档。

  

8.1.1.1. Block Indentation Indicator

     

通常,从其第一条非空行检测块标量的缩进级别。任何前导空行都包含比第一个非空行更多的空格是错误的。

     

当第一行非空行包含前导内容空间字符时,检测失败。内容可以安全地以制表符或“#”字符开头。

     

当检测失败时,YAML要求使用显式缩进指示符来指定内容的缩进级别。相对于其父节点,此级别被指定为用于内容的附加缩进空间的整数。

     

为块标量节点指定缩进指示符始终是有效的,尽管YAML处理器仅应在检测失败的情况下发出显式缩进指示符。

在您的情况下,无论是否使用显式指示符,YAML往返都很好。它可以从第一条非空行获得缩进。我以为特定的YAML实现是保守的,并且在第一行为空白时使缩进明确。

有许多方法可以在YAML中表达相同的内容。例如,添加额外的前导空格,然后Ruby切换到引号。

2.4.3 :055 > puts " \n1\n2\n3\n".to_yaml
--- " \n1\n2\n3\n"
 => nil 

为什么不呢?

--- |2-

  1
  2
  3

可能是因为它不易阅读,并且在准备好人类后很容易错过额外的空间,因此YAML既适用于人类,也适用于机器。要真正知道,您必须在开发过程中阅读YAML库的代码以及可能的在线讨论。我猜想,当存在歧义或混淆更安全的可能性时,决定将其明确。