2015-03-31 50 views
0

给定一个带有样本值的yaml文件,我需要遍历它并构造另一个在交互控制台步骤中编辑一些值。这是我正在尝试的代码。Ruby:从另一个动态构造一个散列

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

尝试使用简单的递归:

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" 
    } 
} 
} 
+0

谢谢,就像一个魅力和真干净! – sekipaolo 2015-03-31 21:34:22

相关问题