奇怪的红宝石to_yaml行为

时间:2012-01-04 11:09:45

标签: ruby yaml

我遇到了to_yaml行为不同的奇怪问题。为:

"0111".to_yaml

它返回:

"--- \"0111\"\n"

与此同时:

"0128".to_yaml

返回:

"--- 0128\n"

正如您所看到的,第一个输出有""但第二个输出没有。

有什么想法吗?

环境:MRI Ruby 1.9.2和JRuby 1.6.5(1.9模式)。

2 个答案:

答案 0 :(得分:4)

我相信Eugene对于这些问题的原因是正确的 - 似乎解析器对包含有效八进制数的字符串进行不同的处理。

如果你不喜欢它,你可以切换到另一个YAML解析器。根据{{​​3}},有两种解析器可用:SyckPsych。前者是旧的,没有维护,后者是它的替代品。

Psych用于最新版本的Rails,是1.9.3中的默认YAML引擎。但是你可以在1.9.2中轻松使用它并看到差异:

require 'yaml'

p YAML::ENGINE.yamler      # => "syck"
# or explicitly set YAML::ENGINE.yamler = "syck" in 1.9.3
p '01'.to_yaml             # => "--- \"01\"\n"
p '08'.to_yaml             # => "--- 08\n"
p YAML.load('01'.to_yaml)  # => "01"
p YAML.load('08'.to_yaml)  # => "08"

p YAML::ENGINE.yamler = "psych"
p '01'.to_yaml             # => "--- '01'\n"
p '08'.to_yaml             # => "--- '08'\n"
p YAML.load('01'.to_yaml)  # => "01"
p YAML.load('08'.to_yaml)  # => "08"

正如您所看到的,只要您使用相同的引擎来解码数据,就不必担心Syck中字符串的不同表示(在两种情况下都会返回原始字符串)。

如果由于某种原因你需要在YAML中对字符串进行统一表示,你可以切换到Psych(至少在这种情况下它更加一致),但要小心,因为你可能会遇到麻烦试图加载{{ 1}}以前使用Psych转储的数据。

答案 1 :(得分:0)

我也可以复制这个。我不确定是做什么的,但我的第一个猜测是它与字符串中的“数字”实际上是八进制数字。或者更准确地说,第一个是八进制,第二个不是。如果删除0,则会从第一个中获取行为。也许其他人可以详细说明这个理论。

1.9.2p290 :002 > "0111".to_yaml
  => "--- \"0111\"\n" 
1.9.2p290 :003 > "0128".to_yaml
  => "--- 0128\n" 
1.9.2p290 :004 > "\0111".to_yaml
  => "--- \"\\t1\"\n" 
1.9.2p290 :005 > "\0128".to_yaml
  => "--- \"\\n\\\n8\"\n" 
1.9.2p290 :006 > string = "0111"
  => "0111" 
1.9.2p290 :007 > string.class
 => String 
1.9.2p290 :008 > string.to_yaml
 => "--- \"0111\"\n" 
1.9.2p290 :009 > string = "111"
 => "111" 
1.9.2p290 :010 > string.to_yaml
 => "--- \"111\"\n" 
1.9.2p290 :011 > string = "128"
 => "128" 
1.9.2p290 :012 > string.to_yaml
 => "--- \"128\"\n"