Subject: ANNOUNCE: New perl5 Argv Options Parser
From: [email-masked] (Uri Guttman)
Date: 25 May 1995 10:57:19 GMT
Newsgroups: comp.lang.perl.announce,comp.lang.perl.misc,comp.lang.perl

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-masked]

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