By Randal L. Schwartz, Tom Phoenix, brian d foy
Cover | Table of Contents
perlfaq2 manpage lists several other editors, too. Ask your local expert about text editors on your system. #!/usr/bin/perl
@lines = `perldoc -u -f atan2`;
foreach (@lines) {
s/\w<([^>]+)>/\U$1/g;
print;
}
#! line, as you saw before. You might need to change that line for your system, as we discussed earlier.` `"). (The backquote key is often found next to the number 1 on full-sized American keyboards. Be sure not to confuse the backquote with the single quote, "'".) The command we used is perldoc -u -f atan2; type that at your command line to see what its output looks like. The perldoc command is used on most systems to read and display the documentation for Perl and its associated extensions and utilities, so it should normally be available. This command tells you something about the trigonometric function atan2; we're using it here as an example of an external command whose output we wish to process.@lines. The next line of code starts a loop that processes each one of those lines. Inside the loop, the statements are indented. Though Perl doesn't require this, good programmers do.s/\w<([^>]+)>/\U$1/g;. Without going into too much detail, we'll just say that this can change any line that has a special marker made with angle brackets (< >), and there should be at least one of those in the output of the perldoc command.ex1-1, for simplicity, since it's exercise 1 in Chapter 1.)perldoc -u -f atan2 at a command prompt and note its output. If you can't get that to work, then find out from a local administrator or the documentation for your version of Perl about how to invoke perldoc or its equivalent. (You'll need this for the next exercise anyway.)hello
or the Gettysburg Address). Though you may think of numbers and strings as different things, Perl uses them nearly interchangeably. 1.25
255.000
255.0
7.25e45 # 7.25 times 10 to the 45th power (a big number)
-6.5e24 # negative 6.5 times 10 to the 24th
# (a big negative number)
-12e-24 # negative 12 times 10 to the -24th
# (a very small negative number)
-1.2E-23 # another way to say that - the E may be uppercase
1.25
255.000
255.0
7.25e45 # 7.25 times 10 to the 45th power (a big number)
-6.5e24 # negative 6.5 times 10 to the 24th
# (a big negative number)
-12e-24 # negative 12 times 10 to the -24th
# (a very small negative number)
-1.2E-23 # another way to say that - the E may be uppercase
0
2001
-40
255
61298040283768
61_298_040_283_768
hello). Strings may contain any combination of any characters. The shortest possible string has no characters. The longest string fills all of your available memory, though you wouldn't be able to do much with that. This is in accordance with the principle of "no built-in limits" that Perl follows at every opportunity. Typical strings are printable sequences of letters, digits, and punctuation in the ASCII 32 to ASCII 126 range. However, the ability to have any character in a string means you can create, scan, and manipulate raw binary data as strings and that is something with which many other utilities would have great difficulty. For example, you could update a graphical image or compiled program by reading it into a Perl string, making the change, and writing the result back out. 'fred' # those four characters: f, r, e, and d
'barney' # those six characters
'' # the null string (no characters)
'Don\'t let an apostrophe end this string prematurely!'
'the last character of this string is a backslash: \\'
'hello\n' # hello followed by backslash followed by n
'hello
there' # hello, newline, there (11 characters total)
'\'\\' # single quote followed by backslash
\n within a single-quoted string is not interpreted as a newline but as the two characters backslash and -w option on the command line:$ perl -w my_program
#! line:#!/usr/bin/perl -w
#!perl -w
#!/usr/bin/perl
use warnings;
'12fred34' as if it were a number:Argument "12fred34" isn't numeric
diagnostics pragma. The perldiag manpage has the short warning and the longer diagnostic description. #!/usr/bin/perl
use diagnostics;
use diagnostics pragma to your program, it may seem to you that your program now pauses for a moment whenever you launch it. That's because your program has to do a lot of work (and gobble a chunk of memory) in case you want to read the documentation as soon as Perl notices your mistakes, if any. This leads to a nifty optimization that can accelerate your program's launch (and memory footprint) with no adverse impact on users, once you no longer need to read the documentation about the warning messages produced by your program, remove the use diagnostics pragma. (It's even better if you fix your program to avoid causing the warnings. But it's sufficient merely to finish reading the output.)-M, to load the pragma only when needed instead of editing the source code each time to enable and disable $Fred is a different variable from $fred. And all of the letters, digits, and underscores are significant:$a_very_long_variable_that_ends_in_1
$a_very_long_variable_that_ends_in_2
$. In the shell, you use $ to get the value, but leave the $ off to assign a new value. In awk or C, you leave the $ off entirely. If you bounce back and forth a lot, you'll find yourself typing the wrong things occasionally. This is expected. (Most Perl programmers would recommend that you stop writing shell, awk, and C programs, but that may not work for you.)$r is probably not descriptive but $line_length is. A variable used for only two or three lines close together may be called something like $n, but a variable used throughout a program should probably have a more descriptive name.$super_bowl is a better name than $superbowl since that last one might look like $superb_owl. Does $stopid mean $sto_pid (storing a process-ID of some kind?), $s_to_pid (converting something to a process-ID?), or print() operator makes this possible. It takes a scalar argument and puts it out without any embellishment onto standard output. Unless you've done something odd, this will be your terminal display: print "hello world\n"; # say hello world, followed by a newline
print "The answer is ";
print 6 * 7;
print ".\n";
print a series of values, separated by commas:print "The answer is ", 6 * 7, ".\n";
$meal = "brontosaurus steak";
$barney = "fred ate a $meal"; # $barney is now "fred ate a brontosaurus steak"
$barney = 'fred ate a ' . $meal; # another way to write that
$barney = "fred ate a $meat"; # $barney is now "fred ate a "
print "$fred"; # unneeded quote marks
print $fred; # better style
if control structure: if ($name gt 'fred') {
print "'$name' comes after 'fred' in sorted order.\n";
}
else
keyword provides that as well: if ($name gt 'fred') {
print "'$name' comes after 'fred' in sorted order.\n";
} else {
print "'$name' does not come after 'fred'.\n";
print "Maybe it's the same string, in fact.\n";
}
if control structure. That's handy if you want to store a true or false value into a variable, like this: $is_bigger = $name gt 'fred';
if ($is_bigger) { ... }
0 means false; all other numbers mean true.'') means false; all other strings mean true.'0' is the same scalar value as the number 0, Perl has to treat them the same. That means that the string '0' is the only nonempty string that is false.!. If what follows it is a true value, it returns false; if what follows is false, it returns true: if (! $is_bigger) {
# Do something when $is_bigger is not true
}
<STDIN>.
<STDIN> in a place where a scalar value is expected, Perl reads the next complete text line from standard input (up to the first newline) and uses that string as the value of <STDIN>. Standard input can mean many things; unless you do something uncommon, it means the keyboard of the user who invoked your program (probably you). If there's nothing waiting for <STDIN> to read (typically the case unless you type ahead a complete line), the Perl program will stop and wait for you to enter some characters followed by a newline (return).
<STDIN> typically has a newline character on the end of it. So, you could do something like this: $line = <STDIN>;
if ($line eq "\n") {
print "That was just a blank line!\n";
} else {
print "That line of input was: $line";
}
chomp operator.chomp operator, it seems overspecialized. It works on a variable, and the variable has to hold a string. If the string ends in a newline character, chomp can get rid of the newline. That's (nearly) all it does as in this example: $text = "a line of text\n"; # Or the same thing from <STDIN>
chomp($text); # Gets rid of the newline character
chomp because of a simple rule: whenever you need a variable in Perl, you can use an assignment instead. Perl does the assignment and then it uses the variable in whatever way you requested. The most common use of chomp looks like this: chomp($text = <STDIN>); # Read the text, without the newline character
$text = <STDIN>; # Do the same thing...
chomp($text); # ...but in two steps
chomp may not seem to be the easy way, especially if it seems more complex. If you think of it as two operations, read a line and chomp it, then it's more natural to write it as two statements. If you think of it as one operation, read just the text and not the newline, it's more natural to write the one statement. Since most other Perl programmers are going to write it that way, you may as well get used to it now.chomp is a function. As a function, it has a return value, which is the number of characters removed. This number is hardly ever useful: $food = <STDIN>;
$betty = chomp $food; # gets the value 1 - but you knew that!
chomp with or without the parentheses. This is another general rule in Perl: except in cases where it changes the meaning to remove them, parentheses are always optional.chomp removes only one. If there's no newline, it does nothing and returns zero.while loop repeats a block of code as long as a condition is true: $count = 0;
while ($count < 10) {
$count += 2;
print "count is now $count\n"; # Gives values 2 4 6 8 10
}
if test. Like the if control structure, the block curly braces are required. The conditional expression is evaluated before the first iteration, so the loop may be skipped completely if the condition is initially false.undef value before they are first assigned, which is Perl's way of saying "nothing here to look at—move along, move along." If you use this "nothing" as a "numeric something," it will act like zero. If you use it as a "string something," it will act like the empty string. But undef is neither a number nor a string; it's an entirely separate kind of scalar value.undef automatically acts like zero when used as a number, it's easy to make an numeric accumulator that starts out empty: # Add up some odd numbers
$n = 1;
while ($n < 10) {
$sum += $n;
$n += 2; # On to the next odd number
}
print "The total was $sum.\n";
$sum was undef before the loop started. The first time through the loop, $n is one, so the first line inside the loop adds one to $sum. That's like adding 1 to a variable that already holds zero because you're using undef as if it were a number. Now it has the value 1. After that, since it's been initialized, adding works in the traditional way.$string .= "more text\n";
$string is undef, this will act as if it already held the empty string, putting "more text\n" into that variable. But if it holds a string, the new text is appended.undef when the arguments are out of range or don't make sense. If you don't do anything special, you'll get a zero or a null string without major consequences. In practice, this is hardly a problem. In fact, most programmers rely upon this behavior. But you should know that when warnings are turned on, Perl will typically warn about unusual uses of the undefined value since that may indicate a bug. For example, copying undef from one variable into another isn't a problem, but trying to print it would generally cause a warning.undef is the line-input operator, <STDIN>. Normally, it returns a line of text. But if there is no more input, such as at end-of-file, it will return undef to signal this. To tell if a value is undef and not the empty string, use the defined function, which returns false for undef and true for everything else: $madonna = <STDIN>;
if ( defined($madonna) ) {
print "The input was $madonna";
} else {
print "No input available!\n";
}
undef values, you can use the obscurely named undef operator:$madonna = undef; # As if it had never been touched
undef values, or any mixture of different scalar values. Nevertheless, it's most common to have all elements of the same type, such as a list of book titles (all strings) or a list of cosines (all numbers). $fred[0] = "yabba";
$fred[1] = "dabba";
$fred[2] = "doo";fred") is from a completely separate namespace than scalars use. You could have a scalar variable named $fred in the same program. Perl treats them as different things and doesn't get confused. (Your maintenance programmer might be confused though, so don't capriciously make all of your variable names the same.) $fred[0] = "yabba";
$fred[1] = "dabba";
$fred[2] = "doo";fred") is from a completely separate namespace than scalars use. You could have a scalar variable named $fred in the same program. Perl treats them as different things and doesn't get confused. (Your maintenance programmer might be confused though, so don't capriciously make all of your variable names the same.)$fred[2] in every place where you could use any other scalar variable like $fred. For example, you can get the value from an array element or change that value by the same sorts of expressions we used in the previous chapter: print $fred[0];
$fred[2] = "diddley";
$fred[1] .= "whatsis"; $number = 2.71828;
print $fred[$number - 1]; # Same as printing $fred[1]undef. This is the same as ordinary scalars; if you've never stored a value into the variable, it's undef. $blank = $fred[ 142_857 ]; # unused array element gives undef
$blanc = $mel; # unused scalar $mel also gives undefundef values. $rocks[0] = 'bedrock'; # One element...
$rocks[1] = 'slate'; # another...
$rocks[2] = 'lava'; # and another...
$rocks[3] = 'crushed rock'; # and another...
$rocks[99] = 'schist'; # now there are 95 undef elementsrocks that we've been using, the last element index is $#rocks. That's not the same as the number of elements because there's an element number zero. $end = $#rocks; # 99, which is the last element's index
$number_of_rocks = $end + 1; # okay, but you'll see a better way later
$rocks[ $#rocks ] = 'hard rock'; # the last rock$#name value as an index, like that last example, happens often enough that Larry has provided a shortcut: negative array indices count from the end of the array. But don't get the idea that these indices "wrap around." If you've got three elements in the array, the valid negative indices are -1 (the last element), -2 (the middle element), and -3 (the first element). In the real world, nobody seems to use any of these except -1, though. $rocks[ -1 ] = 'hard rock'; # easier way to do that last example
$dead_rock = $rocks[-100]; # gets 'bedrock'
$rocks[ -200 ] = 'crystal'; # fatal error! (1, 2, 3) # list of three values 1, 2, and 3
(1, 2, 3,) # the same three values (the trailing comma is ignored)
("fred", 4.5) # two values, "fred" and 4.5
() # empty list - zero elements
(1..100) # list of 100 integers..
range operator, seen here for the first time, which creates a list of values by counting from the left scalar up to the right scalar by ones: (1..5) # same as (1, 2, 3, 4, 5)
(1.7..5.7) # same thing - both values are truncated
(5..1) # empty list - .. only counts "uphill"
(0, 2..6, 10, 12) # same as (0, 2, 3, 4, 5, 6, 10, 12)
($m..$n) # range determined by current values of $m and $n
(0..$#rocks) # the indices of the rocks array from the previous section ($m, 17) # two values: the current value of $m, and 17
($m+$o, $p+$q) # two values ("fred", "barney", "betty", "wilma", "dino")qw shortcut makes it easy to generate them without typing a lot of extra quote marks:qw( fred barney betty wilma dino ) # same as above, but less typing
qw stands for "quoted words" or "quoted by whitespace," depending upon whom you ask. Either way, Perl treats it like a single-quoted string so, you can't use \n or $fred inside a qw list as you would in a double-quoted string. The whitespace (characters like spaces, tabs, and newlines) will be discarded, and whatever remains becomes the list of items. Since whitespace is discarded, here's another (but unusual) way to write that same list: ($fred, $barney, $dino) = ("flintstone", "rubble", undef); ($fred, $barney) = ($barney, $fred); # swap those values
($betty[0], $betty[1]) = ($betty[1], $betty[0]);undef.
($fred, $barney) = qw< flintstone rubble slate granite >; # two ignored items
($wilma, $dino) = qw[flintstone]; # $dino gets undef($rocks[0], $rocks[1], $rocks[2], $rocks[3]) = qw/talc mica feldspar quartz/;
@) before the name of the array (and no index brackets after it) to refer to the entire array at once. You can read this as "all of the," so @rocks is "all of the rocks." This works on either side of the assignment operator: @rocks = qw/ bedrock slate lava /;
@tiny = (); # the empty list
@giant = 1..1e5; # a list with 100,000 elements
@stuff = (@giant, undef, @giant); # a list with 200,001 elements
$dino = "granite";
@quarry = (@rocks, "crushed rock", @tiny, $dino);@quarry the five-element list (bedrock, slate, lava, crushed rock, granite) since @tiny contributes zero elements to the list. (In particular, it doesn't put an undef item into the list, but you could do that explicitly as we did with @rocks = qw{ flintstone slate rubble };
print "quartz @rocks limestone\n"; # prints five rocks separated by spaces print "Three rocks are: @rocks.\n";
print "There's nothing in the parens (@empty) here.\n"; $email = "fred@bedrock.edu"; # WRONG! Tries to interpolate @bedrock
$email = "fred\@bedrock.edu"; # Correct
$email = 'fred@bedrock.edu'; # Another way to do that @fred = qw(hello dolly);
$y = 2;
$x = "This is $fred[1]'s place"; # "This is dolly's place"
$x = "This is $fred[$y-1]'s place"; # same thing$y contains the string "2*4", we're still talking about element 1, not element 7, because "2*4" as a number (the value of $y used in a numeric expression) is just plain 2. If you want to follow a simple scalar variable with a left square bracket, you need to delimit the square bracket so it isn't considered part of an array reference: @fred = qw(eating rocks is wrong);
$fred = "right"; # we are trying to say "this is right[3]"
print "this is $fred[3]\n"; # prints "wrong" using $fred[3]
print "this is ${fred}[3]\n"; # prints "right" (protected by braces)
print "this is $fred"."[3]\n"; # right again (different string)
print "this is $fred\[3]\n"; # right again (backslash hides it)foreach loop steps through a list of values, executing one iteration (time through the loop) for each value: foreach $rock (qw/ bedrock slate lava /) {
print "One rock is $rock.\n"; # Prints names of three rocks
}$rock in that example) takes on a new value from the list for each iteration. The first time through the loop, it's "bedrock"; the third time, it's "lava". @rocks = qw/ bedrock slate lava /;
foreach $rock (@rocks) {
$rock = "\t$rock"; # put a tab in front of each element of @rocks
$rock .= "\n"; # put a newline on the end of each
}
print "The rocks are:\n", @rocks; # Each one is indented, on its own line$rock after the loop has finished? It's the same as it was before the loop started. The value of the control variable of a foreach loop is automatically saved and restored by Perl. While the loop is running, there's no way to access or alter that saved value. So after the loop is done, the variable has the value it had before the loop or undef if it didn't have a value. That means that if you want to name your loop control variable "$rock", you don't have to worry that maybe you've used that name for another variable.foreach loop, Perl uses its favorite default variable, $_. This is (mostly) like any other scalar variable, except for its unusual name, as in this example: foreach (1..10) { # Uses $_ by default
print "I can count to $_!\n";
} 42 + something # The something must be a scalar
sort something # The something must be a list @people = qw( fred barney betty );
@sorted = sort @people; # list context: barney, betty, fred
$number = 42 + @people; # scalar context: 42 + 3 gives 45 @list = @people; # a list of three people
$n = @people; # the number 3