Обработка строкового кодирования с одинаковым кодом в Ruby 1.8 и 1.9 - PullRequest
1 голос
/ 22 марта 2011

У меня есть gem , который использовал группу людей, использующих группу различных интерпретаторов Ruby, и включает в себя то, что сводится к этому коду:

res = RestClient.post(...)
doc = REXML::Document.new(res).root

Содержаниеres - это всегда UTF-8, и это прекрасно работает в Ruby 1.8, но взрывается в Ruby 1.9, если ответ не является чистым ASCII и кодировка пользователя по умолчанию не UTF-8.

Теперь, если бы я хотел сделать эту работу только на Ruby 1.9, я бы просто вставил туда res.force_encoding('utf-8') и покончил бы с этим, но этот метод только для 1.9, а затем перестал работать под Ruby 1.8:

NoMethodError: undefined method `force_encoding' for #<String:0x101318178>

Лучшее решение, которое может быть предложено, это то, что заставляет кодировку по умолчанию для всей системы использовать UTF-8:

Encoding.default_external = 'UTF-8' if defined? Encoding

Лучшие идеи, или это так хорошо, как это получается?Будет ли какое-либо негативное влияние на пользователей библиотеки, которые пытаются использовать разные кодировки?

Ответы [ 4 ]

3 голосов
/ 22 марта 2011
  if res.respond_to?(:force_encoding)
    new_contents = res.force_encoding("UTF-8")
  else
    new_contents = res
  end

Я бы сделал что-то подобное для обратной совместимости.

2 голосов
/ 31 марта 2011

Я с Майком Льюисом использую respond_to, но не делайте этого с переменной res везде в вашем коде.

Я посмотрел на ваш код в gateway.rb , и, похоже, везде, где вы используете res, он устанавливается при вызове make_api_request, так что вы можете добавить его до возврата утверждение в этом методе:

doc = doc.force_encoding("UTF-8") if doc.respond_to?(:force_encoding) 

Даже если это другие места, но это не буквально с каждой строкой, с которой вы сталкиваетесь, я уверен, что вы можете найти способ реорганизовать код, который имеет смысл и решает проблемы в одном месте, а не везде, где вы сталкиваетесь с ним.

У вас проблемы с другими местами?

1 голос
/ 29 марта 2011

Насколько я вижу из фрагмента, причина проблемы - RestClient, которая не возвращает строку в правильной кодировке (той, которая указана в HTTP-ответе), поэтому сначала я попытаюсь ее получить.проблема исправлена.Если это не может быть сделано, тогда вы можете обернуть RestClient вызовы своим кодом, который форсирует кодирование (как предложил Майк Льюис).Или вы испытываете проблему в других местах, кроме RestClient звонков?

0 голосов
/ 29 марта 2011

Работает ли это, если вы включили заголовок #encoding: utf-8 в этот конкретный файл, который использует этот метод.

Ruby 1.9 поддерживает различные кодировки во всем приложении и должна нормально работать, если это содержимое имеет кодировку utf-8.

Ruby 1.8 просто игнорировал бы заголовок #encoding и продолжал бы нормально работать.

Это очень простой подход, но я считаю, что это стоит попробовать!

...