Part I Programming Perl
1 Perl Data Types
1.1 Funny Characters
1.2 Singularities
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
$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
1.3.1 Array
@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.2 Hash
Suppose you wanted to translate abbreviated day names to the corresponding full names. You could write the following list assignment:
%longday = ("Sun", "Sunday", "Mon", "Monday", "Tue", "Tuesday", "Wed", "Wednesday", "Thu", "Thursday", "Fri", "Friday", "Sat", "Saturday");
But that's rather difficult to read, so Perl provides the => (equals sign, greater-than sign) sequence as an alternative separator to the comma. Using this syntactic sugar (and some creative formatting), it is much easier to see which strings are the keys and which strings are the associated values.
%longday = ( "Sun" => "Sunday", "Mon" => "Monday", "Tue" => "Tuesday", "Wed" => "Wednesday", "Thu" => "Thursday", "Fri" => "Friday", "Sat" => "Saturday", );
Linguistically, the relationship encoded in a hash is genitive or possessive, like the word "of" in English, or like "'s". The wife of Adam is Eve, so we write:
$wife{"Adam"} = "Eve";
1.3.3 Complexities
$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
$kids_of_wife{"Jacob"} = { "Leah" => ["Reuben", "Simeon", "Levi", "Judah", "Issachar", "Zebulun"], "Rachel" => ["Joseph", "Benjamin"], "Bilhah" => ["Dan", "Naphtali"], "Zilpah" => ["Gad", "Asher"], };
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;
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:
$fido = new Camel "Amelia";
In fact, some of the built-in modules don't actually introduce verbs at all, but simply warp the Perl language in various useful ways. These special modules we call pragmas. For instance, you'll often see people use the pragma strict, like this:
use strict;
1.4 Verbs
1.5 Filehandles
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.
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";
which draws a line across your screen, presuming $scrwid contains your screen width, and not your screw identifier.
2.3 Assignment Operators
$line .= "/n"; # Append newline to $line. $fill x= 80; # Make string $fill into 80 repeats of itself. $val ||= "2"; # Set $val to 2 if it isn't already "true".
2.4 Unary Arithmetic Operators
Example | Name | Result |
---|---|---|
++$a, $a++ | Autoincrement | Add 1 to $a |
--$a, $a-- | Autodecrement | Subtract 1 from $a |
2.5 Logical Operators
2.6 Some Numeric and String Comparison Operators
2.7 Some File Test Operators
Here are a few of the file test operators:
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:
"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.