【发布时间】:2011-05-08 03:44:47
【问题描述】:
我刚刚开始学习 Ruby(最终转向 RoR),但我刚刚被告知 Ruby 不支持 unicode。这是真的吗? Ruby 程序员如何支持 unicode?
【问题讨论】:
我刚刚开始学习 Ruby(最终转向 RoR),但我刚刚被告知 Ruby 不支持 unicode。这是真的吗? Ruby 程序员如何支持 unicode?
【问题讨论】:
您所听到的内容已经过时并且(仅部分)适用于 Ruby 1.8 或更早版本。 Ruby 最新的稳定版本(1.9),支持不少于95种不同的字符编码(我刚才的系统上算)。这包括几乎所有已知的 Unicode 转换格式,包括 UTF-8。
Ruby (1.8) 的早期稳定版本部分支持 UTF-8。
如果您使用 Rails,它会为您处理默认的 UTF-8 编码。如果您只需要 UTF-8 编码意识,那么 Rails 将适合您无论您运行的是 Ruby 1.9 还是 Ruby 1.8。如果您有非常具体的字符编码要求,您应该以 Ruby 1.9 为目标。
如果您真的感兴趣,这里有一个series of articles,描述了 Ruby 1.8 中的编码问题以及它们是如何解决的,并最终在 Ruby 1.9 中得到解决。 Rails 仍然包含针对 Ruby 1.8 中许多常见缺陷的解决方法。
【讨论】:
这是一个很老的问题。 Ruby 当前的稳定版本是 2.0.1。是的,它可以处理大部分您可以在 Unicode 中输入的内容,但请注意它很容易损坏。
看看这个代码示例和结果(灵感来自this):
["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"
重点是:现代 Ruby 处理基础 - 不应该指望更高级的字符串功能。
【讨论】:
efflab 是baffle 的反面没有意义?或者为什么baffle的大写应该是ELFFAB?
baffle 的反向应该是 elffab,而不是 efflab :-)
baffle 被正确处理,考虑到 ffl 是单个字符。这确实很有意义。 :)
gem 安装rails,需要active_support/core_ext/string 并改用str.mb_chars.reverse。
在我的文件顶部添加以下行解决了它。
# encoding: utf-8
【讨论】:
在this answer 的另一个问题中,有人说他们在处理 Ruby 1.9 中的 unicode 数据时遇到了 Iconv 的问题,但我不能保证它的准确性。
【讨论】:
那不是真的。确实,Ruby 不支持 only Unicode,它还支持一大堆其他编码。
这与 Java、.NET 或 Python 等系统形成对比,它们遵循“一个编码来统治它们”模型。 Ruby 拥有 Ruby m17n 系统的一位设计者所称的“CSI”模型(代码集独立),这意味着不是所有字符串都只有一个相同的编码,而是每个字符串都有自己的编码标记。
这在易用性和性能方面都有一些显着的优势,因为这意味着如果您的输入和输出编码相同,您永远不需要转码,而使用 One True Encoding 模型,您需要转码两次最坏的情况(不幸的是,最坏的情况经常发生,因为这些环境中的大多数都选择了没有人实际使用的内部编码),从输入编码到内部编码,然后到输出编码。在 Ruby 中,您最多需要转码一次。
OTE 模型的基本问题是,无论您选择哪种编码作为唯一真正编码,这将是一个完全任意的选择,因为根本没有每个人甚至大多数人都使用的单一编码。
例如,在 Java 中,他们选择 UCS-2 作为 One True Encoding。然后,几年后,事实证明 UCS-2 实际上不足以编码所有字符,因此他们不得不对 Java 进行向后不兼容的更改,以切换到 UTF-16 作为 One True Encoding。除了那个时候,世界上很大一部分地区已经从 UTF-16 转向 UTF-8。如果 Java 早在几年前被发明出来,他们可能会选择 ASCII 作为唯一的真正编码。如果它是在另一个国家发明的,它可能是 Shift-JIS。如果它是由另一家公司发明的,它可能是 EBCDIC。这真的完全是武断的,如此重要的选择不应该。
【讨论】: