在使用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
答案 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库的代码以及可能的在线讨论。我猜想,当存在歧义或混淆更安全的可能性时,决定将其明确。