Ruby 1.9尚不支持Unicode规范化
我正在尝试将一些旧的rails应用程序移植到Ruby 1.9,并且我一直在收到有关“Ruby 1.9如何不支持Unicode规范化”的警告。 我已将其跟踪到此function,但每个请求我收到大约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
任何想法我应该如何开始跟踪这些并解决它?
如果你知道后果,即重音字符不会在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确实解决了这个问题,因此更加面向未来的解决方案就是向它迁移。
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"
请享用。
该方法定义包含在Ruby 1.9的if语句中。 在它上面,你会发现常规定义,它更多地显示了它正在做的事情。 这是一种用于将重音字符转换为常规变体的方法。 例如: á
=> a
,或ë
=> e
但是这种方法仅用于参数化,而参数化又在音译之上定义。 这仍然在ActiveSupport中。 我找不到任何直接调用参数化的东西。
那么也许你在Rails应用程序中的某个地方使用参数化或音译?
常用(根据参数化文档)用于从任意字符串创建友好的永久链接,就像SO一样,例如:
http://stackoverflow.com/questions/2135247/ruby-1-9-doesnt-support-unicode-normalization-yet ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
用方法替换方法的主体
raise "transliterate called"
并观察一个回溯,它将显示第一次通话时东西的来源。 您的应用程序当然也会崩溃,但这可能会让您在第一次尝试时成为罪魁祸首。
我很欣赏这是解决问题的一种肮脏方式,但是已经阅读了错误消息,我知道这个问题。 所以我想摆脱警告。 我在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
如果你不想修补Inflector
模块,你也可以这样做……
以下这两个对我来说是沉默这个恼人的“Ruby 1.9还不支持Unicode规范化”警告:
silence_stream(STDERR) { whatever_code_caused_transliterate_to_be_called }
要么
silence_warnings { whatever_code_caused_transliterate_to_be_called }
这样做的缺点是它需要混乱你的调用代码,但是这种技术通常可以在你不想看到警告或其他输出时使用。
activesupport
在activesupport-2.3.11/lib/active_support/core_ext/kernel/reporting.rb
提供silence_stream
和silence_warnings
String#unicode_normalize , String#unicode_normalize! , String#unicode_normalized? 将在Ruby 2.2中介绍。 在测试用例 lib / unicode_normalize.rb和lib / 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)