Ruby支持unicode吗?它是如何工作的?

Reg*_*man 31 ruby unicode

我刚刚开始学习Ruby(最终转向RoR),但我刚刚被告知Ruby不支持unicode.这是真的吗?Ruby程序员如何支持unicode?

mol*_*olf 31

你听到的是过时的,并且(仅部分)适用于Ruby 1.8或之前.Ruby(1.9)的最新稳定版本支持不少于95种不同的字符编码(刚才我的系统统计).这包括几乎所有已知的Unicode转换格式,包括UTF-8.

以前稳定版本的Ruby(1.8)部分支持 UTF-8.

如果你使用Rails,它会为你处理默认的UTF-8编码.如果您只需要UTF-8编码感知,无论您运行Ruby 1.9还是Ruby 1.8,Rails都能为您提供服务.如果您有非常特定的字符编码要求,那么您应该针对Ruby 1.9.

如果您真的很感兴趣,这里有一系列文章描述了Ruby 1.8中的编码问题以及它们是如何解决的,最终在Ruby 1.9中得到了解决.Rails仍然包含Ruby 1.8中许多常见缺陷的解决方法.


Kan*_*yan 15

在我的文件顶部添加以下行解决了它.

# encoding: utf-8
Run Code Online (Sandbox Code Playgroud)


Jör*_*tag 14

这不是真的.什么是真正的是,红宝石不支持 Unicode的,它支持其他编码的整体转换,以及.

这与Java,.NET或Python之类的系统形成对比,后者遵循"One Encoding To Rule Allm"模型.Ruby拥有Ruby的m17n系统的一个设计者称为"CSI"模型(Code Set Indepedent),这意味着每个字符串都使用自己的编码标记,而不是只有一个相同的编码.

这对于易用性和性能都有一些显着的优势,因为这意味着如果您的输入和输出编码相同,您永远不需要转码,而使用One True Encoding模型,您需要在最坏的情况下进行两次转码(不幸的是,最糟糕的情况经常发生,因为大多数这些环境选择了一个没有人实际使用的内部编码),从输入编码到内部编码再到输出编码.在Ruby中,您需要最多转码一次.

OTE模型的基本问题是,无论您选择哪种编码作为One True Encoding,它都将是一个完全随意的选择,因为没有一个编码,每个人,甚至大多数人使用.

例如,在Java中,他们选择UCS-2作为One True Encoding.然后,几年后,事实证明UCS-2实际上还不足以对所有字符进行编码,因此他们必须对Java进行向后不兼容的更改,以切换到UTF-16作为One True Encoding.除此之外,世界上很大一部分人已经从UTF-16转向UTF-8.如果Java是几年前发明的,那么他们可能会选择ASCII作为One True Encoding.如果它是在另一个国家发明的,它可能是Shift-JIS.如果它是由另一家公司发明的,它可能是EBCDIC.这是真的完全是随意的,而这样一个重要的选择不应该是.

  • Jörg:[#1]**角色曲目**是完整的纯抽象角色.[#2] A**编码字符集**将这些抽象字符映射到以1:1关系称为*代码点*的非负整数.[#3]**字符编码函数**(或表单)定义了用于序列化这些整数代码点的精确按位布局.通过查看比Unicode更小的曲目,可能更容易理解这一点.Radix-50有一个50个字符的曲目,有2个不同的编码字符集(pre-vs PDP-11),其代码点一次包含3个16位字.*(继续…)* (5认同)
  • @Jörg:你忘了提Perl.它的模型比Java更清晰,因为它使用逻辑代码点(def#2)而不是序列化的(def#3)作为Java和Python不明智.但是,是的,所有内容都规范化为Unicode指令表(def#1).我还没有看到任何合理的演示,为什么你会想要外来的,非Unicode能力的代码点或永远携带每个字符串的原始序列化.我认为Ruby是一个严重的缺陷,而不是任何一种理想的功能.它还暗示了对Unicode的巨大"私人使用"部分的误解. (4认同)
  • @tchrist:它是一种编码,它为每个字符分配一个唯一的*数字*(这几乎就是"编码"的字典定义).它不是一种编码,因为它没有为每个字符分配唯一的*位模式*(在Unicode术语中,这是传输格式的工作).不幸的是,除了"编码"之外,我从来没有能够为Unicode提供一个好名字. (3认同)
  • *(...续)*根据def#1,Unicode是一个包含诸如带有MACRON的拉丁文大写字母AE,德国PENNY SIGN和CIRCLED WZ等抽象字符的曲目.根据def#2,这3个抽象字符分别分配代码点1E2 1,20B0 1和1F12E 18.根据def#3,那些整数在UTF-8下序列化为"\ xC7\xA2","\ xE2\x82\xB0"和"\ xF0\x9F\x84\xAE"; 下UTF-16BE到 "\ XE2\X01", "\ XB0\X20",& "\ X3C\XD8\X2E \的xDD"; 在UTF-32LE下为"\ x00\x00\x01\xE2","\ x00\x00\x20\xB0",&"\ x00\x01\xF1\x2E".我,我使用*encoding*代表def#3,*代码点赋值*代表def#2.合理? (3认同)

Gre*_*gPK 5

这是一个很老的问题.目前Ruby的稳定版本是2.0.1.是的,它可以处理大部分你可以使用Unicode的内容,但请注意它很容易破坏.

看看这段代码示例和结果(灵感来自于此):

["noe?l","","ba?e"].each do |str|
  puts "Result for '#{str}'"
  puts "  Size: #{str.size}"
  puts "  Reverse: [#{str.reverse}]"
  puts "  Uppercase: [#{str.upcase}]"
end  

Result for 'noe?l'
  Size: 5 << bad size
  Reverse: [l?eon] <= accent is shifted
  Uppercase: [NOE?L]
Result for ''
  Size: 2
  Reverse: []
  Uppercase: []
Result for 'ba?e'
  Size: 4
  Reverse: [e?ab] <= doesn't really make sense
  Uppercase: [BA?E] <= should be "ELFFAB"
Run Code Online (Sandbox Code Playgroud)

关键是:现代Ruby处理基础知识 - 不应指望更高级的字符串功能.

  • @kralyk @GregPK看起来'ba ffl e`被正确对待,考虑ffl是单个字符.它确实有意义.:) (4认同)