在我的ruby应用程序中覆盖yaml的配置?

时间:2013-07-09 00:33:58

标签: ruby configuration yaml

从我的ruby应用程序覆盖yaml的配置。我想覆盖,但现有的nil和false让我困惑。我的期望值低于(优先级:具体> default_company> default_base):

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

对象#Try和activesupport更好? HASHIE?我的应用程序非常小,如果可能的话,我想使用hashie或小解决方案(不是activesupport)。

或者你知道另一种解决方案吗?

1 个答案:

答案 0 :(得分:1)

如果YAML解析失败,则返回false,因此显然没有解析specific。即使您已经解决此问题,如果default_company.yaml不存在,您也会失败,因为defaultnil,因此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