Ruby:从另一个动态构造哈希

时间:2015-03-31 20:46:07

标签: ruby

给定一个带有样本值的yaml文件,我需要迭代它并构建另一个通过交互式控制台步骤编辑一些值。这是我正在尝试的代码。

require 'yaml'
require 'awesome_print'

def set_globals
  @defaults = YAML.load_file('config.example.yml')
  @globals = {}    
  @defaults.each do |k, v|
    set_value k, v, []
  end
end

def set_value k, v, chain
  if v['wtf_kind'] && v['wtf_kind'] == 'string'
    set_key chain.push(k), 'random' #this should trigger the console session
  else
    set_value v.first.first, v.first.last, chain.push(k)
  end
end

def set_key chain, v
  c = 0
  last = {}
  while c <= chain.size
    if c == chain.size
      @globals.store(chain[c], v)
    else 
      @globals.store(chain[c], {})
    end
    c += 1
  end
end

set_globals

ap @globals

config.example.yaml

global:
  redmine:
    site: 
      wtf_kind: string
      question: Redmine server url
      default: http://redmineaddress.com

    user: 
      wtf_kind: string
      question: Redmine username
      default: spitzname

    password: 
      wtf_kind: string
      question: Redmine password
      default: changeme

我得到的是:

{
     "global" => {},
    "redmine" => {},
       "site" => {},
          nil => "random"
}

虽然我希望得到:

{
  "global" => {
    "redmine" => {
       "site" => "random"
     }
   }
}

1 个答案:

答案 0 :(得分:1)

尝试使用简单的递归:

require 'yaml'
require 'awesome_print'

def travel(data)
  if data['wtf_kind'] == 'string'
    'random' #this should trigger the console session
  else 
    r = Hash.new
    data.each do |k, v|
      r[k] = travel(data[k])
    end
    r
  end
end

@data = YAML.load_file('example.yml')
ap travel(@data)

输出:

{
"global" => {
    "redmine" => {
        "site" => "random",
        "user" => "random",
    "password" => "random"
    }
}
}