Ruby 1.9 не поддерживает нормализацию Unicode
Я пытаюсь перенести некоторые из моих старых приложений на rails в Ruby 1.9, и я продолжаю получать предупреждения о том, как Ruby 1.9 еще не поддерживает нормализацию Unicode. Я отследил его до этой функции, но я получаю около 20 предупреждающих сообщений за запрос:
Рельсы-2.3.5/ActiveSupport/Library/active_support/inflector.rb
def transliterate(string)
warn "Ruby 1.9 doesn't support Unicode normalization yet"
string.dup
end
Любые идеи, как я должен начать отслеживать их и разрешать?
Ответы
Ответ 1
Если вы знаете о последствиях, то есть акцентированные символы не будут транслитерироваться в 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 действительно решает эту проблему, поэтому более надежным решением будет переход на это.
Ответ 2
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"
Enjoy.
Ответ 3
Это определение метода завершается в if-statement для Ruby 1.9. Прямо над ним вы найдете регулярное определение, которое показывает немного больше того, что это делает. Это метод, используемый для преобразования акцентированных символов в их обычные варианты. Например: á
= > a
, или ë
= > e
Но этот метод используется только в параметризации, который, в свою очередь, определен прямо над транслитерацией. Это все еще в ActiveSupport. Я не могу найти ничего, что непосредственно вызывает параметризацию.
Итак, возможно, вы используете параметризовать или транслитерировать себя, где-то в вашем приложении Rails?
Общее использование (в соответствии с документацией по параметризации) предназначено для создания дружественных постоянных ссылок из произвольных строк, например SO, например:
http://stackoverflow.com/questions/2135247/ruby-1-9-doesnt-support-unicode-normalization-yet
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Ответ 4
Замените тело метода на
raise "transliterate called"
и обратите внимание на обратную трассу, которая покажет вам, откуда материал при первом вызове. Ваше приложение, конечно же, рушится, но это, скорее всего, даст вам виновника с первой попытки.
Ответ 5
Я ценю, что это грязный способ решить проблему, но, прочитав сообщение об ошибке, я знаю об этой проблеме. Поэтому я хочу избавиться от предупреждений. Я отбросил этот код в 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
Ответ 6
Если вы предпочтете не обезвреживать патч 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
предоставляет silence_stream
и silence_warnings
в activesupport-2.3.11/lib/active_support/core_ext/kernel/reporting.rb
Ответ 7
Строка # unicode_normalize, Строка # unicode_normalize!, Строка # 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)