【问题标题】:Why does Ruby Integer method 'chr' use ASCII-8bit, not UTF-8 by default?为什么 Ruby Integer 方法“chr”默认使用 ASCII-8bit,而不是 UTF-8?
【发布时间】:2021-05-10 15:05:38
【问题描述】:

根据它的源代码https://www.rubydoc.info/stdlib/core/Integer:chr,如果没有提供参数,则此方法使用ASCII编码,实际上,带参数和不带参数调用时会给出不同的结果:

irb(main):002:0* 255.chr
=> "\xFF"

irb(main):003:0' 255.chr 'utf-8'
=> "ÿ"

为什么会这样?默认情况下,Ruby 不应该在任何地方都使用 UTF-8 吗?至少所有字符串似乎都是用 UTF-8 编码的:

irb(main):005:0> "".encoding
=> #<Encoding:UTF-8>

【问题讨论】:

    标签: ruby utf-8 character-encoding ascii


    【解决方案1】:

    为什么会这样?

    对于从 U+0000 到 U+007F (127) 的字符,绝大多数单字节和可变长度字符编码都同意编码。特别是,它们都同意是 ASCII 的严格超集。

    换句话说:对于直到并包括 U+007F、ASCII、整个 ISO8859 系列、整个 DOS 代码页系列、整个 Windows 系列以及 UTF-8 的字符,实际上相同。因此,对于 U+0000 和 U+007F 之间的字符,ASCII 是合乎逻辑的选择:

    0.chr.encoding
    #=> #<Encoding:US-ASCII>
    
    127.chr.encoding
    #=> #<Encoding:US-ASCII>
    

    但是,对于 127 以上的任何内容,或多或少没有两个字符编码是一致的。事实上,127 以上的绝大多数字符甚至在绝大多数字符集中都不存在,因此没有编码 > 在绝大多数字符编码中。

    换句话说:几乎不可能为127以上的字符找到单个默认编码。

    因此,Ruby 选择的编码是Encoding::BINARY,这基本上是一种伪编码,意思是“这实际上不是文本,这是非结构化的未知二进制数据”。 (对于歇斯底里的葡萄干,这种编码也别名为ASCII-8BIT,我觉得这非常可怕,因为 ASCII 是 7 位,句号,而任何使用第 8 位的东西根据定义不是 ASCII。)

    128.chr.encoding
    #=> #<Encoding:ASCII-8BIT>
    
    255.chr.encoding
    #=> #<Encoding:ASCII-8BIT>
    

    另请注意,Integer#chr 仅限于单个八位字节,即范围从 0 到 255,因此这里实际上不需要多八位字节或可变长度编码。

    默认情况下,Ruby 不应该在所有地方都使用 UTF-8 吗?

    你说的是哪种编码? Ruby 大约有半打。

    对于绝大多数编码,您的说法是不正确的。

    • 语言环境编码是环境的默认编码
    • 文件系统编码是用于文件路径的编码:值由文件系统确定
    • IO 对象的外部编码是假定此读取的文本和写入的文本的编码> 转码为:默认为locale编码
    • IO 对象的内部编码Strings 必须写入IO 对象的编码以及@987654332从IO对象读取的@s被转码为:默认为默认内部编码,其默认值为nil,表示不进行转码
    • 脚本编码是读取Ruby脚本的编码,脚本中的String字面量也会继承这种编码:在脚本开头用魔术注释设置, 默认为 UTF-8

    因此,如您所见,有许多不同的编码和许多不同的默认值,其中只有 一个 是 UTF-8。而 none 这些编码实际上与您的问题相关,因为 128.chr 既不是 String 文字也不是 IO 对象。它是一个String 对象,由Integer#chr 方法使用它认为合适的任何编码创建。

    【讨论】:

    • 还要注意,Integer#chr 仅限于单个八位字节,即范围从 0 到 255,因此这里实际上不需要多八位字节或可变长度编码。 i> 实际上,chr 方法可以处理多字节字符,但前提是您指定了正确的编码,例如:irb(main):002:0&gt; 1050.chr 'utf-8' =&gt; "К"
    • 你提到的“歇斯底里的葡萄干”让我想起了 1980 年代中期的一些 famous TV ads。 ¯\_(ツ)_/¯
    猜你喜欢
    • 2016-07-23
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 2014-02-09
    • 2014-06-12
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    相关资源
    最近更新 更多