13

在我看来,ruby 1.9 附带的 YAML 库是编码聋的。

这意味着在生成 YAML 时,它将采用任何字节字符串,并转义任何不输出干净 ASCII 的字节序列。这很蹩脚,但可以接受。

我的问题是相反的。从所述 YAML 转储加载内容时。

在下面的示例中,我创建了一个 UTF-8 字符串,将其转储,它的转储类型为!binary. 当我重新加载它时,它的编码为 ASCII-8BIT。在示例的最后,我尝试将原始字符串和重新加载的字符串与另一个 UTF-8 字符串连接起来。后者将失败并显示Encoding::CompatibilityError.

require 'yaml'
s0 = "Iñtërnâtiônàlizætiøn"
y  = s0.to_yaml
s1 = YAML::load y
puts s0                 # => Iñtërnâtiônàlizætiøn
puts s0.encoding        # => UTF-8
puts s1                 # => Iñtërnâtiônàlizætiøn
puts s1.encoding        # => ASCII-8BIT
puts y                  # => --- !binary |
                        #    ScOxdMOrcm7DonRpw7Ruw6BsaXrDpnRpw7hu
puts "ñårƒ" + s0        # => ñårƒIñtërnâtiônàlizætiøn
puts "ñårƒ" + s1        # => Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT

我认为很清楚,当您处理一些包含嵌套散列和带有叶字符串的数组的 YAML 源时,这将如何迅速导致麻烦。

目前我有一些代码遍历所有哈希和数组并调用force_encoding每个字符串。至少可以说,这是难看的。

我现在正在寻找的是一种方法来告诉YAML::load任何传入的字符串都应该被视为,因此将其编码设置为 UTF-8。


理想情况下,ruby 的 YAML 应该只用正确的编码注释它转储的字符串。有一个 Ya2YAML 项目试图转储 UTF-8 安全 YAML。我不确定它有多远。如果有人玩过它,我欢迎任何想法。

无论如何,我仍然有这些转储,没有任何编码信息要处理。虽然我知道它们都是 UTF-8。

4

4 回答 4

3

考虑将您的 ruby​​ 升级到最新的 1.9.2 。

我在 1.9.1 但不是 1.9.2 中发现了该错误。

于 2011-04-18T09:39:46.643 回答
2
YAML::ENGINE.yamler='psych'
'Résumé'.to_yaml # => "--- Résumé\n...\n"
于 2012-01-27T17:35:09.300 回答
1

首先,您尝试读取的文本文件必须是 UTF-8 编码的(这应该是您的 YAML 文件)。

然后将此行添加到您的 ruby​​ 文件的顶部,哈希和所有

# encoding: UTF-8

这将意味着所有字符串的默认编码都是 UTF-8,并且应该意味着您使用 YAML.dump('text') 转储的任何文本甚至字符串文字“like this”也应该编码为 UTF-8,并且从现在开始,一切都应该很好。

于 2010-07-27T08:05:03.723 回答
0

Evgeny 的答案对我来说仍然显示二进制,但这有效('syck' instoad of 'psych'):

YAML::ENGINE.yamler='syck'
'Résumé'.to_yaml # => "--- "R\xE9sum\xE9"

我正在使用 Ruby 1.9。请注意,出于我的目的,对特价商品进行转义很好 - 我只需要它不显示 !binary... 对于普通单词。感谢上帝 .to_yaml 再次对我有用 - 曾经一直使用它。如何真正加载理智的生活:)

于 2013-03-16T22:28:16.620 回答