保留从Ruby中的文件加载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

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

如果你因为任何原因(比如我)而使用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 

我正在寻找一种解决方案,允许我递归地挖掘从.yml文件加载的Hash ,查找那些YAML::PrivateClass对象,并将它们转换为ActiveSupport::OrderedHash 。 我可以发一个问题。

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

有人想出了同样的问题 。 有一个gem有序哈希 。 请注意,它不是哈希,它创建哈希的子类。 你可以尝试一下,但是如果你看到处理YAML的问题,那么你应该考虑升级到ruby1.9。