Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

parsing lpr options with getopts

8 views
Skip to first unread message

Peter Steele

unread,
Oct 6, 1993, 4:56:53 PM10/6/93
to
The lpr command has two options that doesn't seem to be "compatible"
with getopts, name the -#<copies> option and the -i[count] option.
The problem with -# is obvious; a call to &Getopts would try to
build a variable called $opt_#, which isn't a valid variable. The
-i option is a problem because its argument is optional. Getopts
has no provision for this. You either have to use

&Getopts("i");

or

&Getopts("i:");

I've got a hack to solve the -# option, by going through @ARGS
and replacing -# with -N. This works well enough, although it's
not perfect. I can't think of anyway to handle the -i option
though, other than forcing it to have an argument. Any one have
any suggestions?

--
Peter Steele Unix Services Manager peter....@acadiau.ca
Acadia Univ., Wolfville, NS, Canada B0P 1X0 902-542-2201 Fax: 902-542-4364

Frank O'Carroll

unread,
Oct 6, 1993, 10:59:08 PM10/6/93
to
>From: pe...@dragon.acadiau.ca (Peter Steele)
>Subject: parsing lpr options with getopts
>Organization: Acadia University
>Date: Wed, 6 Oct 1993 20:56:53 GMT

>The lpr command has two options that doesn't seem to be "compatible"
>with getopts, name the -#<copies> option and the -i[count] option.
>The problem with -# is obvious; a call to &Getopts would try to
>build a variable called $opt_#, which isn't a valid variable.

I've always wondered why Getopts builds special variables instead of using
an associative array like
$opts{"i"}
or $opts{"#"}
That way, even keyword arguments like
$opts{"conv=ascii"}
or $opts{"foreground"}
might work.

Any reason why it's not implemented that way?

Frank O'Carroll
ocar...@mri.co.jp
ocar...@ss151.icot.or.jp
Tokyo

Peter Steele

unread,
Oct 7, 1993, 7:42:06 AM10/7/93
to
>>The lpr command has two options that doesn't seem to be "compatible"
>>with getopts, name the -#<copies> option and the -i[count] option.
>>The problem with -# is obvious; a call to &Getopts would try to
>>build a variable called $opt_#, which isn't a valid variable.

>I've always wondered why Getopts builds special variables instead of using
>an associative array like
> $opts{"i"}
>or $opts{"#"}
>That way, even keyword arguments like
> $opts{"conv=ascii"}
>or $opts{"foreground"}
>might work.

>Any reason why it's not implemented that way?

I can't see any reason at all. In fact, to solve my lpr arg problem
I modified getopts.pl as suggested above. It works great. It would
need a lot more work to handle things like $opts{"conv=ascii"}. Maybe
Getopts should take multiple regular expressions as patterns to match
each arg, so you could say Getopts("conv=.*","foreground","#[0-9]+").
Just a thought. In any case, here's my modified getopts that uses
an associative array instead of multiple variables:

;# getopts.pl, take 2 - an even better getopt.pl

;# Usage:
;# do Getopts('a:bc'); # -a takes arg. -b & -c not. Sets %opts as a
;# # side effect.

sub Getopts {
local($argumentative) = @_;
local(@args,$_,$first,$rest);
local($errs) = 0;
local($[) = 0;

@args = split( / */, $argumentative );
while(@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
($first,$rest) = ($1,$2);
$pos = index($argumentative,$first);
if($pos >= $[) {
if($args[$pos+1] eq ':') {
shift(@ARGV);
if($rest eq '') {
++$errs unless @ARGV;
$rest = shift(@ARGV);
}
$opts{"$first"} = $rest;
}
else {
$opts{"$first"} = 1;
if($rest eq '') {
shift(@ARGV);
}
else {
$ARGV[0] = "-$rest";
}
}
}
else {
print STDERR "Unknown option: $first\n";
++$errs;
if($rest ne '') {
$ARGV[0] = "-$rest";
}
else {
shift(@ARGV);
}
}
}
$errs == 0;

Larry Wall

unread,
Oct 7, 1993, 12:52:12 PM10/7/93
to
In article <OCARROLL.9...@ss151.icot.or.jp> ocar...@ss151.icot.or.jp writes:
: I've always wondered why Getopts builds special variables instead of using

: an associative array like
: $opts{"i"}
: or $opts{"#"}
: That way, even keyword arguments like
: $opts{"conv=ascii"}
: or $opts{"foreground"}
: might work.
:
: Any reason why it's not implemented that way?

Oh, laziness, impatience and hubris, I suppose. :-) Tom C's gonna be
working over the whole library at some point, so maybe we can get him
to fix up something. Maybe we need a new function, or perhaps we just
need to make it so that evaluating an existing function in a list
context would return an associative array value. It's certainly
cleaner to use an associative array, though a little less efficient in
certain ways.

On the other hand, perhaps the fascists in the crowd think we shouldn't
change a thing, since it imposes some standards on switch names. :-)

Larry

Alan Stebbens

unread,
Oct 7, 1993, 5:06:38 PM10/7/93
to
> >>The lpr command has two options that doesn't seem to be "compatible"
> >>with getopts, name the -#<copies> option and the -i[count] option.
> >>The problem with -# is obvious; a call to &Getopts would try to
> >>build a variable called $opt_#, which isn't a valid variable.
>
> I can't see any reason at all. In fact, to solve my lpr arg problem
> I modified getopts.pl as suggested above. It works great. It would
> need a lot more work to handle things like $opts{"conv=ascii"}. Maybe
> Getopts should take multiple regular expressions as patterns to match
> each arg, so you could say Getopts("conv=.*","foreground","#[0-9]+").
> Just a thought...

Ok. Here's *my* script to parse arguments; embedded man page at the
bottom. Try it and feel free to comment, improve, etc.

Alan
============================= cut here ===================================
#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 10/07/1993 21:04 UTC by ???@dokoka
# Source directory /fs.real/dokoka/home/aks/src/lang/perl/Lib/parseargs
#
# existing files will NOT be overwritten unless -c is specified
#
#
#
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 20351 -r--r--r-- parseargs.pl
# 554 -r--r--r-- Makefile
# 946 -rwxr-xr-x test.pl
# 113 -r-xr-xr-x test1
#
if test -r _shar_seq_.tmp; then
echo 'Must unpack archives in sequence!'
echo Please unpack part `cat _shar_seq_.tmp` next
exit 1
fi
# ============= parseargs.pl ==============
if test -f 'parseargs.pl' -a X"$1" != X"-c"; then
echo 'x - skipping parseargs.pl (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting parseargs.pl (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'parseargs.pl' &&
# ParseArgs.pl script for perl
'di';
'ig00';
#
# Author: Alan K. Stebbens <a...@hub.ucsb.edu>
# $Id: parseargs.pl,v 1.7 1993/09/11 02:19:12 aks Exp $
# See bottom of file for documentation.
X
$InitParseProgram = '
X Arg:while (length($_ = shift @ARGV)) {
X $arg = s/=(.*)// ? $1 : undef;
X while (/^-./) { # parse clustered switches
X ';
X
$FinishParseProgram = '
X last;
X }
X if (!index(\'-debug\',$_)) {
X $Debug = $arg || 1; next;
X }
X if (!index(\'-verbose\',$_)) {
X $Verbose = $arg || 1; next;
X }
X next Arg if /^-$/;
X last Arg unless /^-/;
X die "Bad arg: $_\n", $Usage;
X }
X unshift(@ARGV, $_) if length;
X ';
X
sub ParseOpts {
X local($i);
X local(@opts) = split(' ',shift);
X for ($i = $#opts + 1; $i > $[; $i--) {
X splice(@opts, $i, 0, ''); # insert null actions
X }
X &ParseArgs(@opts);
}
X
%ParseArgFlags = ( '<', 'ParseArgInFile',
X '>', 'ParseArgOutFile',
X '/', 'ParseArgDirectory',
X '.', 'ParseArgPlainFile',
X '!', 'ParseArgNewFile',
X '@', 'ParseArgsFromFile',
X '#', 'ParseNumberArgs',
X '~', 'ParseUserLogin',
X '(', 'ParseGroupName',
X '=', '',
X ':', '',
X '+', '',
X '*', '',
X );
X
$ParseArgFlags = join('',keys(%ParseArgFlags));
X
sub ParseArgs {
X local(@arglist) = @_; # argument list
X local($_);
X local($NoArg) = "Missing argument for option: ";
X if ($#arglist == $[) { # a single string?
X local(@lines) = split(/\n/,$arglist[0]);
X @arglist = ();
X foreach (@lines) { # parse strings into FLAG, ACTION pairs
X if (/^\s*(\S+)\s+(\S.*)$/) {
X push(@arglist,$1,$2);
X } elsif (/^\s*(\S+)/) {
X push(@arglist,$1,''); # default ACTION
X }
X }
X }
X local($parser,$x,$option,$flag,$action,$expr,$arg,$interp);
X $parser = $InitParseProgram;
X for ($x = 0; $x <= $#arglist; $x += 2) {
X $option = $arglist[$x];
X $action = $arglist[$x+1];
X length($option) || next; # ignore null options
X $action =~ s/\s*\#\s*$//; # remove any comments
X $action =~ s/\bARG\b/\$arg/g; # substitute
X $action =~ s/\bNEXT\b/next Arg/g;
X $action =~ s/\bLAST\b/last Arg/g;
X # check for --word, -word, +word, or _word w or w/o =
X if ($option =~ /^(--|-|\+|_)(\w+)(\W|)/) {
X $expr = "\t if (!index('$1$2',\$_)) {\n";
X if ($flag = $3) { # is there a flag char?
X die "$0: Unknown option flag: $flag\n"
X if !defined($ParseArgFlags{$flag});
X $interp = $ParseArgFlags{$flag};
X $arg = "\$arg = defined(\$arg) ? \$arg : shift \@ARGV"
X unless $flag eq '*';
X $arg .= " || die \"$NoArg $2\\n\", \$Usage" if $flag eq '=';
X $expr .= "\t\t".$arg.";\n";
X $expr .= "\t\t\$arg = \&".$interp."('$2',\$arg);\n" if $interp;
X $action = "\$opt_$2 = \$arg" unless $action;
X $expr .= "\t\t".$action.";\n";
X } else { # no flag char: -xyz
X $arg = $1 eq '--' ? 1 : $1 eq '-' ? 2 : $1 eq '+' ? 4 : 8;
X $action = "\$opt_$2 = $arg" unless $action;
X $expr .= "\t\t".$action.";\n";
X }
X $expr .= "\t\tnext Arg;\n";
X } elsif ($option =~ /^(\w)(\W)?/) { # how about single character option?
X $flag = $2;
X $expr = "\t if (s/^-$1/-/) {\n";
X if ($flag) { # assignment option?
X die "$0: Unknown option flag: $flag on option $option\n"
X if index($ParseArgFlags,$flag) < $[;
X $interp = $ParseArgFlags{$flag};
X $arg = "\$arg = " unless $flag eq '*';
X if ($flag eq '+' || $flag eq '*') { # sticky args?
X $expr = "\t if (s/^-$1(.*)/-/) {\n";
X $arg = "\$arg = length(\$1) ? \$1 : ";
X $arg .= 'undef' if $flag eq '*';
X }
X $arg .= "defined(\$arg) ? \$arg : shift \@ARGV"
X unless $flag eq '*';
X $arg .= " || die \"$NoArg $1\\n\", \$Usage"
X if $flag eq '=' || $flag eq '+';
X $expr .= "\t\t".$arg.";\n";
X $expr .= "\t\t\$arg = \&".$interp."(\$1,\$arg);\n" if $interp;
X $action = "\$opt_$1 = \$arg" unless $action;
X $expr .= "\t\t".$action.";\n" if $action;
X $expr .= "\t\tundef \$arg;\n";
X } else {
X $expr .= "\t\t\$opt_$1++;\n" unless $action;
X $expr .= "\t\t".$action.";\n" if $action;
X }
X $expr .= "\t\tnext;\n";
X } else { # use option as expr
X $expr = "\t if ($option) {\n";
X $expr .= "\t\t".$action.";\n" if $action;
X $expr .= "\t\tnext Arg;\n" unless $action =~ /\bnext\b/;
X }
X $parser .= $expr;
X $parser .= "\t }\n";
X }
X $parser .= $FinishParseProgram;
X print STDERR $parser
X if @ARGV && $ARGV[0] eq '-DEBUG_PARSER' && shift @ARGV;
X eval $parser;
X die $@ if $@;
}
X
# Reference this routine in an action if you want an option to
# insert arguments acquired by reading a file.
X
sub ParseArgsFromFile {
X local($opt,$file) = @_;
X open(FEXP,$file) || die "Can't open input: $file: $!\n";
X unshift(@ARGV, grep((chop, s/\s*\#.*$//, length > 0),<FEXP>));
X close FEXP;
}
X
sub ParseArgInFile {
X local($opt,$_) = @_;
X die "$0: File $_ cannot be read!\n" unless -r;
X open("FH_$opt","<$_") || die "$O: Cannot open $_ for input: $!\n";
X $_;
}
X
sub ParseArgOutFile {
X local($opt,$_) = @_;
X -e && ( -w || die "$0: File $_ cannot be written!\n" );
X open("FH_$opt",">$_") || die "$0: Cannot open $_ for output: $!\n";
X $_;
}
X
sub ParseArgDirectory {
X local($opt,$_) = @_;
X -e || die "$0: Directory $_ does not exist!\n";
X -d || die "$0: $_ is not a directory!\n";
X $_;
}
X
sub ParseArgPlainFile {
X local($opt,$_) = @_;
X -e || die "$0: File $_ does not exist!\n";
X -f || die "$0: File $_ is not a plain file!\n";
X $_;
}
X
sub ParseArgNewFile {
X local($opt,$_) = @_;
X ! -e || die "$0: File $_ already exists!\n";
X $_;
}
X
sub ParseNumberArgs {
X local($opt,$_) = @_;
X /^\d+$/ || die "$0: Option $opt $_ is not a number!\n";
X $_;
}
X
sub ParseUserLogin {
X local($opt,$_) = @_;
X /^\d+$/ ?
X $_ == (getpwuid($_))[$[+2] || die "$0: $_ is not a valid user id!\n"
X : $_ eq (getpwnam($_))[$[] || die "$0: $_ is not a valid login name!\n";
X $_;
}
X
sub ParseGroupName {
X local($opt,$_) = @_;
X /^\d+$/ ?
X $_ == (getgrgid($_))[$[+2] || die "$0: $_ is not a valid group id!\n"
X : $_ eq (getgrnam($_))[$[] || die "$0: $_ is not a valid group name!\n";
X $_;
}
X
1;
__END__
###############################################################
X # These next few lines are legal in both Perl and nroff.
X
.00; # finish .ig
X
'di \" finish diversion--previous line must be blank
.nr nl 0-1 \" fake up transition to first page again
.nr % 0 \" start at page 1
.rm ';
.\" Bullet Item
.de Bi
.TP 1i
.B \\h'.5i'\\$1
..
.TH PARSEARGS 3 "January 14, 1993"
.AT 3
.SH NAME
parseargs.pl - Parse the argument vector
.SH SYNOPSIS
.B require 'parseargs.pl'
.sp
.B &ParseOpts('FLAG1 FLAG2 ... FLAGn');
.sp
.B &ParseArgs('FLAG1', 'ACTION1', 'FLAG2', 'ACTION2', ...);
.sp
.nf
.na
.ft B
&ParseArgs(<<'EOF');
X FLAG1 ACTION1
X FLAG2 ACTION2
X ...
X FLAGn ACTIONn
EOF
.ft R
.ad
.fi
.SH DESCRIPTION
These subroutines parse the current command argument vector,
.BR @ARGV ,
for switches which match defined
.B FLAG
expressions, evaluating associated
.B ACTION
expressions.
.sp
The argument parsing stops on the first unhandled non-flag argument.
An error is reported on any unhandled flag arguments (\c
.BI -flag ).
.sp
There are two subroutines:
.BR ParseArgs ,
and
.BR ParseOpts .
The former is
more general and allows complete control over the flag strings and the
associated actions. The
.B ParseOpts
routine has a simpler interface,
with useful default actions for the specified flag strings.
.sp
In both routines, each
.B FLAG
is matched against the current argument,
and, if successful, the corresponding
.B ACTION
is evaluated, followed by
a
.BR next .
.B FLAG
can be a general Perl expression, or it can be one of
a special syntax (defined below), which is used to create a Perl
expression for testing.
.sp
Any argument not matching any of the test expressions causes an error.
When an error occurs, if the string
.B $Usage
is defined, it will be
printed after the error message.
.sp
.B ACTION
can be a general Perl expression, except that no embedded
newlines are permitted. An empty string, or action of
.B `#'
is considered to be a null action, for which useful defaults are
supplied.
.sp
Within
.BR ACTION ,
there are several strings which are translated to the appropriate
Perl expressions:
.sp
.TP .5i
.B ARG
evaluates to the argument of the switch
which selected the action.
.TP
.B NEXT
causes the parser to procede to the next argument.
.TP
.B LAST
causes the parser to complete argument processing; any string in
.B `$_'
will be unshifted back onto the front of
.BR @ARGV .
.sp
In the case of
.BR ParseOpts ,
all actions are provided by default.
.sp
As a convenience for Perl script writers (that is, myself :^), the
following flags and actions are supplied, after all other flags have
been tested:
.sp
.nf
.B \t-debug\t$DEBUG++
.B \t-verbose\t$VERBOSE++
.fi
.sp
Also, for the case of when arguments may be obtained by reading a file
passed as an argument itself, the user may reference the subroutine
.B &ParseArgsFromFile(\c
.IB ARG )
as an action, where
.I ARG
is the special
string recognized and substituted with an appropriate expression.
.sp
The syntax of
.B FLAG
is:
.TP .5i
(a) \fB(--|-|+|_)\fIWORD\fB[\fIF\fB]\fR
.sp
This syntax allows the various methods of setting switches to be
recognized, with an optional trailing flag character
.IR `F' ,
indicating how to handle the
argument, if any.
If there is no graphic character suffixed to the
.IR WORD ,
then the option accepts no arguments, and is set to 1 when supplied on
the command line.
.sp
The following graphic flag characters are recognized and provide for
interpretation of the arguments, when given. When an explicit user
action is given in conjunction with one of these flag characters, the
interpretation action is accomplished before the user action. When no
user action is given, the default variable,
.BI `$opt_ WORD' ,
is assigned the value of the argument.
.Bi `='
this flag accepts a required argument, either in the same word following an
equal sign (\c
.BR `=' ),
or in the next word of the argument vector. That is, both of these
argument types are valid:
.sp
.B \t-WORD=VALUE\t
and
.B \t-WORD VALUE
.sp
An omitted argument is an error with the \fB`='\fP flag character.
.Bi `:'
this flag character causes the option to take an
optional argument, not causing an error should it be omitted.
.Bi `<'
treat the argument as an input file,
causing an error if the file is non-existent or unreadable. The file is
opened for reading under the file handle
.BI FH_ WORD.
.Bi `>'
treat the argument as an output file,
causing an error if the file is not writable. The file is opened for
writing under the file handle
.BI FH_ WORD.
.Bi `/'
treat the argument as a directory, which must exist.
.Bi "`.'" "(a period)"
treat the argument as a plain file which must exist; if the file is a
directory, or a special file, then an error occurs. Symbolic links are
ok, if they point to a plain file.
.Bi `!'
treat the argument as a new, nonexistent file name. An error occurs if
the file already exists, in any form.
.Bi `#'
treat the argument as an integer, causing an error for any non-digits
found.
.Bi `~'
verify the argument as a valid user login name or numerical user id.
.Bi `('
treat the argument as a valid group name, or numerical group id.
.Bi `@'
treat the argument as a readable file, read the files contents, and
split the lines into the argument vector,
.BR @ARGV .
.IP "" .5i
The switches recognized by
.I (a)
may all be minimally abbreviated, as
the test expression used to recognize the switch is
.B `!index(FLAG,$_)'.
Thus, for the flag
.BR `-edit' ,
the options
.BR `-edit' ,
.BR `-edi' ,
.BR `-ed',
and
.B `-e'
will be recognized.
.sp
When designing switch names with abbreviation, care must be taken to
specify the longer abbreviations first, so they will not be masked
by shorter ones.
.sp
The default
.B ACTION
performed by a switch matching this style
.BR FLAG ,
is to set a Perl variable,
.BI $opt_ WORD,
to a `1', if no value was given, or to the argument supplied.
.sp
X The following are all examples of this syntax:
.sp
.B --list-all -edit +help -verbose _broadcast= _netmask=
.B -input< -output> -dir/ --user~ -file@ -count#
.sp
.TP .5i
(b) \fIC\fB[=:<>/.!#~(+*]\fR
.sp
In this syntax,
.B C
is a single character switch, which may be followed by one of the
previously documented flag characters, or one of the following two
additional ones:
.Bi `+'
This flag character causes the option to require an argument, which may
be given either juxtaposed with the option word itself, or on the
subsequent argument vector word.
.Bi `*'
This flag character causes the parser to optionally obtain an argument;
in this case, optionally means only if there are any characters
following the option, within the same argument word.
.IP "" .5i
Single character switches may be given separately, or may be clustered into
a single switch word. For example, the options
.B -l
and
.BR -t ,
may be given as:
.B -lt
or
.BR -tl .
.sp
The single character assignable options may require arguments, or
they may be optional. The argument syntax may be one of:
.sp
.nf
.B \t\fR(1)\fB `-O=arg'
.B \t\fR(2)\fB `-Oarg'
.B \t\fR(3)\fB `-O arg'
.fi
.sp
where
.B `-O'
is your favorite option. The argument flags
.B `='
and
.B `:'
indicate required or optional arguments which can only be assigned
via styles
.I (1)
and
.IR (3) .
The argument flags
.B `+'
and
.B `*'
also mean required and optional, respectively.
.B `+'
allows syntax style
.I (1)
or
.IR (3) ,
while
.B `*'
allows
.I only
syntax style
.IR (2) .
.sp
The following table should make this a little clearer:
.sp
.ta .5i +.5i +1i +1i +1i
.nf
.ft B
X Flag Argument? -O=arg -Oarg -O arg
.ft R
X ---- --------- ------ ----- ------
X \fB=\fP required ok no ok
X \fB:\fP optional ok no ok
X \fB+\fP required ok ok ok
X \fB*\fP optional ok ok no
.fi
.ta 0.5i
.sp
If a switch defined with an argument is given in a cluster, its
argument may come from:
.sp
.IP \\h'.5i'1. 1i
the immediately following characters, if the
.I FLAG
is defined as
.BR `C+' .
This behavior is similar to how
.I lpr
parses its printer switch:
.BR `-Pprinter' .
In this case, the flag would be given as
.BR `P+' .
If the flag is defined as
.BR `P=' ,
then either an equal sign must be used, or the subsequent word will be
used as the argument.
.sp
.IP \\h'.5i'2. 1i
the string followed by the equal sign (\fB`='\fP)
in the same word as the switch. This allows single character switches
to be given similar to longer switches:
.B `-l=999'
or
.BR `-length=999' .
.IP \\h'.5i'3. 1i
the subsequent word in the argument vector, if there are no
strings resulting from cases
.I (1)
or
.I (2)
above.
.sp
The default action for this style flag is to increment a Perl
variable,
.BI $opt_ C,
where
.B `C'
is the single character switch name, or to set its value to the argument
if defined to accept arguments.
For example, if the flags
.B `l'
and
.B `t'
were defined, then the switch
.B `-lt'
would cause the variables
.B $opt_l
and
.B $opt_t
to both be incremented.
.TP .5i
(c) \fBexpr\fR
This syntax is the usual Perl expression. It is tested
directly, and no default action is assumed; actions must be
specified by the user.
.PP
Since the order of the flags is the order in which the tests will be
performed, if the user mixes flag styles, and there are overlaps between
single character options and word options, the word options should
be specified first, otherwise the single character parsing will cause
the word argument to get broken into characters.
.PP
In order to facilitate debugging the options specifications and the
resulting parser, if the first argument is
.BR `-DEBUG_PARSER' ,
then the parser code will be printed to
.B STDERR
before being eval'ed.
.SH EXAMPLES
.sp
.nf
.ft B
&ParseArgs(<<'EOF') \fR# NOTE: single quotes!\fB
X t $tbl++
X l $lst++
EOF
.ft R
.fi
.IP
This example recognizes the
.B `-t'
and
.B `-l'
switches, which may be
given separately or combined as
.B `-lt'
or
.BR `-tl' ,
and sets the associated variables accordingly. In this case, the
default variable assignments (\c
.B $opt_t
and
.BR $opt_l )
are NOT done.
.PP
.nf
.ft B
&ParseArgs('t', '$tbl++', 'l', '$lst++');
.ft R
.fi
.IP
This is equivalent to the previous example.
.PP
.ft B
&ParseOpts('t l');
.ft R
.IP
This is essentially equivalent to the first two examples, except
that the variables set for
.B `-t'
and
.B `-l'
are
.B $opt_t
and
.BR $opt_l ,
respectively.
.PP
.nf
.ft B
&ParseOpts('-file= -list: -edit -optimize');
.ft R
.fi
.IP
In this example, the variables set would be:
.BR $opt_file ,
.BR $opt_list ,
.BR $opt_edit ,
and
.BR $opt_optimize .
The
.B `-list'
option has an optional argument, while
.B `-file'
must be supplied with an argument or an error will result.
.PP
.nf
.ft B
&ParseArgs(<<'EOF");
X -file= &ParseArgsFromFile(ARG);
X b $Brief++
X v $Verbose++
X l* $Len = ARG || 80
X -edit
X -arch= $Arch = ARG
X -os= $OS = ARG
EOF
.fi
.ft R
.IP
This example illustrates the combination of the various types,
including a default action.
.sp
The
.B `-file'
switch, which may be abbreviated as
.B `-f'
causes the routine,
.I &ParseArgsFromFile
to be invoked with computed argument
.B (ARG)
of the
.B `-file'
switch. The arguments read from the file argument are then placed on
the argument stack as if they had been typed by the user. These new
arguments are parsed along with any remaining, original arguments.
.sp
The
.B $Brief
and
.B $Verbose
variables will be set if their respective, clusterable option flags are
given.
.sp
The
.B `-l'
option may be optionally given an argument, either as
.B `-lXYZ' or
.BR `-l=XYZ' ;
it is assigned to
.BR $Len .
.sp
The variable
.B $opt_edit
will be set (to 1).
.sp
The
.B $Arch
variable will be set to the argument supplied to the
.B `-arch'
switch; similarly, the
.B $OS
variable will be set by the
.B `-os'
switch, both of which may be abbreviated.
.sp
.PP
.ft B
&ParseOpts('-in< -out> -directory/ -file. -user~ -group( -num# -new!');
.ft R
.PP
This is a rather baroque example illustrating the features of useful
default actions. The following variables will be set as follows.
.TP 1i
.B $opt_in
is set to the name of a file which is opened for input, using the
filehandle of
.BR `FH_in' .
The variable and filehandle names are always
.BI `$opt_ OPTION'
and
.BI `FH_ OPTION'.
If the file could not be opened for input, an error would have occurred.
.TP
.B $opt_out
is set to the name of a file opened for writing, using the filehandle of
.BR `FH_out' .
.TP
.B $opt_directory
is set to the name of an existing directory; an error will occur if the
directory doesn't exist.
.TP
.B $opt_file
is set to the name of an existing file; no other tests are made, just
existence. If the file given as an argument doesn't exist, an error
occurs.
.TP
.B $opt_user
is set to the name of a valid user login name or numeric user id.
.TP
.B $opt_group
is set to the name of a valid group name or numeric group id.
.TP
.B $opt_num
is set to a number given as the argument; anything other than a number
causes an error.
.IP
.B $opt_new
is set to the name of a non-existent file; an error occurs if the file
already exists.
.sp
.SH ENVIRONMENT
.B
.IP @ARGV
The argument vector is implicitly parsed.
.SH FILES
None.
.SH AUTHOR
Alan Stebbens <a...@hub.ucsb.edu>
.SH "SEE ALSO"
.IR getopts.pl (3),
.IR perl (1)
.SH DIAGNOSTICS
.PP
When an error occurs, one of the following error messages is generated,
followed by the value of
.I $Usage
if it is defined.
.sp
Unknown option flag: $flag
.sp
Can't open input: $file: $!
.sp
Unknown option flag: $flag on option $option
.sp
File $_ cannot be read!
.sp
File $_ cannot be written
.sp
Cannot open $_ for output: $!
.sp
Directory $_ does not exist!
.sp
$_ is not a directory!
.sp
File $_ does not exist!
.sp
File $_ is not a plain file!
.sp
File $_ already exists!
.sp
Option $opt: $_ is not a number!
.sp
$_ is not a valid user id!
.sp
$_ is not a valid login name!
.sp
$_ is not a valid group id!
.sp
$_ is not a valid group name!
.sp
Missing argument for option: $option
.sp
Bad option: $option
.SH BUGS
Probably.
.\" Emacs Local Variables:
.\" Emacs mode: perl
.\" Emacs End:
SHAR_EOF
chmod 0444 parseargs.pl ||
echo 'restore of parseargs.pl failed'
Wc_c="`wc -c < 'parseargs.pl'`"
test 20351 -eq "$Wc_c" ||
echo 'parseargs.pl: original size 20351, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= Makefile ==============
if test -f 'Makefile' -a X"$1" != X"-c"; then
echo 'x - skipping Makefile (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting Makefile (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
# Makefile to install parseargs
X
X SHELL = /bin/sh
X
X ROOT = /eci/share
X PERLLIB = $(ROOT)/lib/perl
X MANDIR = $(ROOT)/man/man3
X
X INSTALL = /usr/ucb/install
X
I = ( set -x ; $(INSTALL) -c -m 444 $? $@ )
L = ( set -x ; ln -s $? $@ )
R = if [ -f $@ ]; then rm -f $@ ; fi
X
default:
X @( set -x ; $(MAKE) -n install )
X
install: $(PERLLIB)/parseargs.pl $(MANDIR)/parseargs.3
X
$(PERLLIB)/parseargs.pl: parseargs.pl ; @$R ; $I
$(MANDIR)/parseargs.3: $(PERLLIB)/parseargs.pl ; @$R ; $L
X
shar:
X shar -L50 -o parseargs.shar parseargs.pl Makefile test.pl test1
SHAR_EOF
chmod 0444 Makefile ||
echo 'restore of Makefile failed'
Wc_c="`wc -c < 'Makefile'`"
test 554 -eq "$Wc_c" ||
echo 'Makefile: original size 554, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= test.pl ==============
if test -f 'test.pl' -a X"$1" != X"-c"; then
echo 'x - skipping test.pl (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting test.pl (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'test.pl' &&
#!/bin/perl
X
require 'parseargs.pl';
X
$Usage = <<EOF;
usage: $0 -input INPUT -output OUTPUT -new NEW -exists OLD
X -login LOGIN -group GROUP -number NUM
EOF
X
&ParseArgs(<<'EOF');
X -input<
X -dir/
X -output>
X -new!
X -exists.
X -login~
X -group(
X -number#
EOF
X
format STDOUT =
X input = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X $opt_input
X dir = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X $opt_dir
output = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X $opt_output
X new = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X $opt_new
exists = @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
X $opt_exists
X login = @<<<<<<<<<<<<<<
X $opt_login
X group = @<<<<<<<<<<<<<<<
X $opt_group
number = @<<<<<<<<<<<<<<
X $opt_number
.
X
write;
X
open(INPUT,"<&FH_input") || die "can't dup FH_input: $!\n";
close FH_input;
open(OUTPUT,">&FH_output") || die "Can't dup FH_output: $!\n";
close FH_output;
X
while (<INPUT>) { print OUTPUT; }
close (INPUT);
close (OUTPUT);
X
exit;
SHAR_EOF
chmod 0755 test.pl ||
echo 'restore of test.pl failed'
Wc_c="`wc -c < 'test.pl'`"
test 946 -eq "$Wc_c" ||
echo 'test.pl: original size 946, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
# ============= test1 ==============
if test -f 'test1' -a X"$1" != X"-c"; then
echo 'x - skipping test1 (File already exists)'
rm -f _shar_wnt_.tmp
else
> _shar_wnt_.tmp
echo 'x - extracting test1 (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'test1' &&
#!/bin/sh
set -x
./test.pl -input=test.pl -dir . -output=xyz -new=qrz -exists=test1 -login bin -group bin -num 1
SHAR_EOF
chmod 0555 test1 ||
echo 'restore of test1 failed'
Wc_c="`wc -c < 'test1'`"
test 113 -eq "$Wc_c" ||
echo 'test1: original size 113, current size' "$Wc_c"
rm -f _shar_wnt_.tmp
fi
exit 0

Peter Steele

unread,
Oct 7, 1993, 8:14:13 PM10/7/93
to
lw...@netlabs.com (Larry Wall) writes:

>In article <OCARROLL.9...@ss151.icot.or.jp> ocar...@ss151.icot.or.jp writes:
>: I've always wondered why Getopts builds special variables instead of using
>: an associative array like
>: $opts{"i"}
>: or $opts{"#"}
>: That way, even keyword arguments like
>: $opts{"conv=ascii"}
>: or $opts{"foreground"}
>: might work.
>:
>: Any reason why it's not implemented that way?

>Oh, laziness, impatience and hubris, I suppose. :-) Tom C's gonna be
>working over the whole library at some point, so maybe we can get him
>to fix up something. Maybe we need a new function, or perhaps we just
>need to make it so that evaluating an existing function in a list
>context would return an associative array value. It's certainly
>cleaner to use an associative array, though a little less efficient in
>certain ways.

It may be a bit less efficient, but the change to Getopts to make it
use associative arrays instead of multiple variables is trivial (see
my post "A better getopts"). All that needed changing were the two
eval lines, and now it can handle non-alpha arguments quite easily.
Of course, Tom C will probably do it better... :-)

Stephen O. Lidie

unread,
Oct 12, 1993, 11:42:41 AM10/12/93
to
In article <1993Oct7.1...@netlabs.com>, lw...@netlabs.com (Larry

Of course, more robust 'getopt' packages like newgetopts by Johan Vromans
and my evaluate_parameters package handle 'list of' command line parameters
and so return both scalar AND list type variables... so the associative
array trick doesn't work here!

When I wrote evap I kept with this convention because I thought everyone
was happy with it :-).

To use associative arrays with list parameters I'd have to join the list
values before sticking them into the array and the user would have to split
them after evap returned..... possible I suppose. Any better ideas out
there?

Take care,

SOL

Larry Wall

unread,
Oct 13, 1993, 2:40:53 AM10/13/93
to
In article <lusol-121...@meatball.cc.lehigh.edu> lu...@Lehigh.EDU (Stephen O. Lidie) writes:
: To use associative arrays with list parameters I'd have to join the list

: values before sticking them into the array and the user would have to split
: them after evap returned..... possible I suppose. Any better ideas out
: there?

In Perl 5 you'd be able to have a reference to a list as the value of
an associative array element.

[I'm getting awfully tired of typing "associative array". Let's figure
out something a little more monomorphemic to denote one. I've sort of
started calling them "hashes", which confuses implementation with
specification, and Tom has sort of started calling them "tables", which
is misleading to anyone who thinks of tables as having more than two
columns, and ordered rows. Anybody else have any bright ideas? Some
of the best metaphors are almost as hard to type as "associative array".]

Larry

Ian Phillipps

unread,
Oct 13, 1993, 5:25:45 AM10/13/93
to
lw...@netlabs.com (Larry Wall) writes:

>[I'm getting awfully tired of typing "associative array". Let's figure
>out something a little more monomorphemic to denote one. I've sort of
>started calling them "hashes", which confuses implementation with
>specification, and Tom has sort of started calling them "tables", which
>is misleading to anyone who thinks of tables as having more than two
>columns, and ordered rows. Anybody else have any bright ideas? Some
>of the best metaphors are almost as hard to type as "associative array".]

How about "grabs" - you can grab things out of them, and they're a sort
of grab-bag you can put things in.

Or "awks", which honours the language that made them popular? (Do they
pre-date awk?)

Ian
--
---
Ian Phillipps. Tech support manager, Unipalm. If you ask me, all conspiracy
Phone +44 223 250103, Fax 250101 theories are put about by the
Pipex phone +44 223 250120. Internic: IP4. same bunch of people.

Craig H. Smith

unread,
Oct 13, 1993, 8:26:05 AM10/13/93
to

Ian Phillipps writes:
> How about "grabs" - you can grab things out of them, and they're a sort
> of grab-bag you can put things in.

Again could be confused with the bag data structure (do we remember
it?). Although those aren't used much here so it probably doesn't
matter.

> Or "awks", which honours the language that made them popular? (Do they
> pre-date awk?)

Make me think of awkward. ;) Which they are not. For those people not
familiar with awk (like me), the name "awks" does not have the
historical meaning to link it with associative arrays.

I though of shortening the name "associative array" rather than making
a new name because associative array has a lot of meaning attached to
it. I came up with or A-ray (pronouced 'a ray'). Only problem I can
think of, saying this to myself is that it could be confused in
converstaion, "a ray" and "array" are very similiar. Only difference
is where you but the stress.

(raig

--
-------------------------------------------------------------
Craig H. Smith "Try not. Do, or do not.
Network Management Group There is no try." - Yoda
Xyplex Inc.
chs...@eng.xyplex.com "Wer ist der Typ?" - Das Prizen
-------------------------------------------------------------
It's... (dum-dum-dum) a cappellaman!
-------------------------------------------------------------

Steve Vinoski

unread,
Oct 13, 1993, 10:16:20 AM10/13/93
to

What's wrong with the term "map"?

--steve

Steve Vinoski vin...@apollo.hp.com (508)436-5904
Distributed Object Computing Program fax: (508)436-5122
Hewlett-Packard, Chelmsford, MA 01824

Aaron Sherman

unread,
Oct 13, 1993, 9:55:15 AM10/13/93
to

lw...@netlabs.com (Larry Wall) writes:

[I'm getting awfully tired of typing "associative array". Let's figure
out something a little more monomorphemic to denote one. I've sort of
started calling them "hashes", which confuses implementation with
specification, and Tom has sort of started calling them "tables", which
is misleading to anyone who thinks of tables as having more than two
columns, and ordered rows. Anybody else have any bright ideas? Some
of the best metaphors are almost as hard to type as "associative array".]

I got used to the GNU-EMACS lisp construct, alist. It's simple, short
and pretty-much says it all.

Any comments?

Others:

pair list pair array
binding/bound list binding/bound array
map hash
table string farm

or the famous:

if you don't like this name, then write your own damn language!

A little harder to type, but *much* more satisfying ;-)


-AJS

Ken Fitch

unread,
Oct 13, 1993, 11:02:14 AM10/13/93
to

Why not "assay"? Not only is it short & sweet, but it
is a legitimate word with a set of meanings that can
be stretched to cover the usage of associative arrays.

From the webster server at cs.indiana.edu:

assay:
1. as.say \'as-.a-, a-'sa-\ n [ME, fr. OF essai, assai test, effort - more
at ESSAY] archaic 1: TRIAL, ATTEMPT 2: examination and determination as to
characteristics (as weight, measure, quality) 3: analysis (as of an ore or
drug) to determine the presence, absence, or quantity of one or more
components 4: a substance to be assayed; also : the tabulated result of
assaying
2. as.say \a-'sa-, 'as-.a-\ vt 1: TRY, ATTEMPT 2a: to analyze (as an ore)
for one or more valuable components 2b: ESTIMATE : to prove up in an assay
- as.say.er n


Ken Fitch
Westinghouse Electric Corp.
--
Kenneth R. Fitch
fi...@ittc.pgh.wec.com
(412)733-6435

Michael Meissner

unread,
Oct 13, 1993, 12:52:06 PM10/13/93
to
In article <1993Oct13....@unipalm.co.uk> i...@unipalm.co.uk (Ian
Phillipps) writes:

| Or "awks", which honours the language that made them popular? (Do they
| pre-date awk?)

Umm, Snobol predates awk, I believe, and it had tables in it (at least I ran
across snobol before I ran across Unix -- if I remember correctly, V6 had a
snobol-3 interpreter but no awk).
--
Michael Meissner email: meis...@osf.org phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

Old hackers never die, their bugs just increase.

Tim Bunce

unread,
Oct 13, 1993, 1:46:04 PM10/13/93
to
In article <CEuAB...@apollo.hp.com> vin...@apollo.hp.com (Steve Vinoski) writes:
>
>What's wrong with the term "map"?
>
Seconded. I also like "map" as a name for associative arrays.

>--steve
>
>Steve Vinoski vin...@apollo.hp.com (508)436-5904
>Distributed Object Computing Program fax: (508)436-5122
>Hewlett-Packard, Chelmsford, MA 01824

Regards,
Tim Bunce.

James Knowles

unread,
Oct 13, 1993, 2:45:39 PM10/13/93
to
In article <1993Oct13.0...@netlabs.com> lw...@netlabs.com (Larry Wall) writes:
>[I'm getting awfully tired of typing "associative array". Let's figure
>out something a little more monomorphemic to denote one. I've sort of
>started calling them "hashes", which confuses implementation with
>specification, and Tom has sort of started calling them "tables", which
>is misleading to anyone who thinks of tables as having more than two
>columns, and ordered rows. Anybody else have any bright ideas? Some
>of the best metaphors are almost as hard to type as "associative array".]

I've thought of them as "parades."

"Huh?" you say? Well this is how I think of them:

%array -> [p]ercent [array] -> parray -> which reminds me of "parade"
without the "d" on the end. I think I somehow used it as a verb in the
past tense in an instant of convoluted insanity. It stuck and I can't
get it out of my head.

Is it a useful suggestion? Probably not outside my sphere of
corruptio...uh...influence.

-------
James Knowles
aristo...@cc.usu.edu Je crois que je ne vais jamais voir... /\/\
jam...@spillman.com Un animal si beau qu'un chat. ( oo )
...!uunet!spillman!jamesk -----------
Unix can't be all that bad. After all, there's a "cat" command but no
"dog" command.

Brian Rice

unread,
Oct 13, 1993, 2:23:02 PM10/13/93
to
I sometimes explain associative arrays by calling them cubbies.

+==========+==========+==========+==========+==========+
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
+==========+==========+==========+==========+==========+
| Susie | June | Larry | Randal | Spot |
+==========+==========+==========+==========+==========+

--
Brian Rice ri...@dg-rtp.dg.com +1 919 248 6328
DG/UX Software Quality Engineering
Data General Corp., Research Triangle Park, North Carolina
"Why these mountains? Why this sky? This long road? This empty room?"

Alan Stebbens

unread,
Oct 13, 1993, 2:26:02 PM10/13/93
to
> [I'm getting awfully tired of typing "associative array". Let's figure
> out something a little more monomorphemic to denote one. I've sort of
> started calling them "hashes", which confuses implementation with
> specification, and Tom has sort of started calling them "tables", which
> is misleading to anyone who thinks of tables as having more than two
> columns, and ordered rows. Anybody else have any bright ideas? Some
> of the best metaphors are almost as hard to type as "associative array".]

How about calling it an "alist", with many being "alists"? This is what
Emacs lisp programmers call an associative list structure.

Alan Stebbens <a...@hub.ucsb.edu>

Kartik Subbarao

unread,
Oct 13, 1993, 11:28:20 AM10/13/93
to
In article <5...@ittc.wec.com> fi...@ittc.wec.com (Ken Fitch) writes:
>
>Why not "assay"? Not only is it short & sweet, but it
>is a legitimate word with a set of meanings that can
>be stretched to cover the usage of associative arrays.
>
>From the webster server at cs.indiana.edu:
>
>assay:
>1. as.say \'as-.a-, a-'sa-\ n [ME, fr. OF essai, assai test, effort - more
> at ESSAY] archaic 1: TRIAL, ATTEMPT 2: examination and determination as to
> characteristics (as weight, measure, quality) 3: analysis (as of an ore or
> drug) to determine the presence, absence, or quantity of one or more
> components 4: a substance to be assayed; also : the tabulated result of
> assaying
>2. as.say \a-'sa-, 'as-.a-\ vt 1: TRY, ATTEMPT 2a: to analyze (as an ore)
> for one or more valuable components 2b: ESTIMATE : to prove up in an assay
> - as.say.er n

Good one! This one has my vote.

-Kartik

Anthony Thyssen

unread,
Oct 14, 1993, 2:34:00 AM10/14/93
to
pe...@dragon.acadiau.ca (Peter Steele) writes:
| I've got a hack to solve the -# option, by going through @ARGS
| and replacing -# with -N. This works well enough, although it's
| not perfect. I can't think of anyway to handle the -i option
| though, other than forcing it to have an argument. Any one have
| any suggestions?

This is the way I handle this problem. From a program I wrote called
pstalk which I use for printing to network and tty printers.


sub Usage {
print STDERR @_;
print STDERR <<'END_USAGE';
Usage: command [options] -n name -h name file
.... option meanings ....
END_USAGE
exit 2;
}

while( $_ = $ARGV[0], ($_, $arg) = /^-(.)(.*)/ ) {
shift;
if ( /c/ ) { $pass_ctrl = 1; next }
if ( /n/ ) { $user = $arg || shift; next }
if ( /h/ ) { $host = $arg || shift; next }
&Usage( "Bad Option `-", $_, $arg, "'\n" );
}
undef($arg);

# Get Non-options
$file = shift;

# now check the arguments
# ...

undef( &Ugaes ); # we don't need this any more


This is highly cut down but you can get the method.


Anthony Thyssen - (SysProg @ Griffith University) ant...@cit.gu.edu.au
------------------------------------------------------------------------------
`Hear me, Oh Gods! Its a rest break not a timeout!
Put the fire back!'
-- "Dream Park"
------------------------------------------------------------------------------

Tom Christiansen

unread,
Oct 14, 1993, 5:31:58 AM10/14/93
to
From the keyboard of a...@dokoka.ucsb.edu (Alan Stebbens):
:> [I'm getting awfully tired of typing "associative array". Let's figure

I don't like the word. It's not a list. List implies some kind of
ordering. I talk about linear arryas, and call them lists, or associative
arryas, and call them tables. I don't mind maps at all. It seems to me
though that the word table could also be applied to something more like a
list o' lists or such.

--tom
--
Tom Christiansen tch...@cs.colorado.edu
"Will Hack Perl for Fine Food and Fun"
Boulder Colorado 303-444-3212

Jurgen Botz

unread,
Oct 14, 1993, 11:27:12 AM10/14/93
to
In article <MEISSNER.93...@pasta.osf.org>,

Michael Meissner <meis...@osf.org> wrote:
>In article <1993Oct13....@unipalm.co.uk> i...@unipalm.co.uk (Ian
>Phillipps) writes:
>| Or "awks", which honours the language that made them popular? (Do they
>| pre-date awk?)
>
>Umm, Snobol predates awk, I believe, and it had tables in it (at least I ran
>across snobol before I ran across Unix -- if I remember correctly, V6 had a
>snobol-3 interpreter but no awk).

Well, then we'll just have to call them "snobs"... ;-) ;-)
--
Jurgen Botz, jb...@mtholyoke.edu | ``Accountability is the price of openness''
South Hadley, MA, USA | - Daniel Geer

Chaim Frenkel

unread,
Oct 14, 1993, 11:34:47 AM10/14/93
to
In article <1993Oct13.0...@netlabs.com> lw...@netlabs.com (Larry Wall) writes:

[I'm getting awfully tired of typing "associative array". Let's figure
out something a little more monomorphemic to denote one. I've sort of
started calling them "hashes", which confuses implementation with
specification, and Tom has sort of started calling them "tables", which
is misleading to anyone who thinks of tables as having more than two
columns, and ordered rows. Anybody else have any bright ideas? Some
of the best metaphors are almost as hard to type as "associative array".]

How about

assoc (Insert the value into an ASSOC, and then retreive it)
or
alist (Insert the value into an ALIST, and then retreive it)
or
keytab (Insert the value into a KEYTAB, and then retrieve it)
or
hashtab (Insert the value into a HASHTAB, and then retreive it)

<chaim>
--
Chaim Frenkel On contract at:
ch...@nlk.com ch...@fsrg.bear.com
Nonlinear Knowledge, Inc. Bear Stearns & Co., Inc.

Roy Johnson

unread,
Oct 14, 1993, 2:04:20 PM10/14/93
to
i...@unipalm.co.uk (Ian Phillipps) writes:

Or "awks", which honours the language that made them popular? (Do they
pre-date awk?)

PostScript calls them dictionaries (you look up something by a keyword).
--
-------- Roy Johnson ---- rjoh...@shell.com ---- Speaking for myself --------
"When the only tool you have is Perl, the whole | "Hooray for snakes!"
world begins to look like your oyster." -- Me | -- The Simpsons (29 Apr 93)

Larry Wall

unread,
Oct 14, 1993, 4:00:52 PM10/14/93
to
In article <ASHERMAN.93Oct13095515@new_lx.fmrco.com> ashe...@fmrco.COM writes:
: I got used to the GNU-EMACS lisp construct, alist. It's simple, short

: and pretty-much says it all.

It pretty-much says nothing to me, being more of a vi person... :-)

It also has the difficulty of not being visually distinct from "list".
It has the additional difficulty that an associative array isn't really
a list, though it's sometimes represented as a list.

: Others:


:
: pair list pair array
: binding/bound list binding/bound array
: map hash
: table string farm

String farm is cute, though farms are supposed to have a one-to-many
correspondence. If you plant one string in a string farm, you'd hope
to harvest more than one string, or you'll go out of business.

: or the famous:


:
: if you don't like this name, then write your own damn language!
:
: A little harder to type, but *much* more satisfying ;-)

Heh. So far, I still like "hash" the best, because it so graphically
indicates the *lack* of ordering, as in the phrase, "made a hash of".

The problem with "map" is that the prototypical meaning of map is a
piece of paper showing a two-dimensional representation of geography.
The mathematical usage "this maps to that" is not familiar to many
ordinary folks.

And as I mentioned earlier, I don't like "table" because it implies
some untruthfulnesses about arity and ordering.

If there were a four-letter word meaning "correspondence" that doesn't
have any other interfering technical or metaphorical meanings, I might
like it better than "hash". But I don't think there is such a word.

"Hash" comes from the French word that we get "hatchet" from. Perhaps
Perl is really a French Army Hatchet.

It's certainly true that hashes are the meat and potatoes of Perl
programming...

Larry

John Dawson

unread,
Oct 14, 1993, 8:24:55 PM10/14/93
to
> I'm getting awfully tired of typing "associative array". Let's figure
> out something a little more monomorphemic to denote one.

I call them assocs. Pronounced ASS-ocks. Easy to type, and close enough
to the unabbreviated name to be mnemonic.

...jkd

David M. Sundstrom, EC1 F5 , 997-5380, DMSX

unread,
Oct 14, 1993, 8:03:03 PM10/14/93
to
In article 19...@netlabs.com, lw...@netlabs.com (Larry Wall) writes:
>
> I'm getting awfully tired of typing "associative array".

Must be that vi editor.

> Let's figure out something a little more monomorphemic to denote one.
> I've sort of started calling them "hashes", which confuses implementation with

> specification.

That would be a weak association for some people. I would bet that
the way associative arrays are implemented and the way many people
imagine them being implemented are quite different. (Which may be
why some people are surprised that things don't come out the way
you put them in!)

> and Tom has sort of started calling them "tables", which is
> misleading to anyone who thinks of tables as having more than two
> columns, and ordered rows.

I actually like Tom's metaphor. But then I've been biased. I took
his class.

> Anybody else have any bright ideas? Some of the best metaphors are
> almost as hard to type as "associative array".

I guess symbolically indexed array is out, then.

"partners" maybe?

> String farm is cute.

Yes, it is.

-David Sundstrom su...@asictest.sc.ti.com
Texas Instruments.

> Larry


Laurence Yaffe

unread,
Oct 14, 1993, 11:25:56 PM10/14/93
to
In article 19...@netlabs.com, lw...@netlabs.com (Larry Wall) writes:
>
> I'm getting awfully tired of typing "associative array".

> Let's figure out something a little more monomorphemic to denote one.

> I've sort of started calling them "hashes", which confuses implementation with
> specification.

I lost track of whoever suggested "map", but that's the name I'd choose.
As Larry already noted, not everyone is familiar with the mathematical notion
of a "mapping". However:

Even with the non-mathematical interpretation, everyone knows that maps
store a wealth of information!

The mathematical usage is very widespread and is a good thing to learn. 1/2:-)

Jeff Hayward

unread,
Oct 15, 1993, 2:05:32 AM10/15/93
to
In article <1993Oct13.0...@netlabs.com> lw...@netlabs.com (Larry Wall) writes:
>[I'm getting awfully tired of typing "associative array". Let's figure
>out something a little more monomorphemic to denote one. I've sort of

Well, I've always called them 'CAMs', for Content Addressable
Memories, which is how I first learned of the concept. Works for me,
but then again I don't mind TLAs.
--
Jeff Hayward

Tom Christiansen

unread,
Oct 15, 1993, 3:59:47 AM10/15/93
to
From the keyboard of lw...@netlabs.com (Larry Wall):
:And as I mentioned earlier, I don't like "table" because it implies

:some untruthfulnesses about arity and ordering.
:

Hmm, if you enteered elements like this

$table->{$key} = \@rows;

and at sometime you set this prop:

$table->compare_function(\&sortbyval);

then you could go through the rows this way:

foreach $rp ($table->rows) {
if ($rp->[5] eq 'Happy' ) { }
}

and then I think you would have the kind of table that you were looking for,
right?

Wayne Throop

unread,
Oct 15, 1993, 11:37:03 AM10/15/93
to
: From: lw...@netlabs.com (Larry Wall)
: Message-ID: <1993Oct14.2...@netlabs.com>
: So far, I still like "hash" the best, because it so graphically

: indicates the *lack* of ordering, as in the phrase, "made a hash of".

To me, and I think to most people taught the usual data structures
and algorithms courses, it implies far too much about the
underlying impliementation, implications that should not be there.

: If there were a four-letter word meaning "correspondence" [...]

"Mail". (Sorry, couldn't resist. But then, who could complain after
that "hashes are the meat and potatoes of Perl programming..." crack?)

My favored terms would be "table" or "map". I doubt
that anybody would be confused long by their non-computer, non-
mathematical meanings. And I vaguely remember that "table" was used
as the term for this in Snobol, to little or no complaint.

But failing that, how about calling them "associations"? That's
where the "a" in the rejected "alist" comes from. Further, it
has cognitive resonance with "associative memory" as well as that
with alist. Then, the short form would be "assoc", and who hasn't
a sock as a handy container in which to store things?

Another possibility is "relation", with the nearness to the notion
of "relational database" and related concepts being either a pro or
con depending on viewpoint.

Yet another possibility is to call them "lookups" or "references" (a
reference work being something in which other things are "looked up").
The resonance of "references" to a system of virtual pointers seems to
me also to be a feature, since a string-to-string map (or even a
string-to-whatever map) is basically the ineffable notion of "pointer"
or "dereference" made effable. And the short form of "ref" is (to me)
appealing. (Dictionary, a particular kind of reference, is probably to
narrow a term...)

Ah well, one person's careful use of metaphor and mnemonic is another's
twisted overcute jargon, I suppose. Case in point being the
special-character-named perl pseudovariables I imagine. Another being
the up/down/strange/charm/truth/beauty quarks (before they changed the
last two to top and bottom) (or "barn" as a measure of cross section
for that matter). Sigh.

And while I'm posting.... does it strike anybody else that using such
general terms for a... let's call it map... with a domain of strings
only in a language that has other datatypes mayn't be quite
reasonable? Or is it planned that a (say) list can be used to index
hashes/maps/whatevertheygetcalled? Of course, allowing arbitrary data
types in the domain opens quite a can of worms, dealing with the
meaning of equality and identity. Potentially ugly. Just wondering...

--
Wayne Throop throopw%sh...@concert.net
thr...@aur.alcatel.com

Tim Bunce

unread,
Oct 15, 1993, 6:47:18 AM10/15/93
to
In article <1993Oct14.2...@netlabs.com> lw...@netlabs.com (Larry Wall) writes:
>
>Heh. So far, I still like "hash" the best, because it so graphically
>indicates the *lack* of ordering, as in the phrase, "made a hash of".
>
Is this a case of naming a data type by a side-effect of it's implementation?

>The problem with "map" is that the prototypical meaning of map is a
>piece of paper showing a two-dimensional representation of geography.
>The mathematical usage "this maps to that" is not familiar to many
>ordinary folks.
>

But easy enough to pick up I guess.

Hash, to me, does not actually say very much about what it actually is.
To explain a hash to someone, especially why it's called "hash", requires
a detailed description of hashing keys, buckets, overflow chains etc.

By comparison "this maps to that" sounds simple and easy.

>And as I mentioned earlier, I don't like "table" because it implies
>some untruthfulnesses about arity and ordering.
>

Agreed.

Regards,
Tim Bunce.

Mark Pease

unread,
Oct 15, 1993, 2:18:32 PM10/15/93
to
In article <1993Oct14.2...@netlabs.com>,

Larry Wall <lw...@netlabs.com> wrote:
>If there were a four-letter word meaning "correspondence" that doesn't
>have any other interfering technical or metaphorical meanings, I might
>like it better than "hash". But I don't think there is such a word.
>
>"Hash" comes from the French word that we get "hatchet" from. Perhaps
>Perl is really a French Army Hatchet.
>
>It's certainly true that hashes are the meat and potatoes of Perl
>programming...
>
>Larry

Well, let's coin a new word! How about corr (for correspondence- corr.
is the accepted appr. :-)

It also gives the flavor that associative arrays are the central (the "core"),
or "meat and potatoes", of perl.

Just a thought,

Mark Pease, Co-author of "Software Engineering with Perl"
--
Mark Pease ma...@vlsi-az.sps.mot.com
Motorola CODEX VLSI Design Center
2710 S Roosevelt St. Mail Stop: AZ28 BB106
Tempe, AZ 85282 Phone:(602)784-2725 FAX:(602)784-2759

Craig Steury

unread,
Oct 15, 1993, 8:37:27 AM10/15/93
to

> lw...@netlabs.com (Larry Wall) writes:
>
> >[I'm getting awfully tired of typing "associative array". Let's figure
> >out something a little more monomorphemic to denote one. I've sort of
> >started calling them "hashes", which confuses implementation with
> >specification, and Tom has sort of started calling them "tables", which
> >is misleading to anyone who thinks of tables as having more than two
> >columns, and ordered rows. Anybody else have any bright ideas? Some
> >of the best metaphors are almost as hard to type as "associative array".]
>


Being from a Lisp background I like the name 'A-list' short for Lisp's
association-list (ie (assoc <item> <list>) etc). Given the equivalence
between lists and arrays in Perl this is not too big a stretch ... and 'alist'
slides off the tongue better than 'aarray' or 'a-array'!


On another subject, has anyone thought of adding a package symbol import/export
mechanism to Perl similar to Common Lisp? I currently accomplish this by doing
something like:

package rcs_lib;
#
# External routines ...
#

sub main'rcs_branches_for_version { &rcs_branches_for_version(@_); }

### Internal routines ...

sub rcs_branches_for_version etc
|
|


The main reason I don't like having to do &rcs_lib'rcs_branches_for_version()
etc is that it messes up my indentation, though there are some other
considerations also.

2c

cs
--
Craig Steury
Evans & Sutherland
(801) 582-5847
Salt Lake City, UT 84108

cst...@dsd.es.com

Michael D'Errico

unread,
Oct 15, 1993, 3:45:17 PM10/15/93
to
ma...@markp.vlsi-az.sps.mot.com (Mark Pease) writes:

>Well, let's coin a new word! How about corr (for correspondence- corr.
>is the accepted appr. :-)

>It also gives the flavor that associative arrays are the central (the "core"),
>or "meat and potatoes", of perl.

AAaahhhh! ....it reminds me too much of "core dump" :)

(although I haven't seen many of those while using Perl!)

Mike

Tom Christiansen

unread,
Oct 13, 1993, 8:04:29 AM10/13/93
to
From the keyboard of lu...@Lehigh.EDU (Stephen O. Lidie):
:To use associative arrays with list parameters I'd have to join the list

:values before sticking them into the array and the user would have to split
:them after evap returned..... possible I suppose. Any better ideas out
:there?

Yes, store the list, not a string, as the value of the table.

$options{$optname} = \@local_list;

Dmitry Gokhman

unread,
Oct 16, 1993, 10:39:49 PM10/16/93
to


Ok, I am neophyte with ass. arrays (hmmm...), but when you said the magic word
"map" things started clicking a little. How would one compose maps then?
--
/////////////////////////////////////////////////////////////////////
- Mr. Gumby * \oo7 Dmitry Gokhman -> gok...@ringer.cs.utsa.edu
says: `/v/-* May the wind at your back never be your own.
MY BRAIN HURTS J L - Jack Lemmon YOUR AD HERE!
/////////////////////////////////////////////////////////////////////

Ian Wilson

unread,
Oct 17, 1993, 1:25:26 PM10/17/93
to

Why not "pairpile" ?

Pile implies unordered.
Pair association between two objects.

Ian W.


Jay Rogers

unread,
Oct 29, 1993, 10:37:22 PM10/29/93
to
In article <CSTEURY.93...@cuzco.dsd.es.com> cst...@cuzco.dsd.es.com (Craig Steury) writes:
> The main reason I don't like having to do
> &rcs_lib'rcs_branches_for_version() etc is that it messes up my
> indentation, though there are some other considerations also.

For those of you using emacs perl-mode, here's a fix for messed up
indentation with the package notation (i.e. $package'var).

(setq perl-mode-hook
'(lambda ()
;; Put apostrophe in separator class so package notation recognized.
(modify-syntax-entry ?\' "." perl-mode-syntax-table)))

--
Jay Rogers - Ampersand Inc. Westford, Mass. USA

Randal L. Schwartz

unread,
Nov 1, 1993, 4:05:13 AM11/1/93
to
>>>>> In article <JAY.93Oc...@splat.ampersand.com>, j...@ampersand.com (Jay Rogers) writes:
Jay> In article <CSTEURY.93...@cuzco.dsd.es.com> cst...@cuzco.dsd.es.com (Craig Steury) writes:
Jay> For those of you using emacs perl-mode, here's a fix for messed up
Jay> indentation with the package notation (i.e. $package'var).

Jay> (setq perl-mode-hook
Jay> '(lambda ()
Jay> ;; Put apostrophe in separator class so package notation recognized.
Jay> (modify-syntax-entry ?\' "." perl-mode-syntax-table)))

...except that this mucks up single-quoted strings.

Yeah, Perl's just too rich a language for Emacs to parse reasonably
fast.

print 'Just another Perl hacker,'
--
Name: Randal L. Schwartz / Stonehenge Consulting Services (503)777-0095
Keywords: Perl training, UNIX[tm] consulting, video production, skiing, flying
Email: <mer...@ora.com> Snail/FAX: (Call) DON'T REPLY TO: <mer...@wyeth.intel.com>
Phrase: "Welcome to Portland, Oregon ... home of the California Raisins!"

John Jack Repenning

unread,
Nov 1, 1993, 3:47:15 PM11/1/93
to

> Jay> (setq perl-mode-hook
> Jay> '(lambda ()
> Jay> ;; Put apostrophe in separator class so package notation recognized.
> Jay> (modify-syntax-entry ?\' "." perl-mode-syntax-table)))

You might like

(modify-syntax-entry ?\' "_" perl-mode-syntax-table)

better. The principal difference is that sexp-related commands skip
over symbols (including symbol characters, "_"), but not punctuation
(".").

> ....except that this mucks up single-quoted strings.

It does indeed.

> Yeah, Perl's just too rich a language for Emacs to parse reasonably
> fast.

But considering the complexities involved in supporting C++'s two
comment styles, I'm sure not volunteering to support these two
meanings of "'"!


Jack Repenning M/S 1-875 ja...@wpd.sgi.com
Silicon Graphics, Inc. x3-3027 Off:(415) 390-3027
Visual Magic Division Fax:(415) 390-6056

0 new messages