Path: usenet.cis.ufl.edu!usenet.eel.ufl.edu!gatech!news.sprintlink.net!psgrain!nntp.teleport.com!usenet
From: [email protected] (Uri Guttman)
Newsgroups: comp.lang.perl.announce,comp.lang.perl.misc,comp.lang.perl
Subject: ANNOUNCE: New perl5 Argv Options Parser
Date: 25 May 1995 10:57:19 GMT
Organization: TerraNet, Inc., Boston, MA, USA
Lines: 246
Approved: [email protected] (comp.lang.perl.announce)
Message-ID: <[email protected]>
Reply-To: [email protected]
NNTP-Posting-Host: linda.teleport.com
Xref: usenet.cis.ufl.edu comp.lang.perl.announce:15 comp.lang.perl.misc:159 comp.lang.perl:50543

This is an announcement for alpha versions of two new perl5 packages, an
argv options parser and a ref tree printer. This document will briefly
describe these two packages. More documentation is in the works.


I have always been disappointed in the limitations of the typical getopt
argv parsers (in C and perl). I developed this package to allow for ease
of use and extensibility. I needed perl5 refs to make this happen.

This options parser is called Argv and its file is Argv.pl. It is an
attribute based system which describes each option, its arguments and
alowed values. It is very easy to use but very powerful and flexible. In
its simplest form it can behave like getopt. A more detailed description
follows below.

The ref tree printer is called Dump_tree and is in the file
Dump_tree.pl. It takes a variable name string and a ref value and prints
a legal perl assignment statement to a scalar with that name and with
the value of the ref tree. It was developed to dump the option
descriptions used in Argv and should be useful for debugging any program
using complex ref trees.

I am looking for alpha testers for these two packages. They work well
but need harder real-world testing. Here are some of the things I am
looking for:

       Bugs and fixes          (there are none, of course :-)
       Better coding           (Impossible!! :-)
       More features
       Speed ups
       Better packaging/modules
       Better behavior control
               (passing in the 3 extra args is kludgy and more control
                values need to be created)
       Any other comments and feedback
       Money                   (send it to the name at the top of the list)

Things to do:

       More and better documentation (in pod?)
       Code commenting         (none so far!!)
       Debug tracing           (just some random commented out prints)
       More features           (more file tests, scalar tests)
       Better behavior control

All interested parties should email me and I will email a shar of 4
files:
       argv.doc        Documentation (this file and hopefully updated)
       Argv.pl         Source of Argv package
       Dump_tree.pl    Source of Dump_tree package
       opt.pl          A test of Argv and Dump_tree

Send email to:

       [email protected]

When these pass muster I will post the sources. I hope (at least for
Argv) that they will be popular and become part of the perl5 distribution.


The Argv package is a replacement for the Getopt package that parses
@ARGV for options and sets variables to the options values. It has one
entry point called Parse which takes 4 arguments.  The first argument is
required and it is a ref list of hashes. Each hash is a set of
attributes (hash keys) and values which describe an option. The other 3
arguments are optional and control the behavior of Argv. To set some and
not the others, pass in undef for the arguments you want to leave
out. This behavior control mechanism needs work. I am leaning towards a
second argument which is another hash ref with each control value having
a key/value pair.

       Arg 2:  Environment variable name to parse for options
               (no default)

       Arg 3:  Prefix for long option names (default '-')

       Arg 4   Argument to end option option processing (default '--')

Argv options can be one of 4 types:

       Boolean options can be only set or unset and are guaranteed to
       have a value of 0 or 1. They are stored into a scalar variables.
       Boolean options can be bundled ( e.g. -abc ), inverted (-a is 0,
       default is 1), and a 'no' prefix can be used on long boolean
       option names.

       Scalar options must have 1 argument and they are stored in
       scalar variables. Scalar arguments can be attached (-I/dir1) or
       loose. A scalar option short name can be at the end of a bundled
       set of boolean options and its argument can be attached or loose
       ( -abcI/dir1 -abcI /dir1 ).

       Multi-value scalar options have the same behavior as scalar
       options but can appear multiple times in @ARGV. They are stored
       in array variables. The most well known use is for multiple
       include paths ( e.g. -I/dir1 -I/dir2 ).

       Array options must have the requested number of arguments and
       are stored in array variables.

       The argv options list should be assigned in BEGIN and
       Argv::Parse should also be called there.

       Each option must have either a short or long name attribute (or
       both). It is the ONLY required attribute so a simple set of
       boolean options can described and parsed in this way:

BEGIN {
       $argv_opts = [
                       { 'short' => 'a' },
                       { 'short' => 'b' },
                       { 'short' => 'c' },
       ] ;

       &Argv::Parse( $argv_opts ) ;
}

       This will set variables $opt_a, $opt_b, $opt_c to 1 if set or 0
       by default.

       If an option has a long name then it is used for the
       suffix for variable name instead of the short name ($opt_long).
       The variable name can be set with the 'var' attribute. Then
       there is no 'opt' prefix to the name.

       $argv_opts = [
                       { 'short' => 'a',       # value in $opt_a
                       },
                       { 'short' => 'b',       # value in $opt_bbb
                         'long' => 'bbb',
                       },
                       { 'short' => 'c',       # value in $c_option
                         'long' => 'ccc',
                         'var' => 'c_option',
                       },
       ] ;

       The 'count' and 'multi' options control the type of the option.

       $argv_opts = [
                       { 'short' => 'a',       # No count: Boolean
                       },
                       { 'short' => 'b',       # count = 1
                         'long' => 'bbb',      # scalar option
                         'count => 1,          # value in $opt_bbb
                       },
                       { 'short' => 'c',       # count = 1, multi = 1
                         'long' => 'ccc',
                         'var' => 'c_option',  # values in @c_option
                         'count => 1,
                         'multi' => 1,
                       },
                       { 'short' => 'd',       # count = 3
                         'long' => 'ddd',
                         'var' => 'd_vals',    # 3 values in @d_vals
                         'count => 3,
                       },
       ] ;

For more examples see the file opt.pl. All of the attributes are used in
some way (though some are commented out). Those perl hackers can stuy
the code for exact behavior. More documentation is forthcoming.

These are the currently supported attributes and brief descriptions.

NOTES:  1 is used for boolean attributes
       <text> is any text string
       <int> is an integer
       <scalar> is any scalar value
       <array> is an array ref e.g. [ 1, 2 ]
       <hash> is a hash ref e.g. { 'x' => 1, 'y' => 2 }
       <test> is a file test name ( plain, dir, symlink, block, char )

These attributes control the options parsed in @ARGV and the name of the
option variable:

       short   => <text>       Short name of option (length == 1)

       long    => <text>       Long name of option

       var     => <text>       Name of option variable
                               Default is opt_{long | short}

These attributes control the type of an option:

       count   => <int>        Count of arguments for option
                                       Count undefined -> boolean option
                                       Count == 1 -> scalar option
                                       Count > 1 -> array option

       multi   => 1            Scalar opt is multivalued array

       subopt  => 1            Scalar option's value is parsed for
                               sub-options e.g. 'foo=3,bar'
                               sub opts are reparsed as long options

       required => 1           Scalar or array option is required

These attributes control the default value of an option:

       env     => <text>       Name of ENV variable for option value
                               If an array option, it is split on white
                               space

       default => <scalar> or <array>
                               Default value of (non-boolean) option

These attributes are used for usage and help:

       usage   => <text>       Usage text for option

       help    => <text>       Help text for option

       is_usage => 1           Option prints usage

       is_help => 1            Option prints help

These attributes check the validity of the option's values:

       sub     => <text>       Name of main:: sub to call for value checking
                               If used and found all other checking is
                               skipped

       is_int  => 1            Value must be an decimal integer

       is_hex => 1             Value must be a hex integer

       is_float => 1           Value must be an float

       file_is => <test>       Value must pass file test op

       range   => <array>      Scalar option's value must in range
                               array[0] <= arg <= array[1]

       set     => <array>      Scalar option's arg must be in set of values

       set_vals => <hash>      Scalar option's arg must be in set of
                               keys which are converted to values

       invert  => 1            Invert the boolean option value

       no      => 1            'no' prefix is allowed for boolean option

       mutex   => <text>       Options with same mutex name are
                               mutually exclusive