代码之家  ›  专栏  ›  技术社区  ›  SFEley

我可以在Ruby1.9上设置默认的字符串编码吗?

  •  17
  • SFEley  · 技术社区  · 15 年前

    这听起来可能很小,但一直让我发疯。自从上周五在Ruby1.9上发布应用程序投入生产以来,我遇到了很多与字符编码相关的小异常。几乎所有这些都是关于:

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

    我们有一个国际用户群,所以很多名字都包含元音变调等,如果我修改模板使用 强制编码 在很多地方,它会在flash消息助手中弹出。等等。

    目前看来,我已经确定了我所知道的所有内容,方法是在一个地方修补activesupport的字符串连接,然后设置 # encoding: utf-8 在我所有源文件的顶部。但是,那种为了避免字符串分配问题而不得不永远记住从现在起对每个ruby项目的每个文件都要这样做的感觉,在我的心里并不好受。我读到关于 -Ku 但一切似乎都在警告,这是为了向后兼容,可能随时消失。

    所以我要问1.9个有经验的人:是不是 #encoding 在我所有的档案里 真的? 必要吗?有没有一种合理的方式在全球范围内做到这一点?或者,更好的方法是,对绕过内部/外部默认值的字符串的非文本值设置默认编码?

    提前谢谢你的建议。

    4 回复  |  直到 15 年前
        1
  •  13
  •   Tilo    8 年前

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

    目的 #encoding 文件顶部的语句是在读取/解释代码时让ruby知道,并且编辑器知道如何在编辑/读取文件时处理任何非ascii字符。 --只有在文件中至少有一个非ascii字符时才有必要。这在你的配置/语言环境文件中是必要的。

    同时定义所有文件中的编码 你可以 使用 magic_encoding 宝石 ,它可以将uft-8魔术注释插入到应用程序中的所有ruby文件中。

    运行时出现的错误 Encoding::CompatibilityError 是在程序执行过程中尝试将两个具有不同编码的字符串连接起来时发生的错误,并且它们的编码不兼容。

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

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

    • 用户用一种外语(如utf-8)输入一个字符串,你的视图试图在某个视图中打印出来,同时打印一些你预先定义的固定字符串(ascii)。 force_encoding 会帮助 那里。还有 Encoding::primary_encoding 在rails 1.9中设置新字符串的默认编码。 还有 config.encoding 在config/application.rb文件的rails中。

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

    边注: 创建数据库时,请确保指定默认编码!

        create database yourproject  DEFAULT CHARACTER SET utf8;
    

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

        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

        2
  •  6
  •   nathanvda    13 年前

    在你 config/application.rb 添加

    config.encoding = "utf-8"
    

    高于 Application.initialize! 行在 config/environment.rb ,添加以下两行:

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

    希望这有帮助。

        3
  •  3
  •   Trevoke    15 年前

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

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

        4
  •  -2
  •   kojaktsl    13 年前
    String.module_eval "def initialize\nsuper\nputs encoding\nend"
    => nil
    irb(main):006:0> String.new
    ASCII-8BIT
    => ""
    

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

    推荐文章