Ruby on rails 我可以在Ruby 1.9上设置默认的字符串编码吗?

Ruby on rails 我可以在Ruby 1.9上设置默认的字符串编码吗?,ruby-on-rails,ruby,utf-8,character-encoding,ruby-1.9,Ruby On Rails,Ruby,Utf 8,Character Encoding,Ruby 1.9,这听起来可能很小,但我快发疯了。自从上周五在Ruby 1.9上发布了一个应用程序投入生产以来,我遇到了很多与字符编码相关的小异常。几乎所有这些都是以下方面的一些变化: Encoding::CompatibilityError: incompatible character encodings: ASCII-8BIT and UTF-8 我们有一个国际用户群,因此许多名称包含UMLAUT等。如果我修复模板,在许多地方使用强制编码,它会在flash message helper中弹出。等等 目前看

这听起来可能很小,但我快发疯了。自从上周五在Ruby 1.9上发布了一个应用程序投入生产以来,我遇到了很多与字符编码相关的小异常。几乎所有这些都是以下方面的一些变化:

Encoding::CompatibilityError: incompatible character encodings: ASCII-8BIT and UTF-8
我们有一个国际用户群,因此许多名称包含UMLAUT等。如果我修复模板,在许多地方使用强制编码,它会在flash message helper中弹出。等等

目前看来,我已经确定了所有我知道的,通过在一个地方修补ActiveSupport的字符串连接,然后在每个源文件的顶部设置
#encoding:utf-8
。但是,从现在起,为了避免字符串赋值问题,我可能不得不永远记住对每个Ruby项目的每个文件都这样做,这种感觉在我的心里并不舒服。我读到了关于-Ku开关的文章,但似乎所有的东西都警告说,这是为了向后兼容,可能会在任何时候消失

因此,我要问1.9版的老手:在我的每个文件中设置
#编码
真的有必要吗?是否有一种合理的方式在全球范围内做到这一点?或者,更好的方法是,在绕过内部/外部默认值的字符串的非文字值上设置默认编码

提前感谢您的建议。


不要混淆文件编码和字符串编码

String.module_eval "def initialize\nsuper\nputs encoding\nend"
=> nil
irb(main):006:0> String.new
ASCII-8BIT
=> ""

不确定如何在系统中实现字符串,但通过挂接字符串对象的initialize方法,可以为在整个应用程序中创建的任何字符串设置编码。

config/application.rb
add中

config.encoding = "utf-8"
Application.initialize行在
config/environment.rb
中,添加以下两行:

Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8

希望这有帮助。

不要将文件编码与字符串编码混淆

文件顶部的
#encoding
语句的目的是让Ruby在读取/解释代码时知道,并且您的编辑器知道如何在编辑/读取文件时处理任何非ASCII字符
——只有在文件中至少有一个非ASCII字符时才有必要这样做。e、 g.这在您的配置/区域设置文件中是必需的

要一次在所有文件中定义编码,可以使用 gem,它可以在应用程序中的所有ruby文件中插入uft-8魔术注释

您在运行时遇到的错误
Encoding::CompatibilityError
是一个错误,当您在程序执行过程中尝试用不同的编码连接两个字符串,并且它们的编码不兼容时会发生此错误。

这种情况最有可能发生在以下情况:

  • 您正在使用L10N字符串(例如UTF-8),并将它们连接到例如ASCII字符串(在您的视图中)

  • 用户键入一个外语字符串(例如UTF-8),您的视图尝试在某个视图中打印该字符串,以及您预定义的某个固定字符串(ASCII)
    force_编码
    将在这方面有所帮助。Rails 1.9中还有
    编码::primary\u编码
    ,用于设置新字符串的默认编码。
    在config/application.rb文件中的Rails中有
    config.encoding

  • 来自数据库的字符串,然后与视图中的其他字符串组合。 (它们的编码可能是任意一种,并且不兼容)

旁注:请确保在创建数据库时指定默认编码

    create database yourproject  DEFAULT CHARACTER SET utf8;
如果要在字符串中使用表情符号:

    create database yourproject DEFAULT CHARACTER SET utf8mb4 collate utf8mb4_bin;
字符串列上可能包含表情符号的所有索引的长度都必须为191个字符。字符集utf8mb4校对utf8mb4\u bin

原因是普通UTF8最多使用3个字节,而表情符号使用4个字节的存储

请查看这篇耶胡达·卡茨的文章,这篇文章深入介绍了这一点,并对其进行了很好的解释: (专门有一节“不兼容编码”)

以及:


谢谢崔沃克;我确实知道区别。但是,字符串继承创建它们的源文件的编码。(除非它们来自另一个文件上的IO操作;因此是默认的内部属性和默认的外部属性。)因此,虽然它们不一样,但它们有着深刻而令人沮丧的联系。我想要的是一种设置默认字符串编码的方法,而不必使用
#encoding
注释。您想知道的关于编码的一切:可能还有您希望永远不会了解的更多:)看起来很有希望,但在加载“xxx.rb”时仍然会出现相同的多字节错误,其中xxx.rb包含utf8config.encoding用于rails html输出编码afaik,与ruby的字符串编码无关此答案还假设(尽管相当公平)OP询问rails.com似乎无法修复使用utf8加载文件的问题我尝试过:string.module_eval“def initialize\nsuper\nencoding=encoding::UTF_8\nend”加载'xxx.rb'在做了更多的测试之后,我注意到字符串的initialize方法很少被调用。但这只是一个建议,也许在应用程序中创建字符串时,有一个方法可以调用所有字符串?只需将编码行添加到该行,而不是初始化。(我所说的创建,是指加载到内存、解析或其他)也许重写require可以做到这一点,但我不愿意走这么远:我不想处理所有这些编码混乱,知道所有的边缘情况很好,但我希望没有边缘情况。只要把每件事都当作utf8,如果某件事是另一件事,它就必须被声明为utf8。@grosser:我同意——这是一个巨大的痛苦!更糟糕的是,因为它,他们弄乱了低级别的IO类,这些类用来返回st