这可能听起来很小,但它让我疯了。自上周五在Ruby 1.9上发布一个应用程序到生产以来,我一直有很多与字符编码有关的小例外。几乎所有这些都有一些变化:
Encoding::CompatibilityError: incompatible character encodings: ASCII-8BIT and UTF-8
我们有一个国际用户群,所以很多名字都包含变音符号等。如果我修复模板以便在一堆地方使用 force_encoding ,它会在flash消息助手中弹出。等等。
目前看起来我已经确定了我所知道的所有内容,通过在一个地方修补ActiveSupport的字符串连接,然后在我的每个源文件的顶部设置# encoding: utf-8
。但是我觉得我可能必须记住为我从现在开始做的每个Ruby项目的每个文件做到这一点,永远,只是为了避免字符串分配问题,并不适合我的胃。我读到了 -Ku 开关,但所有内容似乎都警告说它是为了向后兼容并且可能随时消失。
所以我对1.9位经验丰富的人提出的问题是:在我的每个文件中设置#encoding
真的是必要的吗?在全球范围内有合理的方法吗?或者,更好的方法是在绕过内部/外部默认值的字符串的非文字值上设置默认编码?
提前感谢任何建议。
答案 0 :(得分:13)
不要将文件编码与字符串编码混淆
文件顶部的 #encoding
语句的目的是让Ruby知道读取/解释代码,编辑知道在编辑/读取代码时如何处理任何非ASCII字符文件 - 只有在文件中至少有一个非ASCII字符时才需要。例如在配置/区域设置文件中是必要的。
要一次定义所有文件中的编码,您可以使用 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
。
来自数据库的字符串,然后与视图中的其他字符串结合使用。 (他们的编码可以是两种方式,也可以是不相容的)。
Side-Note:确保在创建数据库时指定默认编码!
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/
和
答案 1 :(得分:6)
在config/application.rb
添加
config.encoding = "utf-8"
在Application.initialize!
的{{1}}行之上,添加以下两行:
config/environment.rb
希望这有帮助。
答案 2 :(得分:3)
http://zargony.com/2009/07/24/ruby-1-9-and-file-encodings
不要混淆文件编码和字符串编码!
答案 3 :(得分:-2)
String.module_eval "def initialize\nsuper\nputs encoding\nend"
=> nil
irb(main):006:0> String.new
ASCII-8BIT
=> ""
不确定如何在系统中实现字符串,但是通过挂钩String对象的initialize方法,可以为在整个应用程序中创建的任何字符串设置编码。