# \[ANN\] main-2.1.0

**URL:** <https://rubytalk.org/t/ann-main-2-1-0/41527>\
**Category:** ruby-talk\
**Created:** [20 October 2007 16:55 UTC](https://rubytalk.org/t/ann-main-2-1-0/41527 "2007-10-20T16:55:39Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![a11](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/a11/32/8169_2.png) [@a11](https://rubytalk.org/u/a11)\
**Post date:** [20 October 2007 16:55 UTC](https://rubytalk.org/t/ann-main-2-1-0/41527/1 "2007-10-20T16:55:39Z")

</div>

NAME  
&nbsp;&nbsp;&nbsp;main.rb

SYNOPSIS  
&nbsp;&nbsp;&nbsp;a class factory and dsl for generating command line programs real quick

URI  
&nbsp;&nbsp;&nbsp;[http://rubyforge.org/projects/codeforpeople/](http://rubyforge.org/projects/codeforpeople/)  
&nbsp;&nbsp;&nbsp;[http://codeforpeople.com/lib/ruby/](http://codeforpeople.com/lib/ruby/)

INSTALL  
&nbsp;&nbsp;&nbsp;gem install main

HISTORY  
&nbsp;&nbsp;&nbsp;2.1.0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- added custom error handling dsl for parameters, this includes the ability  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to prepend, append, or replace the standard error handlers:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'main'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument 'x' do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error :before do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'this fires \*before\* normal error handling using #instance\_eval...'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'this fires \*instead of\* normal error handling using #instance\_eval...'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error :after do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'this fires \*after\* normal error handling using #instance\_eval...'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;run(){ p param['x'].given? }  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- added ability to exit at any time bypassing \*all\* error handling using  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'throw :exit, 42' where 42 is the desired exit status. throw without a  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;status simply exits with 0.

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- added 'help!' method which simply dumps out usage and exits

DESCRIPTION  
&nbsp;&nbsp;&nbsp;main.rb features the following:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- unification of option, argument, keyword, and environment parameter  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parsing  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- auto generation of usage and help messages  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- support for mode/sub-commands  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- io redirection support  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- logging hooks using ruby's built-in logging mechanism  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- intelligent error handling and exit codes  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- use as dsl or library for building Main objects  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- parsing user defined ARGV and ENV  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;- zero requirements for understanding the obtuse apis of \*any\* command  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;line option parsers

&nbsp;&nbsp;&nbsp;in short main.rb aims to drastically lower the barrier to writing uniform  
&nbsp;&nbsp;&nbsp;command line applications.

&nbsp;&nbsp;&nbsp;for instance, this program

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'main'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument 'foo'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option 'bar'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo']  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['bar']  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit\_success!  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;sets up a program which requires one argument, 'bar', and which may accept one  
&nbsp;&nbsp;&nbsp;command line switch, '--foo' in addition to the single option/mode which is always  
&nbsp;&nbsp;&nbsp;accepted and handled appropriately: 'help', '--help', '-h'. for the most  
&nbsp;&nbsp;&nbsp;part main.rb stays out of your command line namespace but insists that your  
&nbsp;&nbsp;&nbsp;application has at least a help mode/option.

&nbsp;&nbsp;&nbsp;main.rb supports sub-commands in a very simple way

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'main'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mode 'install' do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run() puts 'installing...' end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mode 'uninstall' do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run() puts 'uninstalling...' end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;which allows you a program called 'a.rb' to be invoked as

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ruby a.rb install

&nbsp;&nbsp;&nbsp;and

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ruby a.rb uninstall

&nbsp;&nbsp;&nbsp;for simple programs main.rb is a real time saver but it's for more complex  
&nbsp;&nbsp;&nbsp;applications where main.rb's unification of parameter parsing, class  
&nbsp;&nbsp;&nbsp;configuration dsl, and auto-generation of usage messages can really streamline  
&nbsp;&nbsp;&nbsp;command line application development. for example the following 'a.rb'  
&nbsp;&nbsp;&nbsp;program:

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'main'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument('foo'){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :int  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyword('bar'){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arity 2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :float  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;defaults 0.0, 1.0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option('foobar'){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument :optional  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description 'the foobar option is very handy'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;environment('BARFOO'){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :list\_of\_bool  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;synopsis 'export barfoo=value'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo'].value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['bar'].values  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foobar'].value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['BARFOO'].value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;when run with a command line of

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BARFOO=true,false,false ruby a.rb 42 bar=40 bar=2 --foobar=a

&nbsp;&nbsp;&nbsp;will produce

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;42  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[40.0, 2.0]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"a"  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[true, false, false]

&nbsp;&nbsp;&nbsp;while a command line of

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ruby a.rb --help

&nbsp;&nbsp;&nbsp;will produce

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NAME  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYNOPSIS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.rb foo [bar=bar] [options]+

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PARAMETERS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* foo [1 -\> int(foo)]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* bar=bar [2 ~\> float(bar=0.0,1.0)]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* --foobar=[foobar] [1 ~\> foobar]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the foobar option is very handy

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* --help, -h

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* export barfoo=value

&nbsp;&nbsp;&nbsp;and this shows how all of argument, keyword, option, and environment parsing  
&nbsp;&nbsp;&nbsp;can be declartively dealt with in a unified fashion - the dsl for all  
&nbsp;&nbsp;&nbsp;parameter types is the same - and how auto synopsis and usage generation saves  
&nbsp;&nbsp;&nbsp;keystrokes. the parameter synopsis is compact and can be read as

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* foo [1 -\> int(foo)]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'one argument will get processed via int(argument\_name)'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1 : one argument  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-\> : will get processed (the argument is required)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int(foo) : the cast is int, the arg name is foo

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* bar=bar [2 ~\> float(bar=0.0,1.0)]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'two keyword arguments might be processed via float(bar=0.0,1.0)'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2 : two arguments  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;~\> : might be processed (the argument is optional)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;float(bar=0.0,1.0) : the cast will be float, the default values are  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.0 and 1.0

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* --foobar=[foobar] [1 ~\> foobar]

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'one option with optional argument may be given directly'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* --help, -h

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;no synopsis, simple switch takes no args and is not required

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\* export barfoo=value

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a user defined synopsis

SAMPLES

&nbsp;&nbsp;&nbsp;\<========\< samples/a.rb \>========\>

&nbsp;&nbsp;&nbsp;~ \> cat samples/a.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'main'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ARGV.replace %w( 42 ) if ARGV.empty?

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument('foo'){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;required # this is the default  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :int # value cast to Fixnum  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;validate{|foo| foo == 42} # raises error in failure case  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description 'the foo param' # shown in --help  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo'].given?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo'].value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;~ \> ruby samples/a.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;true  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;42

&nbsp;&nbsp;&nbsp;~ \> ruby samples/a.rb --help

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NAME  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYNOPSIS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a.rb foo [options]+

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PARAMETERS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo (1 -\> int(foo))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the foo param  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--help, -h

&nbsp;&nbsp;&nbsp;\<========\< samples/b.rb \>========\>

&nbsp;&nbsp;&nbsp;~ \> cat samples/b.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'main'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ARGV.replace %w( 40 1 1 ) if ARGV.empty?

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument('foo'){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arity 3 # foo will given three times  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :int # value cast to Fixnum  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;validate{|foo| [40,1].include? foo} # raises error in failure case  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description 'the foo param' # shown in --help  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo'].given?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo'].values  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;~ \> ruby samples/b.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;true  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[40, 1, 1]

&nbsp;&nbsp;&nbsp;~ \> ruby samples/b.rb --help

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NAME  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYNOPSIS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;b.rb foo [options]+

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PARAMETERS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo (3 -\> int(foo))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the foo param  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--help, -h

&nbsp;&nbsp;&nbsp;\<========\< samples/c.rb \>========\>

&nbsp;&nbsp;&nbsp;~ \> cat samples/c.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'main'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ARGV.replace %w( foo=40 foo=2 bar=false ) if ARGV.empty?

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyword('foo'){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;required # by default keywords are not required  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arity 2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :float  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keyword('bar'){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :bool  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo'].given?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo'].values  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['bar'].given?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['bar'].value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;~ \> ruby samples/c.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;true  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[40.0, 2.0]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;true  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false

&nbsp;&nbsp;&nbsp;~ \> ruby samples/c.rb --help

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NAME  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYNOPSIS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c.rb foo=foo [bar=bar] [options]+

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PARAMETERS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo=foo (2 -\> float(foo))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bar=bar (1 ~\> bool(bar))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--help, -h

&nbsp;&nbsp;&nbsp;\<========\< samples/d.rb \>========\>

&nbsp;&nbsp;&nbsp;~ \> cat samples/d.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;require 'main'

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ARGV.replace %w( --foo=40 -f2 ) if ARGV.empty?

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Main {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option('foo', 'f'){  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;required # by default options are not required, we could use 'foo=foo'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# above as a shortcut  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument\_required  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arity 2  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :float  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option('bar=[bar]', 'b'){ # note shortcut syntax for optional args  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# argument\_optional # we could also use this method  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :bool  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default false  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo'].given?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['foo'].values  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['bar'].given?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p params['bar'].value  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;~ \> ruby samples/d.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;true  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[40.0, 2.0]  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nil  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;false

&nbsp;&nbsp;&nbsp;~ \> ruby samples/d.rb --help

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NAME  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d.rb

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SYNOPSIS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;d.rb --foo=foo [options]+

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PARAMETERS  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--foo=foo, -f (2 -\> float(foo))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--bar=[bar], -b (1 ~\> bool(bar=false))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--help, -h

DOCS  
&nbsp;&nbsp;&nbsp;test/main.rb

&nbsp;&nbsp;&nbsp;vim -o lib/main.rb lib/main/\*

API

&nbsp;&nbsp;&nbsp;Main {

> **···**
>
> ###########################################################################  
> &nbsp;&nbsp;&nbsp;# CLASS LEVEL API #  
> &nbsp;&nbsp;&nbsp;###########################################################################  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# the name of the program, auto-set and used in usage  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;program 'foo.rb'  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# a short description of program functionality, auto-set and used in usage  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;synopsis "foo.rb arg [options]+"  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# long description of program functionality, used in usage iff set  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description \<\<-hdoc  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this text will automatically be indented to the right level.
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;it should describe how the program works in detail  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hdoc  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# used in usage iff set  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;author 'ara.t.howard@gmail.com'  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# used in usage  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;version '0.0.42'  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# stdin/out/err can be anthing which responds to read/write or a string  
> &nbsp;&nbsp;&nbsp;# which will be opened as in the appropriate mode  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdin '/dev/null'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stdout '/dev/null'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stderr open('/dev/null', 'w')  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# the logger should be a Logger object, something 'write'-able, or a string  
> &nbsp;&nbsp;&nbsp;# which will be used to open the logger. the logger\_level specifies the  
> &nbsp;&nbsp;&nbsp;# initalize verbosity setting, the default is Logger::INFO  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger(( program + '.log' ))  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logger\_level Logger::DEBUG  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# you can configure exit codes. the defaults are shown  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit\_success # 0  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit\_failure # 1  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit\_warn # 42  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# the usage object is rather complex. by default it's an object which can  
> &nbsp;&nbsp;&nbsp;# be built up in sections using the  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# usage["BUGS"] = "something about bugs'  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# syntax to append sections onto the already pre-built usage message which  
> &nbsp;&nbsp;&nbsp;# contains program, synopsis, parameter descriptions and the like  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# however, you always replace the usage object wholesale with one of your  
> &nbsp;&nbsp;&nbsp;# chosing like so  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usage \<\<-txt  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my own usage message  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;txt
> 
> &nbsp;&nbsp;&nbsp;###########################################################################  
> &nbsp;&nbsp;&nbsp;# MODE API #  
> &nbsp;&nbsp;&nbsp;###########################################################################  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# modes are class factories that inherit from their parent class. they can  
> &nbsp;&nbsp;&nbsp;# be nested \*arbitrarily\* deep. usage messages are tailored for each mode.  
> &nbsp;&nbsp;&nbsp;# modes are, for the most part, independant classes but parameters are  
> &nbsp;&nbsp;&nbsp;# always a superset of the parent class - a mode accepts all of it's parents  
> &nbsp;&nbsp;&nbsp;# paramters \*plus\* and additional ones  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option 'inherited-option'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument 'inherited-argument'
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mode 'install' do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option 'force' do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description 'clobber existing installation'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inherited\_method()  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'installing...'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mode 'docs' do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description 'installs the docs'
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'installing docs...'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mode 'un-install' do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option 'force' do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description 'remove even if dependancies exist'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inherited\_method()  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'un-installing...'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'no mode yo?'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def inherited\_method  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'superclass\_method...'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;###########################################################################  
> &nbsp;&nbsp;&nbsp;# PARAMETER API #  
> &nbsp;&nbsp;&nbsp;###########################################################################  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# all the parameter types of argument|keyword|option|environment share this  
> &nbsp;&nbsp;&nbsp;# api. you must specify the type when the parameter method is used.  
> &nbsp;&nbsp;&nbsp;# alternatively used one of the shortcut methods  
> &nbsp;&nbsp;&nbsp;# argument|keyword|option|environment. in otherwords  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# parameter('foo'){ type :option }  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# is synonymous with  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# option('foo'){ }  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;option 'foo' {  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# required - whether this paramter must by supplied on the command line.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# note that you can create 'required' options with this keyword  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;required # or required true  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# argument\_required - applies only to options.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument\_required # argument :required  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# argument\_optional - applies only to options.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argument\_optional # argument :optional  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# cast - should be either a lambda taking one argument, or a symbol  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# designation one of the built in casts defined in Main::Cast. supported  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# types are :boolean|:integer|:float|:numeric|:string|:uri. built-in  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# casts can be abbreviated  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cast :int  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# validate - should be a lambda taking one argument and returning  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# true|false  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;validate{|int| int == 42}  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# synopsis - should be a concise characterization of the paramter. a  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# default synopsis is built automatically from the parameter. this  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# information is displayed in the usage message  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;synopsis '--foo'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# description - a longer description of the paramter. it appears in the  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# usage also.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;description 'a long description of foo'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# arity - indicates how many times the parameter should appear on the  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# command line. the default is one. negative arities are supported and  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# follow the same rules as ruby methods/procs.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;arity 2  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# default - you can provide a default value in case none is given. the  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# alias 'defaults' reads a bit nicer when you are giving a list of  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# defaults for paramters of \> 1 arity  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;defaults 40, 2  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# you can add custom per-parameter error handlers using the following  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error :before do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'this fires \*before\* normal error handling using #instance\_eval...'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'this fires \*instead of\* normal error handling using #instance\_eval...'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;error :after do  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts 'this fires \*after\* normal error handling using #instance\_eval...'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
> 
> &nbsp;&nbsp;&nbsp;###########################################################################  
> &nbsp;&nbsp;&nbsp;# INSTANCE LEVEL API #  
> &nbsp;&nbsp;&nbsp;###########################################################################  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;# you must define a run method. it is the only method you must define.  
> &nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def run  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# all parameters are available in the 'params' hash and via the alias  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 'param'. it can be indexed via string or symbol. the values are all  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# Main::Parameter objects  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo = params['foo']  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# the given? method indicates whether or not the parameter was given on  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# the commandline/environment, etc. in particular this will not be true  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# when a default value was specified but no parameter was given  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foo.given?  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# the list of all values can be retrieved via 'values'. note that this  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# is always an array.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p foo.values  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# the \_\_first\_\_ value can be retrieved via 'value'. note that this  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# never an array.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p foo.value  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# the methods debug|info|warn|error|fatal are delegated to the logger  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# object  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;info{ "this goes to the log" }  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# you can set the exit\_status at anytime. this status is used when  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# exiting the program. exceptions cause this to be ext\_failure if, and  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# only if, the current value was exit\_success. in otherwords an  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# un-caught exception always results in a failing exit\_status  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit\_status exit\_failure  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# a few shortcuts both set the exit\_status and exit the program.  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit\_success!  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit\_failure!  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit\_warn!  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end
> 
> &nbsp;&nbsp;&nbsp;}
> 
> enjoy.
> 
> a @ [http://codeforpeople.com/](http://codeforpeople.com/)  
> --  
> we can deny everything, except that we have the possibility of being better. simply reflect on that.  
> h.h. the 14th dalai lama
