Ответ 1
Подумайте о том, чтобы обновить рубин до последней версии 1.9.2.
Я нашел ошибку в 1.9.1, но не 1.9.2.
Мне кажется, что библиотека YAML, которая поставляется с ruby 1.9, является кодирующей-глухой.
Это означает, что при создании YAML он берет любую строку байтов и избегает любой последовательности байтов, которая не выводит чистый ASCII. Это хромает, но приемлемо.
Моя проблема в другом. При загрузке содержимого из дампа YAML.
В следующем примере я создаю строку UTF-8, выгружаю ее, она сбрасывается с типом !binary
. Когда я загружаю его, он имеет кодировку ASCII-8BIT. В конце примера я пытаюсь объединить как исходную, так и перезагруженную строку с другой строкой UTF-8. Последний будет терпеть неудачу с Encoding::CompatibilityError
.
require 'yaml'
s0 = "Iñtërnâtiônàlizætiøn"
y = s0.to_yaml
s1 = YAML::load y
puts s0 # => Iñtërnâtiônàlizætiøn
puts s0.encoding # => UTF-8
puts s1 # => Iñtërnâtiônàlizætiøn
puts s1.encoding # => ASCII-8BIT
puts y # => --- !binary |
# ScOxdMOrcm7DonRpw7Ruw6BsaXrDpnRpw7hu
puts "ñårƒ" + s0 # => ñårƒIñtërnâtiônàlizætiøn
puts "ñårƒ" + s1 # => Encoding::CompatibilityError: incompatible character encodings: UTF-8 and ASCII-8BIT
Я думаю, что это ясно, как это быстро приведет к неприятностям, когда вы имеете дело с каким-то источником YAML, содержащим вложенные хэши и массивы с листовыми строками.
В настоящее время у меня есть код, который пересекает все хэши и массивы и вызывает force_encoding
для каждой строки. Это, мягко говоря, неприглядно.
То, что я ищу прямо сейчас, - это способ сообщить YAML::load
, что любая строка, которая входит, должна рассматриваться как, и, следовательно, ее кодировка установлена в UTF-8.
В идеале, ruby YAML должен просто комментировать строки, которые он сбрасывает, с надлежащей кодировкой. Там проект Ya2YAML, который пытается сбросить безопасный YAML UTF-8. Я не уверен, насколько это далеко. Если кто-то играл с ним, я приветствую любые мысли.
Независимо от этого, у меня все еще есть эти дампы без какой-либо информации о кодировании. Хотя я знаю, что все они UTF-8.
Подумайте о том, чтобы обновить рубин до последней версии 1.9.2.
Я нашел ошибку в 1.9.1, но не 1.9.2.
YAML::ENGINE.yamler='psych'
'Résumé'.to_yaml # => "--- Résumé\n...\n"
Во-первых, текстовый файл, который вы пытаетесь прочитать, должен кодироваться в кодировке UTF-8 (это должен быть ваш файл YAML).
Затем добавьте эту строку в верхнюю часть вашего рубинового файла, хэш и все
# encoding: UTF-8
Это будет означать, что кодировка по умолчанию для всех строк будет UTF-8 и должна означать, что любой текст, который вы дампируете с помощью YAML.dump( "текст" ) или даже строковые литералы "как это", также должен быть закодирован UTF- 8, и все должно хорошо работать здесь.
Евгений ответ все еще показывает двоичный код для меня, но это работает ( "syck" instoad "psych" ):
YAML::ENGINE.yamler='syck'
'Résumé'.to_yaml # => "--- "R\xE9sum\xE9"
Я использую Ruby 1.9. Заметьте, что для моих целей, у которых есть специальные экраны, все в порядке - мне просто нужно было не показывать! Binary... для обычных слов. Слава богу .to_yaml снова работает для меня - привык использовать его все время. Как правильно надеть жизнь здравого смысла:)