Ruby 1.9尚不支持Unicode规范化

时间:2010-01-25 20:08:36

标签: ruby-on-rails ruby unicode

我正在尝试将一些旧的rails应用程序移植到Ruby 1.9,并且我一直在收到有关“Ruby 1.9如何不支持Unicode规范化”的警告。我已将其跟踪到此功能,但每个请求我收到大约20条警告消息:

导轨-2.3.5 /的ActiveSupport / LIB / active_support / inflector.rb

def transliterate(string)
  warn "Ruby 1.9 doesn't support Unicode normalization yet"
  string.dup
end

我应该如何开始跟踪它们并解决它?

7 个答案:

答案 0 :(得分:9)

如果你知道后果,即重音字符不会在Ruby 1.9.1 + Rails 2.3.x中音译,请将它放在config / initializers中以使警告静音:

# http://stackoverflow.com/questions/2135247/ruby-1-9-doesnt-support-unicode-normalization-yet
module ActiveSupport
  module Inflector
    # Calling String#parameterize prints a warning under Ruby 1.9,
    # even if the data in the string doesn't need transliterating.
    if Rails.version =~ /^2\.3/
      undef_method :transliterate
      def transliterate(string)
        string.dup
      end
    end
  end
end

Rails 3确实解决了这个问题,因此更加面向未来的解决方案就是向它迁移。

答案 1 :(得分:4)

StringEx Gem似乎运作良好。它也不依赖于Iconv。

它为String类添加了一些方法,比如“to_ascii”,它可以开箱即用:

require 'stringex'
"äöüÄÖÜßë".to_ascii #=> "aouAOUsse"

此外,即使语言支持,Babosa Gem也能很好地音译UTF-8字符串:

"Jürgen Müller".to_slug.transliterate.to_s           #=> "Jurgen Muller"
"Jürgen Müller".to_slug.transliterate(:german).to_s  #=> "Juergen Mueller"

享受。

答案 2 :(得分:2)

该方法定义包含在Ruby 1.9的if语句中。在它的正上方,您将找到常规定义,其中显示了更多内容。这是一种用于将重音字符转换为常规变体的方法。例如:á => aë => e

但是这种方法仅用于参数化,而参数化又在音译之上定义。这仍然在ActiveSupport中。我找不到任何直接调用参数化的东西。

所以也许你在Rails应用程序的某个地方使用参数化或音译?

常用(根据参数化文档)用于从任意字符串创建友好的永久链接,就像SO一样,例如:

http://stackoverflow.com/questions/2135247/ruby-1-9-doesnt-support-unicode-normalization-yet
                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

答案 3 :(得分:2)

替换方法的主体
raise "transliterate called"

并观察一个回溯,它会显示第一次通话时东西的来源。您的应用程序当然也会崩溃,但这可能会让您在第一次尝试时成为罪魁祸首。

答案 4 :(得分:1)

我很欣赏这是解决问题的一种肮脏方式,但是已经阅读了错误消息,我知道这个问题。所以我想摆脱警告。我在environment.rb中删除了这段代码:

module ActiveSupport
  module Inflector
    # Calling String#parameterize prints a warning under Ruby 1.9,
    # even if the data in the string doesn't need transliterating.
    # Maybe Rails 3 will have fixed it...?
    if RAILS_GEM_VERSION =~ /^2\.3/
      undef_method :transliterate
      def transliterate(string)
        string.dup
      end
    end
  end
end

答案 5 :(得分:1)

如果你不想修补Inflector模块,你也可以这样做......

以下这两项工作让我沉默了这个恼人的“Ruby 1.9还不支持Unicode规范化”警告:

silence_stream(STDERR) {
  whatever_code_caused_transliterate_to_be_called
}

silence_warnings {
  whatever_code_caused_transliterate_to_be_called
}

这样做的缺点是它需要混乱你的调用代码,但是这种技术通常可以在你不想看到警告或其他输出时使用。

activesupportsilence_stream

中提供silence_warningsactivesupport-2.3.11/lib/active_support/core_ext/kernel/reporting.rb

答案 6 :(得分:0)

String#unicode_normalize String#unicode_normalize! String#unicode_normalized?将在Ruby 2.2中引入。可以在test caselib/unicode_normalize.rblib/unicode_normalize/normalize.rb中查看示例代码和实现。

// U+00E1: LATIN SMALL LETTER A WITH ACUTE
// U+U+0301: COMBINING ACUTE ACCENT

puts "\u00E1" == "a\u0301".unicode_normalize(:nfc)
puts true == "a".unicode_normalized?(:nfc)