我有一个gem,它使用了许多使用一堆不同Ruby解释器的人,它包含了归结为此代码的内容:
res = RestClient.post(...)
doc = REXML::Document.new(res).root
res
的内容总是UTF-8,这在Ruby 1.8中运行良好,但如果响应不是纯ASCII 并且是用户的默认值,它会在Ruby 1.9下爆炸编码不是UTF-8。
现在,如果我想单独使用Ruby 1.9,我只需将res.force_encoding('utf-8')
放在那里并完成它,但该方法只有1.9,然后在Ruby 1.8下打破:< / p>
NoMethodError: undefined method `force_encoding' for #<String:0x101318178>
最好的解决方案是,这会强制系统范围的默认编码为UTF-8:
Encoding.default_external = 'UTF-8' if defined? Encoding
更好的想法,还是这样的好事?是否会对试图使用不同编码的图书馆用户产生负面影响?
答案 0 :(得分:3)
if res.respond_to?(:force_encoding)
new_contents = res.force_encoding("UTF-8")
else
new_contents = res
end
为了向后兼容,我会做类似的事情。
答案 1 :(得分:2)
我和迈克·刘易斯一起使用respond_to
,但是不要在整个代码中的变量res上执行此操作。
我看了your code in gateway.rb,看起来就像你使用res
的所有地方一样,它是通过调用make_api_request
设置的,所以你可以在你的return语句之前添加它方法:
doc = doc.force_encoding("UTF-8") if doc.respond_to?(:force_encoding)
即使它是其他地方,但它并不是你遇到的每一个字符串的字面意思,我相信你可以找到一种方法来重构有意义的代码并在一个地方而不是你遇到的任何地方解决问题。
你有其他地方的问题吗?
答案 2 :(得分:1)
就我从代码片段中看到的那样,问题的原因是RestClient
,它没有以正确的编码(在HTTP响应中指定的那个)返回字符串,所以我首先尝试解决这个问题。如果无法做到这一点,那么你可以使用强制编码的代码来封装RestClient
调用(Mike Lewis建议的方式)。或者您在RestClient
来电以外的地方遇到问题?
答案 3 :(得分:0)
如果在此特定文件中包含#encoding: utf-8
标头,则使用此方法是否有效。
Ruby 1.9支持整个应用程序中的不同编码,如果此内容是utf-8编码,则应该可以正常工作。
Ruby 1.8只会忽略#encoding
标题并继续正常工作。
这是一个非常简单的方法,但我相信它值得一试!