【问题标题】:Strange ruby to_yaml behavior奇怪的 ruby​​ to_yaml 行为
【发布时间】:2012-01-04 11:09:44
【问题描述】:

我遇到了to_yaml 行为差异的奇怪问题。对于:

"0111".to_yaml

它返回:

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

同时这个:

"0128".to_yaml

返回:

"--- 0128\n"

如您所见,第一个输出有 "",但第二个没有。

有什么想法吗?

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

【问题讨论】:

    标签: ruby yaml


    【解决方案1】:

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

    如果您不喜欢它,您可以切换到不同的 YAML 解析器。根据docs,有两个可用的解析器: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(至少在这种情况下更一致),但要小心,因为您可能会在尝试加载 Psych 数据时遇到麻烦之前用Syck 转储的。

    【讨论】:

    • 不知道 YAML 解析器在 1.9.3 中已更改,很高兴知道。感谢您的提示!
    • 我在 OS X 上运行 ruby 1.9.3p194(通过 RVM 安装),即使 YAML::ENGINE.yamler 报告 "psych"仍然使用 '08' 得到上述行为和'09'
    • 我也是。在 1.9.3 中使用 psych 我得到与在 1.9.2 中使用 syck 相同的行为。我想原因是在 1.9.2 中我有 psych 版本 1.0.0 而在 1.9.3 中它是 1.3.2。他们很可能在最新版本中改变了行为。
    【解决方案2】:

    我也可以复制这个。我不确定它在做什么,但我的第一个猜测是它与字符串中的“数字”实际上是八进制数有关。或者更准确地说,第一个是八进制,第二个不是。如果您删除 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"
    

    【讨论】:

    • 我只是觉得这种行为很奇怪。我测试了其他 yaml 实现,例如 js-yaml。似乎他们以正确的方式处理这个......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-25
    • 2019-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多