Matt - sanemat
Matt - sanemat

Reputation: 5618

Override configuration by yaml in my ruby application?

Override configuration by yaml from my ruby application. I want to override, but existing nil and false confuses me. My expectation is below (priorities: specific > 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

Then, actual:

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

Object#try and activesupport is better? hashie? My application is very small, I want to use hashie or small solution, if possible(not activesupport).

Or Do you know another solution?

Upvotes: 0

Views: 663

Answers (1)

Slartibartfast
Slartibartfast

Reputation: 8805

If YAML parsing failed, false is returned, so apparently specific wasn't parsed. Even if you fix this, you'll fail if default_company.yaml doesn't exist because default will be nil so default['name'] will fail with similar error.

Having said that, what you want is to merge there maps:

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

Upvotes: 1

Related Questions