关于YAML语法和Ruby解析的澄清

关于YAML语法和Ruby解析的澄清,ruby,parsing,yaml,Ruby,Parsing,Yaml,我对亚姆和鲁比还不熟悉。我使用以下Ruby代码解析YAML文件: obj = YAML::load_file('test.yml') “test.yml”的以下YAML文件内容有效吗 案例1: test 在本例中,我没有指定test(类似于test:true)的值,但是我的Ruby解析代码不会抛出错误。我认为这是一个无效的YAML语法 案例2: :test : true 在本例中,Ruby代码将test视为符号而不是字符串,当我执行put obj[:test]时,它将结果返回为“true”

我对亚姆和鲁比还不熟悉。我使用以下Ruby代码解析YAML文件:

obj = YAML::load_file('test.yml')
“test.yml”的以下YAML文件内容有效吗

案例1:

test
在本例中,我没有指定
test
(类似于
test:true
)的值,但是我的Ruby解析代码不会抛出错误。我认为这是一个无效的YAML语法

案例2:

:test : true
在本例中,Ruby代码将
test
视为符号而不是字符串,当我执行
put obj[:test]
时,它将结果返回为“true”。这是红宝石的东西吗?其他语言将其解释为字符串
“:test”

案例3:

:test : true
:test : false

在这种情况下,我的Ruby代码不是为重新定义
:test
抛出错误,而是为
:test
获取最新的值(即
false
)。为什么会这样?YAML语法是否允许重新定义元素,在这种情况下,只获取最新的值?

情况1:YAML允许,或不包含在引号中的“裸”字符串。与带引号的字符串相比,它们不那么灵活,因为在不创建歧义语法的情况下无法使用某些字符,但Ruby解析器确实支持它们

1.9.3-p448 > YAML::parse('test').to_ruby
=> "test"
案例2:正如您所猜测的,这是特定于Ruby的,因为YAML没有“符号”的概念。将YAML转换为Ruby哈希时,以冒号开头的标量键将被解释为符号而不是字符串

案例3:在YAML对a的定义中,键必须是唯一的,因此在给出示例时,严格的解析器应该抛出错误。Ruby解析器似乎更为宽松,允许使用最后一个值规则多次定义同一个键。这在原生Ruby哈希中也是允许的

1.9.3-p448 > YAML::parse("test: true\ntest: false").to_ruby
=> {"test"=>false}
1.9.3-p448 > { 'test' => true, 'test' => false }
=> {"test"=>false}

了解YAML解析器如何与Ruby结构进行转换的一个好方法是编写输出YAML的Ruby代码,并了解它在做什么:

下面是一个基本哈希:

require 'yaml'
foo = {'test' => true} # => {"test"=>true}
foo.to_yaml # => "---\ntest: true\n"
使用符号作为键的哈希:

foo = {test: true}
foo.to_yaml # => "---\n:test: true\n"
具有冲突密钥的哈希,导致第一个密钥被最后一个密钥踩踏:

foo = {test: true, test: false}
foo # => {:test=>false}
foo.to_yaml # => "---\n:test: false\n"
YAML正在创建散列,但散列不能有重复的键;如果发生碰撞,则会导致第二个碰撞替换第一个碰撞


“这也是一个很好的资源。

感谢格兰托维奇抽出时间和回复。在案例1中,我看到内容被反序列化为字符串而不是散列。我的印象是YAML::load_文件总是返回一个散列。另外,不带引号的标量的用途是什么?在案例1中,我认为Ruby会有一个类似于无引号标量的“test”自动解析为true并放入散列。另外一个问题可能与本主题无关。我试图想出一个设计,在那里,我将有一个基本选项文件,其中有一些选项的值,并有覆盖文件,如果需要,将改变这些选项。本质上,我是在利用案例3中提到的Ruby解析器的非严格性。请让我知道它是否是一个好的设计?关于您的第一条评论,
YAML::load_file
只返回一个YAML文档的Ruby表示。YAML文档可以包含数组、哈希和字符串的任意组合——没有规则规定它必须是单个哈希。如果这对您来说是新的,那么Wikipedia的文章()提供了YAML文档如何工作的一个不错的概述。关于您的第二条评论,在这种情况下,您实际上不会利用Ruby解析器的不严格性。键只能在单个散列中是唯一的——因为“base”和“override”是完全独立的YAML文档,所以没有重复的键。谢谢Grantovich。关于你对第二条评论的回复,即使我包含了来自另一个YAML的YAML(不确定我是否可以这样做),它将是不同的散列?你会从阅读中受益。此外,我们还需要看到一个更好的例子,在原地解析YAML。