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)