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

这可能听起来很小,但它让我疯了。 自上周五在Ruby 1.9上将应用程序发布到生产以来,我一直有很多与字符编码有关的小例外。 几乎所有这些都是一些变化:

Encoding::CompatibilityError: incompatible character encodings: ASCII-8BIT and UTF-8 

我们有一个国际用户群,所以很多名字都包含变音符号等。如果我修复模板在一堆地方使用force_encoding ,它会弹出flash消息助手。 等等。

目前看起来我已经确定了我所知道的所有内容,通过在一个地方修补ActiveSupport的字符串连接,然后在每个源文件的顶部设置#coding # encoding: utf-8 。 但是,我可能必须记住为我从现在开始的每个Ruby项目的每个文件都做到这一点的感觉,永远,只是为了避免字符串分配问题,并不适合我的胃。 我读到了关于-Ku开关的信息,但是所有内容似乎都警告说这是为了向后兼容并且可能随时消失。

所以我对1.9经验丰富的人提出的问题是:在我的每个文件中设置#encoding 真的有必要吗? 在全球范围内有合理的方法吗? 或者,更好的方法是在绕过内部/外部默认值的字符串的非文字值上设置默认编码?

在此先感谢您的任何建议。

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

文件顶部#encoding语句的目的是让Ruby在读取/解释代码时知道,并且编辑器知道如何在编辑/读取文件时处理任何非ASCII字符 – 只有在您需要时才需要文件中至少有一个非ASCII字符。 例如,在您的config / locale文件中有必要。

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

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

这很可能发生在:

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

  • 用户以外语(例如UTF-8)键入字符串,并且您的视图会尝试在某些视图中将其打印出来,以及您预定义的一些固定字符串(ASCII)。 force_encoding将有助于那里。 Rails 1.9中还有Encoding::primary_encoding来设置新字符串的默认编码。 在config / application.rb文件中的Rails中有config.encoding

  • 来自数据库的字符串,然后与视图中的其他字符串组合。 (他们的编码可能是两种方式,并且不相容)。

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

  create database yourproject DEFAULT CHARACTER SET utf8; 

如果要在字符串中使用EMOJI:

  create database yourproject DEFAULT CHARACTER SET utf8mb4 collate utf8mb4_bin; 

并且可能包含EMOJI的字符串列上的所有索引的长度必须为191个字符。 字符集utf8mb4 COLLATE utf8mb4_bin

原因是普通UTF8最多使用3个字节,而EMOJI使用4个字节存储。

请查看Yehuda Katz的这篇文章 ,该文章深入介绍了这一点并对其进行了解释:(特别是“不兼容的编码”部分)

http://yehudakatz.com/2010/05/05/ruby-1-9-encodings-a-primer-and-the-solution-for-rails/

http://yehudakatz.com/2010/05/17/encodings-unabridged/

和:

http://zargony.com/2009/07/24/ruby-1-9-and-file-encodings

http://graysoftinc.com/character-encodings

在你的config/application.rb添加

 config.encoding = "utf-8" 

以及Application.initialize!config/environment.rb中添加以下两行:

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

希望这可以帮助。

http://zargony.com/2009/07/24/ruby-1-9-and-file-encodings

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

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

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