chmod +x filename) in your bin directory, where the first line of the file is
#!/usr/bin/perlEverything after that first line is Perl, except for lines beginning with #, which are comments. Every command in Perl should end in a semi-colon; missing semi-colons account for 90% of novice user errors, and 80% of expert user errors. So Perl programs look like this:
#!/usr/bin/perl command; command; # this is a comment, you can say whatever you want here command;Once you've written your Perl program, you run it by typing the name of the file. If you've made some mistake in your "code" (that's geek for "program," as if "program" weren't geeky enough) Perl will refuse to run it, spitting out some usually-informative error message instead.
Enough abstraction; on to some examples.
The Print Statement
The most basic thing you're going to want a perl script to do is
#!/usr/bin/perl print "1 + 2 = 3\n";Run it, and here's what it prints on your screen:
1 + 2 = 3The \n is an end-of-line statement; you'll spend a lot of time in Perl sticking those in and taking them out, unless you want all of your output to come all mushed together on one line and generally misbehaving.
#!/usr/bin/perl $x = 1; $y = 2; $z = 3; print "$x + $y = $z\n";Any variables in quotes will be
1 + 2 = 3
$z = $x + $y;That line really performs the math, and stores the result in $z. So a program like this
#!/usr/bin/perl $x = 1; $y = 2; $z = $x + $y; print "$x + $y = $z\n";will once again print out
1 + 2 = 3
$x = <>;When your program encounters a line like that, it will stop and wait for numbers (or letters, or anything else) to be typed in at the keyboard, until RETURN is hit. Then it will assign everything you just typed into $x, and the program can then play with it. So this program
#!/usr/bin/perl print "Type in a number: "; $x = <>; chop($x); print "Type in a number: "; $y = <>; chop($y); $z = $x + $y; print "$x + $y = $z\n";will wait for two numbers, add them up, and then print the result.
The one strange thing in that program is the chop command. When the value of $x comes in from the keyboard, it's stored along with the \n character from hitting RETURN. So if you typed 35 and then hit RETURN, the value of $x became
35\nChop just chops the last character off of a variable. Its most common use is for getting rid of that nasty "\n"--which, believe it or not, counts as one character. (Even more to the point: it counts as a charcter, which means "35\n" is not anything like "35". You can't add with it, you can't print it without getting an unwanted line break, and it won't do anything else you might expect. Chopping is good Perl practice.)
A subroutine is like a command you define yourself. So let's make a version of the program that uses a subroutine called getnumber that gets a number from the keyboard:
#!/usr/bin/perl $x = &getnumber; $y = &getnumber; $z = $x + $y; print "$x + $y = $z\n"; # The program ends there... # the subroutine is just tacked on at the end: sub getnumber { print "Type in a number: "; $number = <>; chop($number); $number; }Everything inside the curly brackets is the subroutine. Now that section of the program will be run every time you use the command
&getnumber;in your program. In this case, the subroutine "getnumber" returns a variable which is then assigned to $x and $y. Not all subroutines are designed to return variables. This one returns the contents of $number because of the line
$number;So the command
$x = &getnumber;first runs the subroutine, and then, when it sees the line $number; it exits the subroutine, and gives $x the value of $number.
But like I said, not all subroutines are designed to return a value. For instance, you could have a subroutine that just printed out a standard warning:
sub warning { print "WARNING: The program is about to ask you to type in a number!\n"; }So the line
&warning;will now print out
WARNING: The program is about to ask you to type in a number!every time you use it.
You can stick the code for subroutines anywhere you want in your program, but the traditional place is to group them all together at the end of the program, after the main section.
While
Right now the program just executes once and then kicks you out. Many
times you'll want your program to do something over and over again;
you can do this with a control structure that creates a
"loop". There are many types of control structures; we'll start you
off with a simple one called while. It basically means: do this
set of commands while this statement is true. For instance,
here's a code fragment that loops over and over as long as you type in
the number "15":
$x = 15; while($x == 15) { $x = &getnumber; }Two things to note: 1) $x == 15 means "$x is equal to 15". It's a comparative statement; it should never be confused with $x = 15, which assigns the value 15 to $x. Confusing == and = is one of the most common novice errors; in this case, it would create an infinite loop.
2) The first line of the code fragment sets the value of $x to 15. If you didn't do that, $x wouldn't equal 15 the first time around, so the program would never enter the loop at all, and would never ask for a number.
Here's our adding program, with a loop so you can use it over and over:
#!/usr/bin/perl $doagain = "yes"; while($doagain eq "yes") { $x = &getnumber; $y = &getnumber; $z = $x + $y; print "$x + $y = $z\n"; print "Do it again? (yes or no) "; $doagain = <>; chop($doagain); }(I left out the subroutine to save space here, but you'd have to include it if you wanted that program to run.) Note that the comparative statement this time uses "eq" rather than "==". == compares for numerical values; eq is for variables made up of letters, numbers, and other characters (called "string" variables.)
Welcome to the concepts of pattern matching and regular expressions, two of Perl's powerful text-processing tools. Let's start with a simple pattern first: one letter. If you want to test a variable to see if it contains the (lower-case) letter "z", use this syntax:
if ($x =~ /z/) { print "$x has a z in it!\n"; }Let's take that apart: if is just like while, except it only checks once (that is, it won't loop around again and again.) Like while, it will execute every command inside the curly brackets if the statement inside the parentheses is true.
The statement inside the parentheses works like this: =~ makes a comparison between $x and whatever's inbetween the two slashes; in this case, if there's a z anywhere inside $x, then the statement is true.
Let's up the ante, and match only if $x begins with the letter z:
if ($x =~ /^z/) { print "$x begins with a z!\n"; }^z is a regular expression; the carat (^) stands for the beginning of the string. Thus, the matching statement has to find a z immediately following the beginning of the string in order to be true.
How about words that begin with z and end with e? Use the regexp
/^z.*e$/The $ stands for the end of the string; the period stands for "any character whatsoever"; combined with the asterisk, it means "zero or more characters." Without the asterisk,
/^z.e$/would mean "z followed by one character followed by e."
There's a lot of different regular expressions. For instance,
/^z.+e$/means "z followed by at least one character, followed by e."
/^z\w*e$/means "z followed by zero or more word characters followed by e"--that is, "z!e" wouldn't match.
So to make sure that somebody's typing in numbers in our adding program, and not words, make the subroutine getnumber look like this:
sub getnumber { $number = "blah"; while($number =~ /\D/){ print "Enter a number "; $number = <>; chop($number); } $number; }"\D" is the regular expression for non-digits; if any character in $number is not 0-9, the expression won't match, and you'll get asked to enter a number again.
Note how we had to set $number to include a non-digit ($number =
"blah"
) to get inside the loop the first time around.
Substitution
You can transform variables at will or whim using regular expressions,
by use of the substitution command. This command will change the
letters "dog" to "cat" if they occur in the variable $x:
$x =~ s/dog/cat/;Actually, that will only change the last occurence (so "dogdog" would become "dogcat".) To make the change "global", add a g at the end:
$x =~ s/dog/cat/g;This will change "dig" and "dog" (but not "doug") to "cat":
$x =~ s/d.g/cat/g;
$x = 45;If you have a bunch of variables and want to store them together, that's an array. Here's how you assign the numbers 3, 5, 7, and 9 into an array called @dog:
@dog = (3, 5, 7, 9);Although the entire array is referred to as @dog, an individual element--let's say, the first one--is $dog[0]. So $dog[0] equals 3, and $dog[1] equals 5. (Throughout history, programmers have begun their lists with the number zero, and throughout history, this has caused nothing but grief and turmoil.)
Note that the variable $dog and the array elements $dog[0]...$dog[3] are totally unrelated. $dog could be "zebra" or 87000, and it would never affect any of the elements of @dog.
That's just the barest hint of what arrays can do. I'm only bringing them up now so you won't freak out if I use them in an example.