我刚开始学习Ruby(最终要转向RoR),但有人告诉我Ruby不支持Unicode。这是真的吗?Ruby程序员如何支持Unicode?
在我的文件顶部添加以下行解决了它。
# encoding: utf-8
这不是真的。真正的情况是Ruby不仅支持Unicode,还支持一系列其他编码。
这与Java、.NET或Python等系统形成对比,后者遵循“一种编码规则其它所有”的模型。Ruby有一个设计者称之为“CSI”(Code Set Independent)模型的m17n系统,这意味着每个字符串都被标记了自己的编码,而不是所有字符串都只使用一种编码。
这对于易用性和性能都有一些显著的优势,因为这意味着如果你的输入和输出编码相同,你永远不需要转换编码,而在One True Encoding模型中,你需要在最坏的情况下转换两次(而且这种最坏的情况经常发生,因为大多数这些环境选择了一个实际上没有人使用的内部编码),从输入编码到内部编码,然后再到输出编码。在Ruby中,你最多只需要转换一次编码。
OTE模型的基本问题是,无论你选择哪种编码作为唯一的编码,它都将是完全随意的选择,因为根本不存在一种编码是每个人,甚至大多数人都使用的。
例如,在Java中,他们选择UCS-2作为唯一的编码。然后,几年后,发现UCS-2实际上无法编码所有字符,所以他们不得不对Java进行了一次不兼容的更改,以将UTF-16作为唯一的编码。但当时,世界上很大一部分人已经从UTF-16转向UTF-8了。如果Java在几年前被发明,他们可能会选择ASCII作为唯一的编码。如果是在另一个国家发明,可能会是Shift-JIS。如果是由另一家公司发明,可能会是EBCDIC。这真的完全随意,而如此重要的选择不应该是这样的。
这是一个很老的问题。当前稳定版本的Ruby是2.0.1。是的,它可以处理大多数Unicode字符,但请注意它容易崩溃。
看一下这个代码示例和结果(受这篇文章的启发):
["noël","","baffle"].each do |str|
puts "Result for '#{str}'"
puts " Size: #{str.size}"
puts " Reverse: [#{str.reverse}]"
puts " Uppercase: [#{str.upcase}]"
end
Result for 'noël'
Size: 5 << bad size
Reverse: [l̈eon] <= accent is shifted
Uppercase: [NOËL]
Result for ''
Size: 2
Reverse: []
Uppercase: []
Result for 'baffle'
Size: 4
Reverse: [efflab] <= doesn't really make sense
Uppercase: [BAfflE] <= should be "ELFFAB"
efflab
是baffle
的反转不合理呢?或者为什么baffle
的大写应该是ELFFAB
? - eisbaffle
的反转应该是elffab
,而不是efflab
:-) - kralykbaffle
被正确对待了,因为 ffl
是一个单独的字符。这确实很有道理 :) - raygem
安装rails
,需要active_support/core_ext/string
并使用str.mb_chars.reverse
。 - wieczorek1990['a', 'ą', 'b'].sort
在 Ruby 2.3.4 中也会失败(返回 ["a", "b", "ą"]
而不是 ["a", "ą", "b"]
)。 - reducing activity