保留从Ruby中的文件加载YAML的密钥顺序

时间:2011-05-10 21:06:13

标签: ruby load key yaml

我想保留从磁盘加载的YAML文件中的键的顺序,以某种方式处理并写回磁盘。

以下是在Ruby中加载YAML的基本示例(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()使用哪种数据结构的方法,例如alib的orderedmap

我没有运气在网上寻找解决方案。

3 个答案:

答案 0 :(得分:3)

使用Ruby 1.9.x.以前版本的Ruby不保留Hash密钥的顺序,但1.9确实如此。

答案 1 :(得分:2)

如果因为某种原因(就像我一样)使用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个对象,并将它们转换为{{ 1}}。我可以发一个问题。

答案 2 :(得分:1)

有人想出the same issue。有一颗宝石ordered hash。请注意,它不是哈希,它创建哈希的子类。你可以尝试一下,但如果你看到处理YAML的问题,那么你应该考虑升级到ruby1.9。