## Part I    Programming Perl

### 1 Perl Data Types

#### 1.1 Funny Characters

Type Character Example Is a name for:
Scalar cents An individual value (number or string)
Array @ @large A list of values, keyed by number
Hash % %interest A group of values, keyed by string
Subroutine & &how A callable chunk of Perl code
Typeglob * *struck Everything named struck

#### 1.2 Singularities

Strings and numbers are singular pieces of data, while lists of strings or numbers are plural. Scalar variables can be assigned any form of scalar value: integers, floating-point numbers, strings, and even esoteric things like references to other variables, or to objects.

As in the Unix shell, you can use different quoting mechanisms to make different kinds of values. Double quotation marks (double quotes) do variable interpolation and backslash interpolation (such as turning /n into a newline) while single quotes suppress interpolation. And backquotes (the ones leaning to the left) will execute an external program and return the output of the program, so you can capture it as a single string containing all the lines of output.

$answer = 42; # an integer$pi = 3.14159265; # a "real" number
$avocados = 6.02e23; # scientific notation$pet = "Camel"; # string
$sign = "I love my$pet"; # string with interpolation
$cost = 'It costs$100'; # string without interpolation
$thence =$whence; # another variable's value
$salsa =$moles * $avocados; # a gastrochemical expression$exit = system("vi $file"); # numeric status of a command$cwd = pwd; # string output from a command

And while we haven't covered fancy values yet, we should point out that scalars may also hold references to other data structures, including subroutines and objects.

$ary = /@myarray; # reference to a named array$hsh = /%myhash; # reference to a named hash
$sub = /&mysub; # reference to a named subroutine$ary = [1,2,3,4,5]; # reference to an unnamed array
$hsh = {Na => 19, Cl => 35}; # reference to an unnamed hash$sub = sub { print $state }; # reference to an unnamed subroutine$fido = new Camel "Amelia"; # reference to an object
Following the principle of least surprise, the variable is created with a null value, either "" or 0. Depending on where you use them, variables will be interpreted automatically as strings, as numbers, or as "true" and "false" values (commonly called Boolean values). Perl will automatically convert the data into the form required by the current context, within reason. For example, suppose you said this:
$camels = '123'; print$camels + 1, "/n";

The original value of $camels is a string, but it is converted to a number to add 1 to it, and then converted back to a string to be printed out as 124. Similarly, a reference behaves as a reference when you give it a "dereference" context, but otherwise acts like a simple scalar value. For example, we might say: $fido = new Camel "Amelia";
if (not $fido) { die "dead camel"; }$fido->saddle();

#### 1.3 Pluralities

Perl has two types of multivalued variables: arrays and hashes.
##### 1.3.1 Array
An array is an ordered list of scalars, accessed[6] by the scalar's position in the list. To assign a list value to an array, you simply group the values together (with a set of parentheses):
@home = ("couch", "chair", "table", "stove");

Conversely, if you use @home in a list context, such as on the right side of a list assignment, you get back out the same list you put in. So you could set four scalar variables from the array like this:

($potato,$lift, $tennis,$pipe) = @home;

These are called list assignments. They logically happen in parallel, so you can swap two variables by saying:

($alpha,$omega) = ($omega,$alpha);
##### 1.3.3 Complexities
Perl lets you manipulate simple scalar references that happen to refer to complicated arrays and hashes. To extend our previous example, suppose we want to switch from talking about Adam's wife to Jacob's wife. Now, as it happens, Jacob had four wives. (Don't try this at home.) In trying to represent this in Perl, we find ourselves in the odd situation where we'd like to pretend that Jacob's four wives were really one wife. (Don't try this at home, either.) You might think you could write it like this:
$wife{"Jacob"} = ("Leah", "Rachel", "Bilhah", "Zilpah"); # WRONG But that wouldn't do what you want, because even parentheses and commas are not powerful enough to turn a list into a scalar in Perl. (Parentheses are used for syntactic grouping, and commas for syntactic separation.) Rather, you need to tell Perl explicitly that you want to pretend that a list is a scalar. It turns out that square brackets are powerful enough to do that: $wife{"Jacob"} = ["Leah", "Rachel", "Bilhah", "Zilpah"]; # ok
That statement creates an unnamed array and puts a reference to it into the hash element $wife{"Jacob"}. suppose we wanted to list not only Jacob's wives but all the sons of each of his wives. In this case we want to treat a hash as a scalar. We can use braces for that. (Inside each hash value we'll use square brackets to represent arrays, just as we did earlier. But now we have an array in a hash in a hash.) $kids_of_wife{"Jacob"} = {
"Leah" => ["Reuben", "Simeon", "Levi", "Judah", "Issachar", "Zebulun"],
"Rachel" => ["Joseph", "Benjamin"],
"Bilhah" => ["Dan", "Naphtali"],
};

That would be more or less equivalent to saying:

$kids_of_wife{"Jacob"}{"Leah"}[0] = "Reuben";$kids_of_wife{"Jacob"}{"Leah"}[1] = "Simeon";
$kids_of_wife{"Jacob"}{"Leah"}[2] = "Levi";$kids_of_wife{"Jacob"}{"Leah"}[3] = "Judah";
$kids_of_wife{"Jacob"}{"Leah"}[4] = "Issachar";$kids_of_wife{"Jacob"}{"Leah"}[5] = "Zebulun";
$kids_of_wife{"Jacob"}{"Rachel"}[0] = "Joseph";$kids_of_wife{"Jacob"}{"Rachel"}[1] = "Benjamin";
$kids_of_wife{"Jacob"}{"Bilhah"}[0] = "Dan";$kids_of_wife{"Jacob"}{"Bilhah"}[1] = "Naphtali";
$kids_of_wife{"Jacob"}{"Zilpah"}[0] = "Gad";$kids_of_wife{"Jacob"}{"Zilpah"}[1] = "Asher";
##### 1.3.4 Simplicities

Perl also has several ways of topicalizing. One important topicalizer is the package declaration. Suppose you want to talk about Camels in Perl. You'd likely start off your Camel module by saying:

package Camel;
Perl will assume from this point on that any unspecified verbs or nouns are about Camels. It does this by automatically prefixing any global name with the module name "Camel::".

When you say package Camel, you're starting a new package. But sometimes you just want to borrow the nouns and verbs of an existing package. Perl lets you do that with a use declaration, which not only borrows verbs from another package, but also checks that the module you name is loaded in from disk. In fact, you must say something like:

use Camel;

before you say:

#### 1.5 Filehandles

A filehandle is just a name you give to a file, device, socket, or pipe to help you remember which one you're talking about, and to hide some of the complexities of buffering and such. (Internally, filehandles are similar to streams from a language like C++ or I/O channels from BASIC.)
You create a filehandle and attach it to a file by using open. The open function takes at least two parameters: the filehandle and filename you want to associate it with. Perl also gives you some predefined (and preopened) filehandles. STDIN is your program's normal input channel, while STDOUT is your program's normal output channel. And STDERR is an additional output channel that allows your program to make snide remarks off to the side while it transforms (or attempts to transform) your input into your output.
open(SESAME, "filename") # read from existing file
open(SESAME, "<filename") # (same thing, explicitly)
open(SESAME, ">filename") # create file and write to it
open(SESAME, ">>filename") # append to existing file
open(SESAME, "| output-pipe-command") # set up an output filter
open(SESAME, "input-pipe-command |") # set up an input filter

As you can see, the name you pick for the filehandle is arbitrary. Once opened, the filehandle SESAME can be used to access the file or pipe until it is explicitly closed (with, you guessed it, close(SESAME)), or until the filehandle is attached to another file by a subsequent open on the same filehandle.

Once you've opened a filehandle for input, you can read a line using the line reading operator, <>The angle operator encloses the filehandle (<SESAME>) you want to read lines from. The empty angle operator, <>, will read lines from all the files specified on the command line, or STDIN, if none were specified.

An example using the STDIN filehandle to read an answer supplied by the user would look something like this:

print STDOUT "Enter a number: "; # ask for a number
$number = <STDIN>; # input the number print STDOUT "The number is$number./n"; # print the number

If you try the previous example, you may notice that you get an extra blank line. This happens because the line-reading operation does not automatically remove the newline from your input line (your input would be, for example, "9/n"). For those times when you do want to remove the newline, Perl provides the chop and chomp functions. chop will indiscriminately remove (and return) the last character of the string, while chomp will only remove the end of record marker (generally, "/n") and return the number of characters so removed. You'll often see this idiom for inputting a single line:

chop($number = <STDIN>); # input number and remove newline ### 2 Operators #### 2.1 Some Binary Arithmetic Operators Example Name Result$a + $b Addition Sum of$a and $b$a * $b Multiplication Product of$a and $b$a % $b Modulus Remainder of$a divided by $b$a ** $b Exponentiation$a to the power of $b #### 2.2 String Operators Perl defines a separate operator (.) for string concatenation: $a = 123;
$b = 456; print$a + $b; # prints 579 print$a . $b; # prints 123456 There's also a "multiply" operator for strings, called the repeat operator. Again, it's a separate operator (x) to keep it distinct from numeric multiplication: $a = 123;
$b = 3; print$a * $b; # prints 369 print$a x $b; # prints 123123123 The x operator may seem relatively worthless at first glance, but it is quite useful at times, especially for things like this: print "-" x$scrwid, "/n";

--$a,$a-- Autodecrement Subtract 1 from $a The same with C. #### 2.5 Logical Operators Example Name Result$a && $b And$a if $a is false,$b otherwise
$a ||$b Or $a if$a is true, $b otherwise !$a Not True if $a is not true$a and $b And$a if $a is false,$b otherwise
$a or$b Or $a if$a is true, $b otherwise not$a Not True if $a is not true$a xor $b Xor True if$a or $b is true, but not both #### 2.6 Some Numeric and String Comparison Operators Comparison Numeric String Return Value Equal == eq True if$a is equal to $b Not equal != ne True if$a is not equal to $b Less than < lt True if$a is less than $b Greater than > gt True if$a is greater than $b Less than or equal <= le True if$a not greater than $b Comparison <=> cmp 0 if equal, 1 if$a greater, -1 if $b greater #### 2.7 Some File Test Operators Here are a few of the file test operators: Example Name Result -e$a Exists True if file named in $a exists -r$a Readable True if file named in $a is readable -w$a Writable True if file named in $a is writable -d$a Directory True if file named in $a is a directory -f$a File True if file named in $a is a regular file -T$a Text File True if file named in $a is a text file You might use them like this: -e "/usr/bin/perl" or warn "Perl is improperly installed/n"; -f "/vmlinuz" and print "I see you are a friend of Linus/n"; ### 3 Control Structures #### 3.1 Truth Truth in Perl is always evaluated in a scalar context. Other than that, no type coercion is done. So here are the rules for the various kinds of values a scalar can hold: 1. Any string is true except for "" and "0". 2. Any number is true except for 0. 3. Any reference is true. 4. Any undefined value is false. For example: "0.00" + 0 # would become the number 0 (coerced by the +), so false. /$a # is a reference to $a, so true, even if$a is false.
undef() # is a function returning the undefined value, so false.