Case: Development environment log level is DEBUG while Production is INFO. I want to use every default log configuration and overwrite only level if environment == develoment.

Problem: first level configs can be over-written but not sub levels.

Consider Example Code:

#file: config.rb

default = Configuration.for('default'){
  log {
    file '/tmp/foo.log'
    level 'WARN'
    freq 'daily'

development = Configuration.for( 'development', default) {
  log {
    level 'DEBUG'

In main file, I use the above code like so

# main.rb

require 'config.rb'    
$CONFIG = Configuration.for $DEV_ENV # either ('default' || 'development')
p $CONFIG.log.freq

I get an method missing error:

`undefined method `freq' for #<Configuration:0x00000003a65d80> (NoMethodError)`

The only (ugly) solution i have is to point file and freq values back to default like so:

  log {
    file default.log.file
    level 'DEBUG'
    freq default.log.freq

EEWWW!! Nasty!

Any other suggestions? I've tried to implement something like this with SettingsLogic and Configatron too at no avail. There goes the three top configuration gems for Ruby. Do I need to make my own?? Is this really such an exotic example?

Would love your feedback or suggestions.

No correct solution


I was able to solve your problem with SettingsLogic and anchor labels in YAML.

My config file:

defaults: &defaults
  log: &logdefault
      file:  /tmp/foo.log
      level: WARN
      freq: daily

  <<: *defaults
      <<: *logdefault
      level: DEBUG

  <<: *defaults

  <<: *defaults

The trick is to store the defaults in an anchor label and re-use it, when you try to redefine a part of it. You need an anchor for each level.

You can use it as

require 'settingslogic'  #
class SettingsDEV < Settingslogic
  source "./application.yml"
  namespace 'development'
p SettingsDEV.log #{"file"=>"/tmp/foo.log", "level"=>"DEBUG", "freq"=>"daily"}

class SettingsProd < Settingslogic
  source "./application.yml"
  namespace 'production'
p SettingsProd.log  #{"file"=>"/tmp/foo.log", "level"=>"WARN", "freq"=>"daily"}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow