4

我是 YAML 和 Ruby 的新手。我正在使用以下 Ruby 代码来解析 YAML 文件:

obj = YAML::load_file('test.yml')

'test.yml' 的以下 YAML 文件内容是否有效?

情况1:

test

在这种情况下,我没有指定test(类似test : true)的值,但我的 Ruby 解析代码不会引发错误。我认为这是无效的 YAML 语法。

案例二:

:test : true

在这种情况下,Ruby 代码将test其视为符号而不是字符串,当我这样做时puts obj[:test],它返回的结果为“true”。这是Ruby的东西吗?其他语言会将其解释为字符串":test"

案例3:

:test : true
:test : false

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

4

2 回答 2

4

案例 1: YAML 允许不带引号的标量,或不包含在引号中的“裸”字符串。与带引号的字符串相比,它们的灵活性较低,因为您不能在不创建模棱两可的语法的情况下使用某些字符,但 Ruby 解析器确实支持它们。

1.9.3-p448 > YAML::parse('test').to_ruby
=> "test"

案例 2:正如您所猜测的,这是特定于 Ruby 的,因为 YAML 没有“符号”的概念。将 YAML映射转换为 Ruby 哈希时,以冒号开头的标量键被解释为符号而不是字符串。

案例 3:在 YAML 的映射定义下,键必须是唯一的,因此在给出示例时,严格的解析器应该会抛出错误。似乎 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}
于 2013-08-22T17:02:12.577 回答
2

了解 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 正在创建哈希,但哈希不能有重复的键;如果他们这样做了,碰撞会导致第二个替换第一个。

YamlForRuby 站点上的 Yaml Cookbook ”也是一个很好的资源。

于 2013-08-22T19:01:55.690 回答