1

我有一个gem,它被一群人使用了一堆不同的 Ruby 解释器,它包括归结为这段代码的内容:

res = RestClient.post(...)
doc = REXML::Document.new(res).root

的内容res始终是 UTF-8,这在 Ruby 1.8 中运行良好,但如果响应不是纯 ASCII并且用户的默认编码不是 UTF-8,则在 Ruby 1.9 下它会爆炸。

现在,如果我想单独在 Ruby 1.9 上完成这项工作,我会坚持下去res.force_encoding('utf-8')并完成它,但该方法仅适用于 1.9,然后在 Ruby 1.8 下中断:

NoMethodError: undefined method `force_encoding' for #<String:0x101318178>

最好的解决方案是这样,它强制系统范围的默认编码为 UTF-8:

Encoding.default_external = 'UTF-8' if defined? Encoding

更好的想法,或者这是最好的?对尝试使用不同编码的图书馆用户会有负面影响吗?

4

4 回答 4

3
  if res.respond_to?(:force_encoding)
    new_contents = res.force_encoding("UTF-8")
  else
    new_contents = res
  end

为了向后兼容,我会做类似的事情。

于 2011-03-22T04:49:51.937 回答
2

我和 Mike Lewis 一起使用 using respond_to,但不要在代码中各处的变量 res 上执行此操作。

在 gateway.rb 中查看了您的代码,它看起来就像您在使用的任何地方一样res,它是通过调用设置的,make_api_request因此您可以在该方法中的 return 语句之前添加它:

doc = doc.force_encoding("UTF-8") if doc.respond_to?(:force_encoding) 

即使它是在其他地方,但并不是你遇到的每个字符串,我相信你可以找到一种方法来重构有意义的代码,并在一个地方而不是你遇到的任何地方解决问题。

你在其他地方有问题吗?

于 2011-03-31T00:13:45.453 回答
1

据我从代码片段中可以看出,问题的原因是RestClient,它没有以正确的编码(HTTP 响应中指定的编码)返回字符串,所以我首先尝试解决这个问题。如果无法做到这一点,那么您可以RestClient使用强制编码的代码包装调用(Mike Lewis 建议的方式)。RestClient或者您在通话以外的地方也遇到了问题?

于 2011-03-29T17:44:43.443 回答
0

#encoding: utf-8如果您在使用此方法的特定文件中包含标头,它是否有效。

Ruby 1.9 在整个应用程序中支持不同的编码,如果此内容是 utf-8 编码的,应该可以正常工作。

Ruby 1.8 会简单地忽略#encoding标题并继续正常工作。

这是一个非常简单的方法,但我相信它值得一试!

于 2011-03-29T04:19:44.670 回答