Сохранить порядок ключей загрузки YAML из файла в Ruby - PullRequest
4 голосов
/ 11 мая 2011

Я хочу сохранить порядок ключей в файле YAML, загруженном с диска, обработанным каким-либо образом и записанным обратно на диск.

Вот базовый пример загрузки YAML в Ruby (v1.8.7):

require 'yaml'

configuration = nil
File.open('configuration.yaml', 'r') do |file|
  configuration = YAML::load(file)
  # at this point configuration is a hash with keys in an undefined order
end

# process configuration in some way

File.open('output.yaml', 'w+') do |file|
  YAML::dump(configuration, file)
end

К сожалению, это разрушит порядок ключей в configuration.yaml после построения хеша. Я не могу найти способ контролировать, какая структура данных используется YAML::load(), например алиб orderedmap.

Мне не повезло, что я искал решение в сети.

Ответы [ 3 ]

3 голосов
/ 11 мая 2011

Используйте Ruby 1.9.x. Предыдущая версия Ruby не сохраняет порядок ключей хеша, но 1.9 сохраняет.

2 голосов
/ 11 октября 2011

Если вы застряли на 1.8.7 по какой-либо причине (как и я), я прибегнул к использованию active_support/ordered_hash. Я знаю, что activesupport кажется большим включением, но в более поздних версиях его рефакторинг привел к тому, что вам в значительной степени требуется только та часть, которая вам нужна, в файле, а остальное исключено. Просто gem install activesupport и включите его, как показано ниже. Кроме того, в вашем файле YAML обязательно используйте объявление !! omap (и массив хэшей). Пример времени!

# config.yml #

months: !!omap
  - january: enero
  - february: febrero
  - march: marzo
  - april: abril
  - may: mayo

Вот как выглядит этот Ruby.

# loader.rb #

require 'yaml'
require 'active_support/ordered_hash'

# Load up the file into a Hash
config = File.open('config.yml','r') { |f| YAML::load f }

# So long as you specified an !!omap, this is actually a
# YAML::PrivateClass, an array of Hashes
puts config['months'].class

# Parse through its value attribute, stick results in an OrderedHash,
# and reassign it to our hash
ordered = ActiveSupport::OrderedHash.new
config['months'].value.each { |m| ordered[m.keys.first] = m.values.first }
config['months'] = ordered

Я ищу решение, которое позволило бы мне рекурсивно копаться в Hash, загруженном из файла .yml, искать эти YAML::PrivateClass объекты и преобразовывать их в ActiveSupport::OrderedHash. Я могу опубликовать вопрос по этому вопросу.

1 голос
/ 12 мая 2011

Кто-то придумал такой же вопрос . Существует хем упорядоченный хэш . Обратите внимание, что это не хеш, он создает подкласс хеша. Вы можете попробовать, но если вы столкнулись с проблемой, связанной с YAML, вам следует рассмотреть возможность обновления до ruby1.9.

...