Application Context

Every application needs configuration and app-ctx provides a concise way of
doing it.

For all applications (you are not a mouseclicker, are u?), once in a while
you need to supply some configuration values to overrule the built-in
defaults. The app-ctx gem does unify and organize built-in constants,
config files and commandline option with a clearly defined priority, from
low to high:

    - procedural: App::Config#set_default_values
    - default values YAML file from next to the $0 script
    - user supplied configuration file, eg.: --config=/tmp/foo.yml
    - command line options and flags: --foo --bar=foo

But for your application it is of no interesst from where the values are
coming: command line option: "--port=1234", a user configuration file or
from the applications built-in default values. Therefor +app-ctx+ combines
value settings from various sources into a single configuration hash.

basically you have two ways to use it:

    require 'app-ctx' # of course,and than...

1. closures (see examples/run_with_block.rb) 

    App::ctx.run do |context| ... end

or 2. with a mainclass(see examples/run_with_class.rb)

    App::ctx.run YourClassHere

The context object provides:

   values:          the combined key and value settings
   argv:            remaining argument(not the options) of the command line
   defaults_path:   full path to the defaults file

for the second case(with a mainclass) an application instance of this class
is created. The first argument is than taken as method name and executed,
again with a context oject provided: 

    prompt: ruby example/run_with_class show 

will result in the :show method beeing called:

    context = Config.new...
    ...
    app = Simple.new...
    app.show(context)

Conversions

Commandline options are strings only, but sometimes you need strongly typed
primitive values. +app-ctx+ does automatically convert integer and float
values, see "examples/conversions.rb" for:

    prompt: ./examples/conversions.rb             
    {:i=>23, :f=>3.14}
    typeof 'i': Fixnum
    typeof 'f': Float
    prompt: ./examples/conversions.rb -i=17 -f=2.12
    {:i=>17, :f=>2.12}
    typeof 'i': Fixnum
    typeof 'f': Float
    prompt: ./examples/conversions.rb -i=i -f=f
    {:i=>"i", :f=>"f"}
    typeof 'i': String
    typeof 'f': String

Flags/Boolean values

Flags(options without values) are converted to boolean values, see
examples/boolean.rb:

    dluesebrink dl-mbook ruby/app-ctx: r examples/boolean.rb 
    {:bool=>false}
    typeof 'bool': FalseClass
    dluesebrink dl-mbook ruby/app-ctx: r examples/boolean.rb  --bool
    {:bool=>true}
    typeof 'bool': TrueClass

Ruby Conversions

When Fixnum, Float and boolean conversion are not enough, as a last resort,
you can use ruby code directly for evaluation of option values. Replacing
'=' with ':' results in assigning the ruby evaluation value to the key, see
examples/ruby_conv.rb:

    prompt: examples/ruby_conv.rb
    {:r=>1..10, :a=>[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}
    typeof 'r': Range
    typeof 'a': Array
    prompt: ./examples/ruby_conv.rb -r:2..3 -a:'(-1..1).to_a'
    {:r=>2..3, :a=>[-1, 0, 1]}
    typeof 'r': Range
    typeof 'a': Array
    prompt: ./examples/ruby_conv.rb -r:2..3 -a:\(-1..1\).to_a
    {:r=>2..3, :a=>[-1, 0, 1]}
    typeof 'r': Range
    typeof 'a': Array

# vim: set tw=80 syntax=txt nosmartindent: