2013-07-09 34 views
0

從我的ruby應用程序覆蓋yaml的配置。我想重寫,但現有的零和錯誤混淆了我。我的期望是低於(優先:具體> default_company> default_base):在我的紅寶石應用程序中通過yaml覆蓋配置?

default_base = YAML.safe_load_file('default_base.yaml') 
default = YAML.safe_load_file('default_company.yaml') if File.exist?('default_company.yaml') 
specific = YAML.safe_load_file('specific.yaml') 

#expect 
name = specific['name'] || default['name'] || default_base['name'] 
#=> my name 
company = specific['company'] || default['company'] || default_base['company'] 
#=> my company 
port = specific['port'] || default['port'] || default_base['port'] 
#=> 80 

default_base.yaml (in gem) 
    name: 
    example 
    company: 
    example 
    port: 
    80 

default_company.yaml(in user app) 
    name: 
    my company 
    company: 
    my company 

specific.yaml (in user app) 
    name: 
    my name 

然後,實際:

specific['company'] 
NoMethodError: undefined method `[]' for false:FalseClass 
specific.try(:company) 
NoMethodError: undefined method `try' for false:FalseClass 

對象#嘗試的ActiveSupport是更好? HASHIE?我的應用程序非常小,如果可能的話,我想使用hashie或小型解決方案(不支持activesupport)。

或者您是否知道另一種解決方案?

回答

1

如果YAML解析失敗,則返回false,因此顯然specific未被解析。即使您修復此問題,如果default_company.yaml不存在,您將失敗,因爲default將爲nil,因此default['name']將失敗,並出現類似錯誤。

說了這麼多,你想要的是合併有地圖:

if default 
    default_base.merge! default 
end 
if specific 
    default_base.merge! specific 
end 

dafault_base['name'] 
#=> my name 

default_base['company'] 
#=> my company 

default_base['port'] 
#=> 80 
+0

謝謝!在這種情況下,我明白了:default || = {};具體|| = {}; default_base.merge(默認).merge(特定) – sanemat