%%
%% >In article <1994Jan24.101955.20940@news.uit.no>,
%% >Frank OEynes <frank@mack.uit.no> wrote:
%% >>OK, I'm almost blind after using Xarchie for hours so I try posting here!
%% >>
%% >>Are there any usable Perl books/tutorials/manuals
%% >>available from anonymous ftp sites?
%% 
%% >There are scads of them that i know about.  And probably plenty
%% >more that i dont.  A number of archivists are working furiously
%% >to canonicalize and generally improve the level of satisfaction you
%% >get from their sites.  
%% 
%% >That reminds me, if anyone out there has anything of even remote interest
%% >that could be included, please notify us.  (perl-packrats@metronet.com)
%% >And feel free to join up, if you're interested.
%% 
%%         Since you asked, here is a short (20pp) "intro to perl" paper I
%% wrote a few months ago.
%% 
%%
%
% $Header: /home/pat/tex/RCS/perl.tex,v 0.6 1993/09/08 14:16:51 pat Exp pat $
%
%
%
\documentstyle{article}
\pagestyle{plain} %%    {empty}
%\flushbottom
%\setlength{\oddsidemargin}{10mm}
%\setlength{\evensidemargin}{10mm}
%\setlength{\marginparwidth}{0mm}
%\setlength{\marginparsep}{0mm}
%\setlength{\topmargin}{-20mm}
%\setlength{\headheight}{0mm}
\setlength{\textwidth}{145mm}
%\setlength{\textheight}{250mm}
%\setlength{\footheight}{0mm}
%\setlength{\parindent}{0mm}
%\newlength{\lmargin}
%\setlength{\lmargin}{-8mm}
\newcommand{\carat}{\^{\hbox{}}}
\begin{document}
\large

\title{\huge \fbox{Introduction to Perl}}
\author{
{\bf Patrick M. Ryan}\\
 {\tt patrick.m.ryan@gsfc.nasa.gov}\\
 Hughes STX Corporation}
\date{Revised November 16, 1993}
\maketitle

\section{What is Perl?}

Perl has become the new language of choice for many system management
tasks.  Combining elements of C, awk, sed, grep, and the Bourne shell, Perl
is an excellent tool for text and file processing.  Although Perl is often
described as a ``system management language'', it is useful for many tasks
that would otherwise be done with shell scripts.

``Perl'' is an acronym for {\it Practical Extraction and Report Language}.
It was developed by (and is still maintained by) Larry Wall of Netlabs.  It
is freely available
%%(though not strictly public domain)
software and compiles on nearly all major architectures and operating
systems.  These include all the major UNIX\footnote{``UNIX'' is a trademark
of AT\&T.  No, make that Unix Systems Laboratories.  Or maybe Novell, Inc
\ldots} variants as well as VMS and even DOS.

Perl contains features of the Bourne shell ({\tt /bin/sh}), {\tt awk}, {\tt  
sed}, and {\tt grep} as well as access to systems calls and C library
routines.
%  Many tasks which would normally be tackled with shell scripts
%and text processing utilities can be better written in Perl.
It is said that Perl fills the niche between shell scripts and C programs.

Perl is not a compiled language but it is faster than most interpreted
languages.  Before executing a Perl script, the {\tt perl} program reads
the entire script into memory and ``compiles'' it into a fast internal
format.  In nearly all cases, a Perl script is faster than its Bourne shell
analogue.  Note that by convention, one refers to the {\it P}erl language
in upper case and the {\it p}erl program in lower case.

This document is intended to be an overview of the major features of Perl
and does not describe every facet of the language.  Much more extensive
reference materials are available.  These references, as well as pointers
to example scripts, are detailed at the end of this document.

\newpage

\section{Basic Syntax}

Perl is a free-form language like C.  Perl's control flow structures are
very much like C's.  There are no FORTRAN-like line constraints.

Perl programs, by convention, sometimes end in {\tt .pl}.  This is not a
requirement, however, and most Perl scripts simply invoke the interpreter
through the use of the {\tt \#!} construct.  The first line of a Perl
script (at least in the UNIX world) usually looks like this:

\begin{verbatim}
#!/usr/local/bin/perl
\end{verbatim}

In Perl, every statement must end with a semicolon ({\tt ;}).  Text
starting with a pound sign ({\tt \#}) is treated as a comment and is
ignored.

Blocks of Perl code, such as those following conditional statements or in
loops are always enclosed in curly brackets ({\tt \{...\}}).

\section{Data Types}

Perl has three basic data types:

\begin{itemize}
\item scalars
\item arrays of scalars
\item associative arrays of scalars (also known as hash tables)
\end{itemize}

\subsection{Scalars}
The scalar is the basic data type in Perl.  A scalar can be an integer, a
floating point number, or a string.  Perl figures out what kind of variable
you want based on context.  Scalars variables {\it always} have a dollar
sign ({\tt \$}) prefix.  Therefore, a string assignment looks like this:

\begin{verbatim}
        $str = "hello world!";
\end{verbatim}
not:
\begin{verbatim}
        str = "hello world!";
\end{verbatim}

In Perl, an alphanumeric string with no prefix is (generally) assumed to be
a string literal.  Thus, the second statement above attempts to assign
string literal {\tt \verb|"hello world!"|} to string literal {\tt
\verb|"str"|}.

Perl's string quoting mechanisms are similar to those of the Bourne shell.
Strings surrounded in double quotes ({\tt "\ldots"}) are subject to
variable substitution.  Thus, anything that looks like a scalar variable is
evaluated (and possible interpolated) into a string.  Strings inside single
quotes ({\tt '\ldots'}) are passed through basically untouched.

Perl variables do not have to be declared ahead of time.  The are allocated
dynamically.  It is even possible to refer to non-existent Perl variables.
The default value for a variable in a numeric context is 0 and an empty
string in a string context.  Perl has a facility for determining whether a
variable is undeclared or if it is really is a zeroish value.

Perl variables are also typed and evaluated based on context.  String
variables which happen to contain numeric characters are interpolated to
actual numeric values if used in a numeric context.  Consider this code
fragment:

\begin{verbatim}
$x = 4;       # an integer
$y = "11";    # a string
$z = $x+$y;
print $z,"\n";
\end{verbatim}

\noindent
After this code is executed, {\tt \$z} will have a value of {\tt 15}.

This interpolation can also happen the other way around.  Numeric values
are formatted into strings if used in a string context.  Numeric values do
not have to be manually formatted as in C or FORTRAN.  This type of
interpolation takes place often when writing standard output.  For
instance:

\begin{verbatim}
$answer = 42;
print "the answer is $answer";
\end{verbatim}

\noindent
The output from this fragment would be ``the answer is 42''.

Note that integer constants may be specified in octal or hexadecimal as
well as in decimal.

String constants may be specified by way of ``here documents'' in the
manner of the shell.  Here documents start with a unique string and
continue until that string is seen again.  For example:

\begin{verbatim}
$msg = <<_EOM_;
   The system is going down.
   Log off now.
_EOM_
\end{verbatim}

\subsection{Arrays of Scalars}

Perl scripts can have arrays (or ``lists'') consisting of numeric values or
strings.  Entire array variables are prefixed with an ``at'' sign ({\tt
@}).  It is also possible to assign to the array elements by name.  Here
are some examples of valid Perl array assignments:

\begin{verbatim}
@numbers = (3,1,4,1,5,9);
@letters = ("this","is","a","test");
($word,$another_word) = ("one","two");
\end{verbatim}

\noindent
Of course, Perl array elements can also be referenced by index.  By
default, Perl arrays start at 0.  Perl array references look like this:

\begin{verbatim}
$blah[2] = 2.718281828;
$message[12] = "core dumped\n";
\end{verbatim}

\noindent
Note that since an array element is a scalar, it is prefixed by a \$.

The {\tt \$\#} construct is used to find out the last valid {\it index} of
an array rather than its size.  The {\tt \$[} variable indicates the base
index of arrays in a Perl script.  By default, this value is 0.  Here is a
code fragment which tells you the number of elements in an array:

\begin{verbatim}
# assume that @a is an array with a bunch of interesting elements
$n = $#a - $[ + 1;
print "array a has $n elements\n";
\end{verbatim}

\noindent
{\tt \$[} can be reset to use a different base index for arrays.  To have
FORTRAN-style array indexing, set {\tt \$[} to 1.

Arrays are expanded dynamically.  You need only assign to new array
elements as you need them.  You can pre-allocate array memory by assigning
to its {\tt \$\#} value.  For instance:

\begin{verbatim}
$#months = 11;     # array @months has elements 0..11
\end{verbatim}

Perl has operators and functions to do just about anything one would need to
do to an array.  There are facilities for pushing, popping, appending,
slicing, and concatenating arrays.

Perl can only do one-dimensional arrays but there are ways to fake
multi-dimensional arrays.

\subsection{Associative Arrays of Scalars}

Associative arrays are Perl's implementation of hash tables.  Associative
arrays are arguably the most unique and useful feature of Perl.  Common
applications of associative arrays include creating tables of users keyed
on login name and creating tables of file names.  The prefix for associative
arrays is the percent sign ({\tt \%}).

Associative arrays are keyed on strings (numeric keys are interpolated into
strings).  An associative array can be explicitly declared as a list of
key-value pairs.  For example:

\begin{verbatim}
%quota = ("root",100000,
          "pat",256,
          "fiona",4000);
\end{verbatim}

\noindent
Associative arrays elements are referenced in the following way:

\begin{verbatim}
$quota{dave} = 3000;
\end{verbatim}

\noindent
In this case, \verb|"dave"| is the key and {\tt 3000} is the value.  Note
that the reference above is to a scalar and is thus prefixed by a \$.

Here is another example.  In Perl scripts, there is a predefined
associative array called {\tt \%ENV} which contains all of the environment
variables of the calling environment.  Here is a bit of Perl code to see if
you are running X Windows:

\begin{verbatim}
if ($ENV{DISPLAY})
{
      print "X is (probably) running\n";
}
\end{verbatim}

There are routines for traversing the contents of associative arrays and
for deleting elements.  The relevant Perl routines are {\tt each}, {\tt
keys}, {\tt values}, and {\tt delete}.

Note that the namespace for Perl variables is exclusive.  One can refer to
scalars, arrays, associative arrays, subroutines, and packages with the
same name without fear of conflict.

\section{Operators and Comparators}

Perl's set of operators and comparators comprise nearly all of C's
operators and comparators.  All of the usual arithmetic expressions and
precedence are the same in Perl as they are in C.  Listed below are
expressions which are valid in Perl but not in C.  These descriptions are
paraphrased from the Perl man page.

\begin{description}
\item [{\tt **}] The exponentiation operator.
\item [{\tt **=}] The exponentiation assignment operator.
\item [{\tt ()}] The null list, used to initialize an array to null.
\item [{\tt  .}] Concatenation of two strings.
\item [{\tt .=}] The concatenation assignment operator.
\item [{\tt eq}] String equality ($==$ is  numeric  equality). Other
FORTRAN-style comparators are also available.  These are only used on
strings.
\item [{\tt =$\tilde{\ }$}] Certain operations search or modify the string {\tt
\$\_} by default.  This operator makes that kind of operation work on some
other string.  The right argument is a search pattern, substitution, or
translation.  The left argument is what is supposed to be searched,
substituted, or translated instead of the default {\tt \$\_}.
\item [{\tt x}]   The repetition operator.  
\item [{\tt ..}] The range operator
\item [{\tt -f, -x, -l, \ldots}] Unary file test operator.  Perl has the
ability to test various file permission settings in the same way as the
UNIX {\tt test} command.  Consult the Perl manual page for a full listing
of Perl file test operators.
\end{description}

\section{A Word about Default Arguments}

Many functions and syntactic structures in Perl have default arguments.  In
most cases, this default argument is the variable {\tt \$\_}.  While this
is a handy feature for experienced Perl programmers, it can make their code
incomprehensible to those just learning the language.  For novices, it can
be a nuisance when one does not understand how the value of {\tt \$\_} is
determined.

I recommend that when you are first learning Perl, put in all arguments
explicitly.  In many cases, Perl figures out what you are trying to do
based on context and assigns values to {\tt \$\_} according to its own
rules.  The value of {\tt \$\_} can change subtly (or even drastically)
depending on context.

Once you have a few lines of Perl under your belt and understand the ways
of {\tt \$\_}, feel free to use the default arguments.  It is a nifty
feature which allows you to write slick, fast, (and cryptic) Perl code.

\section{Regular Expressions}

Where once you had to execute a {\tt grep} or {\tt expr} every time you
wanted to compare a string to a regular expression (``regexp''), you can
now stick regexps right in your code.  Perl's regexp handling capabilities
are another reason that you'll never want to write another Bourne shell
script.

\subsection{Matching Regular Expressions}

Perl regular expressions look very much like those in {\tt vi}.

\begin{description}
\item [{\tt .}] Match any one character except a newline.
\item [{\it c}{\tt *}] Match zero or more instances of character {\it c}.
\item [{\it c}{\tt +}] Match one or more instances of character {\it c}.
\item [{\it c}{\tt ?}] Match zero or one instance of character {\it c}.
\item [{\tt [{\it class}]}] Match any of the characters in character class {\it
class}.  
\item [{\tt $\backslash$w}] Match an alphanumeric character (including
"\_")  
\item [{\tt $\backslash$W}] Match an non-alphanumeric character (including
"\_")  
\item [{\tt $\backslash$b}] Match a word boundary
\item [{\tt $\backslash$B}] Match non-boundaries
\item [{\tt $\backslash$s}] Match a whitespace character
\item [{\tt $\backslash$S}] Match a non-whitespace character
\item [{\tt $\backslash$d}] Match a numeric character
\item [{\tt $\backslash$D}] Match a non-numeric character
\item {\tt \verb|^  |} Match the beginning of a line
\item [{\tt \$}] Match the end of a line
\end{description}

\noindent
Also, $\backslash${\tt n}, $\backslash${\tt r}, $\backslash${\tt f},
$\backslash${\tt t} and $\backslash${\tt NNN} have their usual C-style
interpretations.

The actual syntax for the pattern matching command is {\tt m/}{\it
pattern}{\tt /gio}.  The modifiers are {\tt g} for ``global'' match, {\tt
i} for ``ignore case'', and {\tt o} for ``only compile this regexp once''.
With the {\tt m} command, you can use any pair of non-alphanumeric
characters to bound the expression.  This especially useful when matching
filenames that contain the ``/'' character.  For example:

\begin{verbatim}
if (m!^/tmp_mnt!)
{ print "$_ is an automounted file system\n"; }
\end{verbatim}

\noindent
If the delimiter you choose is ``{\tt /}'', then the leading {\tt m} is
optional.

Perl even has the ability to do multi-line pattern matching.  Refer to the
documentation on the {\tt \$*} variable for complete information.

\subsection{Extracting Matched String from Regexps}

As in {\tt vi}, {\tt grep}, and {\tt sed}, Perl can return substrings which
are matched in a regular expression.  For instance, here is some Perl code
to (sort of) emulate the UNIX {\tt basename} command:

\begin{verbatim}
$file = "/auto/home/pat/c/utmpdmp.c";
($base) = ($file =~ m|.*/([^/]+)$|);
\end{verbatim}

\noindent
The result of this code fragment is that {\tt \$base} has the value
\verb|"utmpdmp.c"|.  The parens in the regexp indicate the substring we
want to extract.

The return value of a regular expression match depends on context.  In an
array context, the expression returns an array of strings which are the
matched substrings.  In a scalar context, typically in a test to see
whether or not a string matches a regexp, the expression returns a 0 or 1.

Here is an example of a scalar context.  The {\tt <STDIN>} construct,
discussed in detail later, reads in one line of standard input.

\begin{verbatim}
$response = <STDIN>;
if ($response =~ /^\s*y/i)
{ print "you said yes\n"; }
\end{verbatim}

Note that the distinction between an ``array context'' and a ``scalar
context'' is important in Perl.  Many routines and syntactic structures
return different types of values depending on context.  We will say more
about array contexts later.

\section{Flow Control}

Perl has all of the flow control structures one normally expects in a
procedural language as well as a few extras.

\subsection{If-Then-Else}

The Perl {\tt if} statement has the same structure as in C.  Perl uses the
same conjunctions and boolean operators as C: {\tt \&\&} for ``and'', {\tt
||} for ``or'', and {\tt !} for ``not''.  One important note is that the
C-style one-statement {\tt if} construct cannot be used.  All of the code
following a Perl conditional ({\tt if}, {\tt unless}, {\tt while}, {\tt
foreach}) must be enclosed in curly brackets.  For instance, this C
fragment:

\begin{verbatim}
if (error < 0)
       fprintf(stderr,"error code %d received\n",error);
\end{verbatim}

\noindent
becomes this Perl fragment

\begin{verbatim}
if ($error < 0)
{ print STDERR "error code $error received\n"; }
\end{verbatim}

\noindent
The Perl analogue to C's {\tt else if} construct is {\tt elsif} and the
{\tt else} keyword works as expected.

Perl has an {\tt unless} statement which reverses the sense of the
conditional.  For instance:

\begin{verbatim}
unless ($#ARGV > 0)    # are there any command line arguments?
{ print "error; no arguments specified\n"; exit 1; }
\end{verbatim}

Perl's ideas about truth are similar to C.  In a numeric context, a
zero value is considered ``false'' and anything non-zero is ``true''.  An  
empty string is ``false'' and a string with a length of 1 or more is true.
Scalar arrays and associative arrays are considered ``true'' if they have
at least 1 member and ``false'' if empty.  Non-existent variables, since
they are always 0, are ``false''.

%%% note the more obscure ways to use ``if''
%%% goto, labels

Note that Perl does not have a {\tt case} statement because there are
numerous ways to emulate it.

\subsection{The {\tt while} statement}
% next, last

Perl's {\tt while} statement is very versatile.  Since Perl's notion of
truth is very flexible, the {\tt while} condition can be one of several
things.  As in C, Perl conditional statements can be actions or functions.

For instance, the {\tt <STDIN>} statement with no argument assigns a line
of standard input to the {\tt \$\_} variable.  To loop until the standard
input ends, this syntax is used:

\begin{verbatim}
while (<STDIN>)
{
      print "you typed ",$_;
}
\end{verbatim}

\noindent
In keeping with the recommended beginner practice of including all default
arguments, that code would look like this:

\begin{verbatim}
while ($_ = <STDIN>)
{
      print "you typed ",$_;
}
\end{verbatim}

As stated before, an array is ``true'' if it has any elements left.  For
instance:

\begin{verbatim}
@users = ("nigel","david","derek","viv");
while (@users)
{
     $user = shift @users;
     print "$user has an account on the system\n";
}
\end{verbatim}

\noindent
This {\tt while} loop will continue as long as {\tt @users} has at least
one element.  The {\tt shift} routine pops the first element off the named
array and returns it.

Perl has two keywords used for shortcutting loop operations.  The {\tt
next} keyword is like C's {\tt continue} statement.  It will immediately
jump to the next iteration of innermost loop.  The {\tt last} keyword will
break out of the current conditional statement.  It is analogous to C's
{\tt break} statement.

\subsection{The {\tt for} and {\tt foreach} statements}

The {\tt for} and {\tt foreach} statements in Perl are actually identical.
They can be used interchangeably in any context.  Depending on what job is
being performed, however, one usually make more sense than the other.

Just to make things more confusing, there are two ways that the {\tt
for}/{\tt foreach} statement can be used.  One way is exactly like C's
3-argument {\tt for} statement.  For instance:

\begin{verbatim}
@disks = ("/data1","/data2","/usr","/home");
for ($i=0; $i <= $#disks; ++$i)
{ print $disks[$i],"\n"; }
\end{verbatim}

\noindent
However, once you understand Perl's built-in ways of iterating over an
array's elements, you will almost {\it never} need to use the 3-argument
{\tt for} statement.

Perl's one-argument {\tt foreach} statement is similar to the {\tt foreach}
statement in the C Shell.  Given an array argument, the {\tt foreach}
statement will iteratively return that array's elements.  This contrasts
with the destructive traversal demonstrated before with the {\tt while} and
{\tt shift} statements.

The code fragment we just saw can be rewritten as:

\begin{verbatim}
@disks = ("/data1","/data2","/usr","/home");
foreach(@disks)
{ print $_,"\n"; }
\end{verbatim}

\noindent
This construct is much more elegant and does not (necessarily) destroy the
contents of {\tt @disks}.

An subtle but important point to note is that, in the fragment above, {\tt
\$\_} is really a pointer into the array, not simply a copy of a value.  If
the code in the loop modifies the {\tt \$\_}, the array is changed.

\subsection{Goto}

Yes, Perl even has a {\tt goto} statement.  {\tt goto} {\it label} will
send control of the program to the named label.  The usual caveats against
GOTOs apply in Perl as elsewhere.  Don't use GOTOs unless you really need
them!

\section{Built-In Routines, C Library Routines, and System Calls}

Perl has a rich set of built-in routines and access to most of the
interesting functions in the C library.  The manual pages for Perl go into
exhaustive detail about all of these routines so I will simply discuss a
few of the more commonly used ones.  Most of these descriptions are
paraphrased from the man pages.\footnote{And a few are shamelessly copied
word for word} The default argument for most of these routines is {\tt
\$\_}.  Note that parentheses around function parameters are
usually optional.

\subsection{Built-In Routines}
\begin{description}
\item [{\tt chop {\it expr}}] Chop off the last character of a string and
return the character.  This might not seem like a very interesting thing to
do until you understand Perl file I/O.  Upon reading a line of input into a
variable, Perl preserves the newline ($\backslash${\tt n}).  Usually, you
don't need the newline so you probably want to {\tt chop} it off.
\item [{\tt defined {\it expr}}] Determine whether or not the named
variable really exists or not.  This function will return true if the named
variable has a value and is not simply undefined.
\item [{\tt die {\it expr}}] Utter a final message and pass away.  This
function will print out a string argument and then cause the script to
terminate.  It is used most often when some kind of fatal error occurs.
\item [{\tt each} {\it array}] Return the key-value pairs of an associative
array in an iterative manner.
\item [{\tt join} {\it expr},{\it array}] Joins the separate strings of
{\it array} into a single string with fields separated by the value of {\it
expr}, and returns the string.
% \item [{\tt pack}]  
\item [{\tt pop} {\it array}] Pop off the top element off the named array
and shorten the array by one.
\item [{\tt print} {\it expr}] Print out the arguments.  More on the {\tt
print} function later.
%\item [{\tt printf}]  
\item [{\tt push} {\it array},{\it list}]  Treat {\it array} as a stack and
push the values of {\it list} on to the stack.  Has the effect of
lengthening the array.
\item [{\tt shift}]  Shifts the first value of the array off and returns
it, shortening the array by 1 and moving everything down.  Shift() and
unshift() do the same thing to the left end of an array that push() and
pop() do to the right end.
%\item [{\tt sort}]  
\item [{\tt split}(/{\it pattern}/,{\it expr},{\it limit}]) Splits a string
into an array of strings and returns it.  The pattern is treated as a
delimiter separating the fields.  A common use of this function is to split
up lines of the UNIX {\tt /etc/passwd} file into its component fields.
This is similar {\tt awk}'s functionality only more versatile.
\item [{\tt substr} {\it expr},{\it offset},{\it len}] Extract a substring
out of {\it expr} and returns it.
%\item [{\tt unpack}]  
%\item [{\tt values}]  
\end{description}

\subsection{UNIX-type Utility Routines}

\begin{description}
\item [{\tt chmod}] Change the permission bits of the named files.
\item [{\tt chown}] Change the owner and group of the named files.
\item [{\tt mkdir}] Make directories.
\item [{\tt unlink}] Remove a file.
\item [{\tt rename}] Rename a file.
\item [{\tt rmdir}] Remove a directory.
\end{description}

\subsection{C Library Routines}

Many C library routines can be accessed in Perl.  This is a sampling of
them.

\begin{description}
\item [{\tt getpw\*, getgr\*, \ldots}] Perl has access to all of the C
routines which access passwd, group, and hostname information.
\item [{\tt bind, connect, socket, \ldots}] Interprocess communication
facilities are available in Perl.
\item [{\tt stat}] Access file information via the UNIX {\tt stat(2)}
library routine.
\item [{\tt exit}] Exit the program with the specified exit status.
\end{description}

\section{Operating System Interaction}

Perl can execute system commands in several ways.  

Perl can run shell commands via the {\tt system} routine.  This acts
essentially like C's {\tt system(3)} call.  A string is passed to the shell
for execution.  The output from the command is sent to standard output.
The exit status is put into the {\tt \$?} variable.\footnote{Actually, the
entire status word is put into {\tt \$?}.  Read the man page for details.}

Perl also evaluates backquotes (also known as ``backticks'' or ``grave
accents'') in way similar to the shell.  This is useful when you want to
run a shell command and capture the output.  Here is an example in which a
script gets the name of the host:

\begin{verbatim}
$host = `hostname`;
chop($host);
\end{verbatim}

\noindent
Again, the exit status of this command will be put into {\tt \$?}.  Note
that we need to {\tt chop} off the newline from the output.

% mention BSD networking, sockets
\section{File Handling}

%% open,close,<..>,read,write,eof  >>,>, |

Perl's has I/O routines for reading and writing text files as well as
``unformatted'' files.

\subsection{Text I/O}

Perl reads and writes text files by way of filehandles.  By convention,
filehandles are usually in upper case.

Files are opened by way of the {\tt open} command.  This command is given
two arguments: a filehandle and a file name (the file name may be prefixed
with some modifiers).  Lines of input are read by evaluating a filehandle
inside angled brackets ({\tt <\ldots>}).  Here is an example which reads
through a file:

\begin{verbatim}
open(F,"data.txt");
while($line = <F>)
{
    # do something interesting with the input
}
close F;
\end{verbatim}

The file name argument can have one of several prefixes.  If the file name
is prefixed with {\tt <}, the file is opened for reading.  (This is the
default action.)  If the file name is prefixed with {\tt >} then it is
opened for writing.  If the file exists, it is truncated and opened.
Finally, a prefix of {\tt >>} opens the file for appending.  Here are a few
examples:

\begin{verbatim}
# peruse the passwd file
open(PASSWD,"</etc/passwd");
while ($p = <PASSWD>)
{
     chop $p;
     @fields= split(/:/,$p);
     print "$fields[0]'s home directory is $fields[5]\n";
}
close PASSWD;

# enter some information into a log file
open(LOG,">>user.log");
print LOG "user $user logged in as root\n";

# read a line of input from the user
$response = <STDIN>;
\end{verbatim}

There are 3 predefined filehandles which have obvious meanings: {\tt
STDIN}, {\tt STDOUT}, and {\tt STDERR}.  Trying to redefine these
filehandles with {\tt open} statements will cause strange things to happen.
{\tt STDOUT} is the default filehandle for {\tt print}.

Perl's file input facility acts very differently if it is called in an
array context.  If input is being read in to an array, the {\it entire}
file is read in as an array of lines.  For instance:

\begin{verbatim}
$file = "some.file";
open(F,$file);
@lines = <F>;   # suck in the whole file.  yum, yum,...
close F;
\end{verbatim}

\noindent
This capability, though useful, should be used with great care.  Ingesting
whole files into memory can be a risky thing to do if you do not
necessarily know what size files you are dealing with.  Perl already does a
certain amount of input buffering so reading in a file at once does not
necessarily yield an increase in I/O performance.

\subsection{Pipes}

Perl can use the {\tt open} routine to run shell commands and read or
write to them in the manner of C's {\tt popen(3S)} call.

If a file name argument {\it starts} with the pipe character ({\tt |}), the
file name is treated as a command.  The command is then executed and the
program can be sent input via the {\tt print} command.

If the file name argument {\it ends} with a pipe, the command is executed
and that command's output can be read using the {\tt <\ldots>} facility.
Here are two examples:

\begin{verbatim}
open(MAIL,"| Mail root");   # send mail to root
print MAIL "user \"pat\" is up to no good\n";
close MAIL;                 # mail is now sent

open(WHO,"who|");   # see who's on the system
while ($who = <WHO>)
{
    chop $who;
    ($user,$tty,$junk) = split(/\s+/,$who,3);
    print "$user is logged on to terminal $tty\n";
}
close(WHO);
\end{verbatim}

\subsection{Unformatted File Access}

Perl can do direct reading and writing of bytes via the {\tt sysread} and
{\tt syswrite} calls.

Given the narrow scope of this introduction to Perl, I will not discuss
these functions.  The references at the end provide complete information.

\subsection{Use of the {\tt print} command}

We have already seen several examples of the use of the {\tt print} command
in Perl.  Now perhaps is a good time to see a more exact description of
what it does.

The print command is very flexible and, in most cases, can do the same
thing several different ways.  In general, {\tt print} takes a series of
strings separated by commas, does any necessary variable interpolation,
and then prints out the result.  The string concatenation operator (.) is
often used with {\tt print}.  All of the following lines yield the same
output.  

\begin{verbatim}
print "But these go to 11.\n";
$level = 11;
print "But these go to ",$level,".\n";
print "But these go to $level.\n";
printf "But these go to %d.\n",$level;
print "But these " . "go to ". $level.".\n";
print join(' ',("But","these","go","to","$level.\n"));
\end{verbatim}

\noindent
As you can see, the C-style {\tt printf} command is available.  However,
because of Perl's ability to automatically interpolate numeric values to
strings, {\tt printf} is rarely needed.

There are, in fact, subtle performance issues that can be addressed with
each of the methods in the example above.  Wall and Schwartz's book, listed
in the references, talks about these issues.

As seen in several of the previous examples, the {\tt print} command also
takes an optional filehandle argument.   

\section{Some Notes about Perl Array Contexts}

In C, every expression yields some kind of value.  That value can be used
as input to another routine without having to store it in a temporary
variable.  Thus, you can do things like {\mbox {\tt
chdir(getenv("HOME"))}}.

In Perl, many routines and contexts yield arrays.  These resultant arrays
can be passed to other routines, iterated over, and subscripted.  This
eliminates the need for many temporary variables.

Here are a few examples.  In this first case, we use the {\tt sort}
routine.  This routine takes an array as a parameter and passes back a
sorted version of the same array.

\begin{verbatim}
@names = ("bill","hillary","chelsea","socks");
@sorted = sort @names;
foreach $name (@sorted)
{ print $name,"\n"; }
\end{verbatim}

\noindent
In fact, one can iterate directly over the output from {\tt sort}.

\begin{verbatim}
foreach $name (sort @names)
{ print $name,"\n"; }
\end{verbatim}

\noindent
This example shows that we can even put a subscript on an array context.

\begin{verbatim}
$name = (getpwuid($<))[6];
print "my name is ",$name,"\n";
\end{verbatim}

\noindent
The function {\tt getpwuid} returns an array.  We want the ``real name''
(or GECOS) field from the passwd entry so we put a subscript of {\tt [6]}
on the array context and put the result in {\tt \$name}.

\section{Subroutines and Packages}

Perl has the ability to do modular programming by way of subroutines and
libraries.

\subsection{Subroutines}

Perl scripts can contain functions (usually called ``subs'') which have
parameters and can return values.  Listed below is a skeleton for a Perl
sub called {\tt sub1}.

\begin{verbatim}
sub sub1
{
      local($param1,$param2) = @_;
# do something interesting
      $value;
}
\end{verbatim}

\noindent
This sub can then be called in this way:

\begin{verbatim}
$return_val = do sub1("this is","a test");
\end{verbatim}

\noindent
The {\tt do} can be replaced by {\tt \&}.  This is actually the preferred
method:

\begin{verbatim}
$return_val = &sub1("this is","a test");
\end{verbatim}

There are a few thing to keep in mind when writing subroutines.  Parameters
are put into the array {\tt @\_} inside the routine.  Since all variables
are global by default, we use the {\tt local()} function to copy the
values into local variables.

%%% need more info on local()
%%% remember when i said you didn't have to declare variables?  i lied.

Perl has a {\tt return} statement which can be used to explicitly return
values.  This is usually unnecessary, however, because the return value
from a Perl subroutine is simply the value of the last statement executed.
Thus, if you want a subroutine to return a zero, the last line of the
routine can be {\tt 0;}.

\subsection{Packages}

Perl has a library of useful routines which you can include in your
scripts.  The Perl analogue of C's {\tt \#include} statement is {\tt
require}.

For instance, Perl has a library to do command-line parsing similar to C's
{\tt getopt(3)} function.

\begin{verbatim}
require 'getopts.pl';
&Getopts('vhi:');
if ($opt_v) { print "verbose mode is turned on\n"; }
\end{verbatim}

It is also possible to write your own libraries and include them in other
scripts.

\section{Predefined Variables}
%% $_, $?, $<, @_, %ENV, %SIG, @ARGV

Perl has a sizable set of predefined variables.  These are all documented
in detail in the man pages so I will only describe a few of the common
ones.

\begin{description}
\item [{\tt \$\_}] Default argument for many routines and syntactic
structures.  
\item [{\tt \$?}] Status word returned from last system call.  The lower
bytes contain the signal upon which the program died (if any) and the upper
bytes contain the exit code.
\item [{\tt \$\$}] Process ID of script.
\item [{\tt \$<}] Real user ID of user running script.
\item [{\tt @ARGV}] Command-line arguments of script.  Note that {\tt
\$ARGV[0]} is the first actual argument, not the name of the program (as in
C).  The name of the script is in the variable {\tt \$0}.
\item [{\tt \%ENV}] Associative array containing the environment variables
of the calling environment.
% also: $!, $*, @INC, %SIG
\end{description}

\section{Command Line Options}

Perl has a set of command-line switches.  Here are a few of the most useful
ones.

\begin{description}
\item [{\tt -c}] Check the syntax of a Perl script but do not execute it.
\item [{\tt -e}] Specify Perl code on the command line.
\item [{\tt -w}] Warn the programmer about any questionable uses of
variables.  These include variable used only once and variables which are
referenced before being assigned.  New Perl programmers are advised to
check their scripts with {\tt perl -c -w }{\it script.pl}.
\end{description}
%  -n, -p, -i

\section{References}

\subsection{Manuals and Books}
% man page

There are several very good references to Perl available.  The first and
foremost is the Perl manual page.  It is about 90 pages long and describes
all aspects of Perl, albeit in a terse manner.  For me, it is the reference
of first resort since I can scan through it in an Emacs buffer.

% programming perl

The book \underline{Programming Perl} by Perl author Larry Wall and Randal
Schwartz is the definitive compendium of all things Perl.  It is known
colloquially as ``the Camel book'' due to O'Reilly and Associates' habit of
putting animals on the covers of their books, in the case a camel.  It
should be noted, however, that it is not the best book to buy for learning
Perl from scratch simply because it is so big.  It is a better book to read
once you know the basics.

% learning perl

There is a book due out sometime this fall by Randal Schwartz called
\underline{Learning Perl}.  It is being written presumably in response to
the difficulty of learning Perl from the \underline{Programming Perl} book.

There is a Usenet newsgroup devoted to the Perl language called {\tt
comp.lang.perl}.  This is a forum for discussing nuances of Perl and asking
questions about the language.  New Perl programmers are encouraged to read
the manual pages and the Perl FAQ (mentioned below) and to consult
experienced local Perl programmers before posting to the group.

\subsection{How to get Perl}

% ftp, archie, jaameri

The current version of Perl is 4.036.  Although version 5 is in alpha test
right now, version 4 is the stable version.  Version 4 can be found via the
{\tt archie} protocol at hundreds of ftp sites.

I have put the current version of Perl in the anonymous ftp account on my
machine.  The code can be found at:

\begin{verbatim}
jaameri.gsfc.nasa.gov:/pub/perl/perl-4.036.tar.gz
\end{verbatim}

There are several useful things in that directory.  They are:

\begin{itemize}
\item {\tt perl-mode.el}  An Emacs major mode for editing Perl code.
\item {\tt perl.faq} The list of Frequently-Asked Questions about Perl.
\item {\tt refguide.ps} PostScript format reference guide for perl 4.036.
\item {\tt examples/} A directory of example Perl scripts
\end{itemize}

The directory of example scripts is a good place to start hacking with real
Perl code.  Even though I refer to these as ``example'' scripts, they are
all real Perl scripts that I wrote to solve real problems.

I welcome comments, bug fixes, fan mail, et cetera about anything in the
ftp directory or about Perl in general.  I can be reached at {\tt
patrick.m.ryan@gsfc.nasa.gov}.

\end{document}

%  stuff left out:
%
%    <>
%    <*.c>
%    -i, -p, -n
%    eval
%    action if /something/;
%    DBM
%    array slicing
%    formats
%    range operator
%    repetition operator
%    pack, unpack
%    suidperl, taintperl, (sybperl, oraperl, cursperl)
%    $tmp = $opt_t || $ENV{TMPDIR} || "/tmp";
%    *type checking
%    s/../../, tr/../../
%    one-liners: ala ``fixer''
%
%
%
%

.
