Мне кажется, что библиотека YAML, которая поставлется с рубиновыми 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.
Идеально, YAML рубина должен просто аннотировать строки, которые он выводит с надлежащим кодированием. Существует проект Ya2YAML, который пытается вывести безопасный YAML UTF-8. Я не уверен, как далеко вдоль него. Если кто-либо играл с ним, я приветствую любые мысли.
Независимо от этого у меня все еще есть эти дампы без любой информации о кодировании для контакта с. Хотя я знаю, что они - весь UTF-8.
Во-первых, текстовый файл, который вы пытаетесь прочитать, должен быть в кодировке UTF-8 (это должен быть ваш файл YAML).
Затем добавьте эту строку в начало вашего рубинового файла, хеша и всего остального.
# encoding: UTF-8
Это будет означать, что кодировка по умолчанию для всех строк будет UTF-8, и это должно означать, что любой текст, который вы сбрасываете с помощью YAML.dump ( 'text') или даже строковые литералы 'like this' также должны быть в кодировке UTF-8, и с этого момента все они должны работать нормально.