= configuration.rb
pure ruby scoped configuration files

== Description
configuration.rb provides a mechanism for configuring ruby programs with
ruby configuration files.  a configuration.rb file, for example
'config/app.rb', can be written simply as

  Configuration.for('app') {
    key 'value'
    foo 'bar'
    port 42
  }
  
and loaded via the normal ruby require/load mechanism

  Kernel.load 'config/app.rb'

or with a slightly augmented loading mechnanism which simply searches an
extra set of paths in *addition* to the standard ones

  Configuration.path = %w( config configuration )

  Configuration.load 'app'

configurations are completely open

  Configuration.for('app') {
    object_id 'very open'
  }

support arbitrarily nested values

  Configuration.for('app') {
    a { b { c { d 42 } } }
  }

  c = Configuration.for 'app'

  p c.a.b.c.d #=> 42

allow POLS scoped lookup of vars

  Configuration.for('config') {
    outer 'bar'

    inner {
      value 42
    }
  }

  c = Configuration.for 'config'

  p c.outer       #=> 'bar'
  p c.inner.value #=> 42
  p c.inner.outer #=> 'bar'

allow default values

  default = Configuration.for( 'default' ) {
    a 1
    b 2
  }

  c = Configuration.for( 'config', default ) {
   a 10
  }

  p c.a     #=> 10
  p c.b     #=> 2

and not a whole lot else - configuration.rb is s very small library
consisting of one file and < 150 loc

== Samples

=== samples/a.rb
  ~ > cat samples/a.rb

    #
    # basic usage is quite, simple, load the config and use it's values.  the
    # config syntax is fairly obvious, i think, but note that it *is* ruby and any
    # ruby can be included.  also note that each config is named, allowing
    # multiple configs to be places in one file
    #
      require 'configuration'

      c = Configuration.load 'a'

      p c.a + c.b - c.c

  ~ > ruby samples/a.rb

    42


=== samples/b.rb
  ~ > cat samples/b.rb

    #
    # configuration.rb supports a very natural nesting syntax.  note how values
    # are scoped in a POLS fashion
    #
      require 'configuration'

      c = Configuration.for 'b'

      p c.www.url
      p c.db.url
      p c.mail.url

  ~ > ruby samples/b.rb

    "http://codeforpeople.com:80"
    "db://codeforpeople.com:5342"
    "mail://gmail.com:25"


=== samples/c.rb
  ~ > cat samples/c.rb

    #
    # configuration.rb let's you keep code very dry.
    #

      require 'configuration'

      Configuration.load 'c'

      p Configuration.for('development').db
      p Configuration.for('production').db
      p Configuration.for('testing').db

  ~ > ruby samples/c.rb

    "db/development"
    "db/production"
    "db/testing"


=== samples/d.rb
  ~ > cat samples/d.rb

    #
    # configuration.rb makes use of an external blank slate dsl, this means that
    # you Configuration objects do, in fact, have all built-in ruby methods such
    # as #inspect, etc, *unless* you configure over the top of them.  the effect
    # is a configuration object that behaves like a nice ruby object, but which
    # allows *any* key to be configured
    #
      require 'configuration'

      c = Configuration.for 'd'

      p c.object_id
      p c.inspect
      p c.p

  ~ > ruby samples/d.rb

    config/d.rb:2:in `object_id': wrong number of arguments (1 for 0) (ArgumentError)
      from config/d.rb:2
      from ./lib/configuration.rb:159:in `instance_eval'
      from ./lib/configuration.rb:159:in `call'
      from ./lib/configuration.rb:159:in `method_missing'
      from ./lib/configuration.rb:105:in `evaluate'
      from ./lib/configuration.rb:68:in `initialize'
      from ./lib/configuration.rb:29:in `new'
      from ./lib/configuration.rb:29:in `for'
      from config/d.rb:1
      from ./lib/configuration.rb:53:in `load'
      from ./lib/configuration.rb:53:in `load'
      from ./lib/configuration.rb:31:in `for'
      from samples/d.rb:10


=== samples/e.rb
  ~ > cat samples/e.rb

    #
    # configuration.rb uses a totally clean slate dsl for the block.  if you need
    # to access base Object methods you can do this
    #

      require 'configuration'

      c = Configuration.for 'e'

      p c.foo
      p c.bar
      p c.foobar

  ~ > ruby samples/e.rb

    42
    "forty-two"
    42.0

=== samples/f.rb
  ~ > cat samples/f.rb

    #
    # configuration.rb let's you inherit values from another configuration.
    # Like this, you keep your code very dry.
    #

      require 'configuration'

      Configuration.load 'f'

      p c.a
      p c.b

  ~ > ruby samples/f.rb

    10
    2


== Author
ara.t.howard@gmail.com
