Мне кажется, что библиотека 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.