Nathaniel Talbott <nathaniel / talbott.ws> wrote in message news:<380B42FA-3E16-11D8-9233-000A95CD7A8E / talbott.ws>...
> On Jan 3, 2004, at 06:51, GGarramuno wrote:
> 
> 
> A lot of those things are provided by the Ruby package optparse (which 
> I've used with great effect), and I was wondering if you could compare 
> optparse with Getopt-Declare; perhaps Nobu will add the missing 
> features :-)

I can compare the features, most likely.  But the first thing that
quickly turns me off against it is how parameters are passed,
inefficiently one at a time.


Compare that, to the simplicity and elegance of perl's
Getopt::Declare.


For a simple example:

$args = new Getopt::Declare (<<'EOPARAM');

============================================================
   Required parameter:

   -in <infile>         Input file [required]

   ------------------------------------------------------------

   Optional parameters:

   (The first two are mutually exclusive) [mutex: -r -p]

   -r[and[om]]          Output in random order
   -p[erm[ute]]         Output all permutations

   ---------------------------------------------------

   -out <outfile>               Optional output file

   ------------------------------------------------------------
   Note: this program is known to run very slowly of files with
   long individual lines.
   ============================================================
EOPARAM


The beauty of the system is that the syntax definition can almost
looks like the help itself (from which a default -h flag printout is
extracted), so it is very easy to understand, even for newbies who
never read the docs to the module.
You just need to recall anything within [] is optional or a special
command to the engine, while {} is code, etc.


For a more complex case (involving complex switches, embedded code,
multiple file parsing, ranges, arrays, etc.), look at this one:



$args = new Getopt::Declare <<'EOARGS';
($0 version $VERSION)
General options:

        -e <f:i>..<t:i> Set expansion factor to specified range
                        [requires: <file>]
                                { print "k = [$f..$t]\n"; }

        -e [<k:n>...]   Set expansion factor to <k> (or 2 by default)
                        [required]
                                { @k = (2) unless @k;
                                  print "k = [", join(',', @k), "]\n";
}


        -b <blen:i>     Use byte length of <blen> 
                        [excludes: -a +c]
                                { print "byte len: $blen\n"; }

        <file>...       Process files [required] [implies: -a]
                                { print "files: \@file\n"; }

        -a [<N:n>]      Process all data [except item <N>]
                                { print "proc all\n"; print "except
$N\n" if $N; }

        -fab            The fabulous option (is always required :-)
                        [required]
                                { defer { print "fabulous!\n" } }

File creation options:

        +c <file>       Create file [mutex: +c -a]
                                { print "create: $file\n"; }

        +d <file>       Duplicate file [implies: -a and -b 8]
                        This is a second line
                                { print "dup (+d) $file\n"; }
        --dup <file>    [ditto] (long form)
#                               { print "dup (--dup) $file\n"; }

        -how <N:i>      Set height to <N>       [repeatable]

Garbling options:

        -g [<seed:i>]   Garble output with optional seed [requires:
+c]
                                { print "garbling with $seed\n"; }
        -i              Case insensitive garbling [required]
                                { print "insensitive\n"; }
        -s              Case sensitive garbling 
        -w              WaReZ m0De 6aRBL1N6 

        [mutex: -i -s -w]
EOARGS


The time it would take me to write something like that in other getopt
parsers, I'd get frustrated.  It's probably not an issue if you write
command-line tools once in a while, but if you write many of them
every now and then (or expect some program to keep adding complex
switches), it makes sense to use something like Getopt::Declare.

All flags, eventually end up being stored in a public hash of the
object, to extract them later, of course.