\documentclass{ictlab}

% Copyright (c) 2003 by Nick Urbanik <nicku(at)nicku.org>.
% This material may be distributed only subject to the terms and
% conditions set forth in the Open Publication License, v1.0 or later
% (the latest version is presently available at
% http://www.opencontent.org/openpub/).

\RCS $Revision: 1.7 $

\usepackage{textcomp,alltt,amstext}
\ifx\pdftexversion\undefined \else
  \usepackage[pdfpagemode=None,pdfauthor={Nick Urbanik}]{hyperref}
\fi

\newcommand*{\labTitle}{An Introduction to Perl}

\begin{document}
Log into your Linux account.  If you forgot your password, come
over to me to reset it to something of your choice.

Open the editor of your choice; available options are:

\texttt{emacs}, \texttt{xemacs}, \texttt{vi}, \texttt{gvim},
\texttt{gnp}, \texttt{pico}, \texttt{gedit}, and many others.


\section{Background}
\label{sec:background}

\subsection{Reading Perl documentation}
There is a huge amount of documentation about Perl installed on your
computer; if you printed it all out, it would fill many books.  There
is a cross-platform program called \texttt{perldoc} that allows you to
examine and search the documentation.


\paragraph{Reading about basic Perl syntax:}

\texttt{perldoc perlsyn}

\paragraph{Figuring out which documentation to read:}

\texttt{perldoc perl}

\paragraph{How to search the FAQ:}

This searches the headings of the questions for text that matches
\meta{string}.

\texttt{perldoc -q \meta{string}}

As you will see later, the string could be a regular expression.

\paragraph{How to read about built in Perl functions:} The
Perl built-in functions are all described in detail in the
\texttt{perlfunc} man page.  But there is a handy tool for reading
about a single built-in function:

\texttt{perldoc -f \meta{function}}

This works in Windows as well as Linux\@.

\paragraph{Finding out about operators:}

The man page for Perl operators is called \texttt{perlop}.

\paragraph{Finding out about statements:}

The man page for Perl syntax is called \texttt{perlsyn}.  To read
about \emph{backwards} statements, see the section there called
\emph{simple statements}.

\paragraph{Finding out about regular expressions:}
\label{sec:regexp-docs}

\texttt{perlrequick} and \texttt{perlretut} are tutorials for Perl
regular expressions.  The reference for regular expressions is called
\texttt{perlre}.

\paragraph{Nick's Handy Perl summary}

A good overview is at
\url{http://nicku.org/snm/lectures/perl/perl.pdf}


\subsection{Reading from Standard Input}
\label{sec:stdin}

To read a line from standard input, simply do something like this:
\begin{verbatim}
my $input = <STDIN>;
chomp $input; # to remove the newline that will be at the end of the line
\end{verbatim}


\subsection{The special variable \texttt{\$\_}}
\label{sec:dollar-underscore}

In Perl, most built in functions, statements and operators work with a
special variable called \texttt{\$\_}.  For example, the following
\texttt{while} loop reads standard input one line at a time, and
prints that line:
\begin{verbatim}
while ( <STDIN> ) {
    print;
}
\end{verbatim}
Notice that the \texttt{while} loop reads one line into \texttt{\$\_}
at each iteration.  The built in \texttt{print} statement prints the
value of \texttt{\$\_} if you do not tell it to print anything else.

\subsection{About the angle operator: \texttt{<>}}
\label{sec:about-<>}

Many of the programs you will write will use the \emph{angle
  operator}, `\texttt{<>}'.  Since we need it here, I'd better explain
what it does.

First, let us understand the terms \emph{command line} and
\emph{command-line arguments}.  Suppose you
have a program called \texttt{angle-brackets.pl}.  If you execute it
like this:
\begin{verbatim}
angle-brackets.pl
\end{verbatim}
then you have no \emph{command line arguments} passed to the program.
However, if you execute it like this:
\begin{verbatim}
angle-brackets.pl file_1 file_2 file_3
\end{verbatim}
then the \emph{command line} has three \emph{arguments}, which here,
happen to be the names of files.

Now lets try to understand what happens when you do something like
this in a program:
\begin{verbatim}
@array = <>;
\end{verbatim}
Here I've written in pseudocode what happens:
\begin{verbatim}
if there are no command line arguments,
    while there are lines to read from standard input
        read each line from standard input
        put it into the array as the next element
else
    for each command line argument
        open the file
        while there are lines to read
            read each line from the file
            put it into the array as the next element
        close the file        
\end{verbatim}
So if \texttt{file\_1} contains:
\begin{verbatim}
line 1 of file_1
line 2 of file_1
\end{verbatim}
and \texttt{file\_2} contains:
\begin{verbatim}
first line of file_2
second line of file_2
\end{verbatim}
and the program \texttt{angle-brackets.pl} contains:
\begin{verbatim}
#! /usr/bin/perl
@array = <>;
print @array;
\end{verbatim}
If you run the program like this:
\begin{verbatim}
angle-brackets.pl file_1 file_2
\end{verbatim}
then the output will look like this:
\begin{verbatim}
line 1 of file_1
line 2 of file_1
first line of file_2
second line of file_2
\end{verbatim}
Specifically, the first element of the array is \texttt{\$array[0]},
and has the scalar value ``\texttt{line 1 of file\_1}\bs n''; the second
element of the array is \texttt{\$array[1]},
and has the scalar value ``\texttt{line 2 of file\_1\bs n}'', while the
last element of the array is \texttt{\$array[3]}, which contains the
scalar value ``\texttt{second line of file\_2\bs n}''.

The \texttt{<>} operator is most commonly used in a \texttt{while}
loop, rather like this:
\begin{alltt}
while ( <> ) \{
    \meta{commands to be executed for each line of input}
\}
\end{alltt}


\subsection{Finding matching lines}
\label{sec:matching-lines}


\paragraph{Backwards \texttt{if} statement:}

With Perl, there is more than one way to do it
(\TIMTOWTDI{}${}^{\mbox{\texttrademark}}$).  In particular, as well as
normal \texttt{while}, \texttt{if} statements, you can put them
\emph{backwards} if you want to. The backwards \texttt{if} statement
works like this:
\begin{alltt}
\meta{expr1} \textbf{if} \meta{condition}\textbf{;}
\end{alltt}
Note that braces and parentheses are not used. Backwards statements
are just for when you want to do \emph{one} thing if an expression is
true.


\paragraph{Matching Lines:}

Use regular expressions to find matching lines.  This little program
will print all lines on the input that contain the string
``\texttt{string}'':
\begin{verbatim}
while ( <> ) {
    print if /string/;
}
\end{verbatim}

\section{What to do}
\label{sec:what-to-do}


\begin{enumerate}
\item Write a program that calculates the circumference of a circle
  with a radius of 12.5.  The circumference is $C=2\pi r$, and $\pi
  \approx 3.1415927$.
  
\item Modify the program you just wrote to prompt for and read the
  radius from the person who runs the program.  See
  section~\vref{sec:stdin}.

\item Write a program that prompts for and reads two numbers, and
  prints out the result of multiplying the two numbers together.
  
\item Write a program that prompts for and reads a string and a
  number, and prints the string the number of times indicated by the
  number, on separate lines.  Hint: read about the ``\texttt{x}''
  operator.
  
\item Write a program that works like \texttt{cat}, but reverses the
  order of the lines.  It should read the lines from files given on
  the command line, or from standard input if no files are given on
  the command line.  Hints: read about the built-in \texttt{reverse}
  function.  You will want to use an array.  Read
  sections~\ref{sec:dollar-underscore} and~\vref{sec:about-<>}.
\end{enumerate}


\subsection{Regular Expresssions}
\label{sec:regular-expressions}

You will need to do a little research to answer these questions.  Read
section~\vref{sec:matching-lines}, then read the Perl documentation
about regular expressions I pointed to in
section~\vref{sec:regexp-docs}.

\begin{enumerate}
\item Write a program that will read one or more files on the command
  line, and print all lines from these files that have at least one
  `\textbf{\texttt{z}}' followed by any number of
  \textbf{`\texttt{y}}'s.  So it would match lines containing any one of
  these words:

%\begin{verbatim}
\texttt{z \ 
breezy \ 
buzzy \ 
cozy \ 
crazy \ 
dizzy \ 
enzyme \ 
frenzy \ 
fuzzy \ 
hazy \ 
jazzy \ 
lazy \ 
lazybones \ 
Lizzy \ 
snazzy}
%\end{verbatim}
  
\item Write a regular expression that will recognise a floating point
  number that Perl will recognise.  Here are a few examples of
  literal floating point numbers that you can use in a Perl program:

  \smallskip

  \begin{tabular}[t]{@{}>{\ttfamily}ll@{}}
    +1 & A leading plus or minus is optional, so is the decimal point \\
    1.25 & \\
    7.25e45 & $7.25 \times 10^{45}$ \\
    -6.5e24 & $-6.5 \times 10^{24}$ \\
    -12e-24 & $-12 \times 10^{-24}$ \\
    -1.2E-23 & $-1.2 \times 10^{-23}$ which equals $-12 \times 10^{-24}$
  \end{tabular}
  
\item Write a short program that reads files and prints all valid
  floating point numbers contained in them, one to a line, but does
  not print any other output.  Read about using parentheses for
  \emph{capturing} matched values.
\end{enumerate}
\end{document}

