Cover | Table of Contents | Colophon
print "Howdy, world!\n";
Howdy, world!" on your screen.
(The \n in the example produces a newline at the end of the output.)
exit function explicitly if you wish, just
as you may declare some of your variables, or even
force yourself to declare all your variables. But
it's your choice. With Perl you're free to do The Right Thing, however
you care to define it.
print "Howdy, world!\n";
Howdy, world!" on your screen.
(The \n in the example produces a newline at the end of the output.)
exit function explicitly if you wish, just
as you may declare some of your variables, or even
force yourself to declare all your variables. But
it's your choice. With Perl you're free to do The Right Thing, however
you care to define it.
Noël 25 Ben 76 Clementine 49 Norm 66 Chris 92 Doug 42 Carol 25 Ben 12 Clementine 0 Norm 66 …
1 #!/usr/bin/perl
2
3 open(GRADES, "grades") or die "Can't open grades: $!\n";
4 while ($line = <GRADES>) {
5 ($student, $grade) = split(" ", $line);
6 $grades{$student} .= $grade . " ";
7 }
8
9 foreach $student (sort keys %grades) {
10 $scores = 0;
11 $total = 0;
12 @grades = split(" ", $grades{$student});
13 foreach $grade (@grades) {
14 $total += $grade;
15 $scores++;
16 }
17 $average = $total / $scores;
18 print "$student: $grades{$student}\tAverage: $average\n";
19 }GRADES, which exemplifies
another of Perl's data types, the filehandle. 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.)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 function to create filehandles for various
purposes (input, output, piping), you need to be able to specify which
behavior you want. As you might do on the command line, you simply
add characters to the filename.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
| 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 |
0".
/foo/ in a conditional, you know you're
looking at an ordinary pattern-matching operator:
if (/Windows 95/) { print "Time to upgrade?\n" }s/foo/bar/, you know it's asking Perl to substitute "bar" for "foo",
if possible. We call that the substitution operator. It also
happens to return true or false depending on whether it succeeded,
but usually it's evaluated for its side effect:
s/Windows/Linux/;
split
operator uses a regular expression to specify where the data isn't. That
is, the regular expression defines the separators
that delimit the fields of data. Our Average Example has a couple of
trivial examples of this. Lines 5 and 12 each split strings on the space
character in order to return a list of words. But you can split on any
separator you can specify with a regular expression:
($good, $bad, $ugly) = split(/,/, "vi,emacs,teco");
@array = (1 + 2, 3 - 4, 5 * 6, 7 / 8);
foreach loop provides it.
The print operator also provides it. But you don't have to
learn these one by one.sort,
you'll find the syntax summary:sortLISTsort provides a list context to its arguments.typewriter
font is likely to be found in Chapter 29. And
although we've tried to stay
operating-system neutral, if you are unfamiliar with Unix terminology
and run into a word that doesn't seem to mean what you think it ought
to mean, you should check whether the word is in the Glossary. If the
Glossary doesn't work, the index probably will.char,
short, int, long, long long, bool, wchar_t,
size_t, off_t, regex_t, uid_t, u_longlong_t,
pthread_key_t, fp_exception_field_type, and so on. That's just
some of the integer types! Then there are floating-point numbers, and
pointers, and strings.$, even when referring to a scalar that is part of an array or
hash. It works a bit like the English word "the". Thus, we have:| Construct | Meaning |
|---|---|
$days
| Simple scalar value $days
|
$days[28]
| 29th element of array @days
|
$days{'Feb'}
| "Feb" value from hash %days
|
$days,
@days, and %days without Perl
getting confused.| Construct | Meaning |
|---|---|
${days}
| Same as $days but unambiguous before alphanumerics |
$Dog::days
| Different $days variable, in the Dog package |
$#days
| Last index of array @days
|
$days->[28]
| 29th element of array pointed to by reference $days
|
$days[0][2]
| Multidimensional array |
$days{2000}{'Feb'}
| Multidimensional hash |
$days{2000,'Feb'}
| Multidimensional hash emulation |
@, which works much like
the words "these" or "those":
| Construct | Meaning |
|---|---|
@days
| Array containing |
$foo and @foo
are two different variables. Together with the previous rules, it also
means that $foo[1] is an element of @foo totally unrelated to the
scalar variable $foo. This may seem a bit weird, but that's okay,
because it is weird.&, although the funny
character is optional when calling the subroutine. Subroutines aren't
generally considered lvalues, though recent versions of Perl allow you
to return an lvalue from a subroutine and assign to that, so it can
look as though you're assigning to the subroutine.(10/3 == 1/3*10) tend to fail mysteriously.%.14g" on most machines. Improper conversions of
a nonnumeric string like foo to a number count as
numeric 0; these trigger
warnings if you have them enabled, but are silent otherwise. See
Chapter 5, for examples of
detecting what sort of data a string holds.$x = funkshun(); # scalar context
$x[1] = funkshun(); # scalar context
$x{"ray"} = funkshun(); # scalar context@x = funkshun(); # list context
@x[1] = funkshun(); # list context
@x{"ray"} = funkshun(); # list context
%x = funkshun(); # list context($x,$y,$z) = funkshun(); # list context ($x) = funkshun(); # list context
my or our, so we have:my $x = funkshun(); # scalar context my @x = funkshun(); # list context my %x = funkshun(); # list context my ($x) = funkshun(); # list context
funkshun() function above) know which context they are in, and
return a list in contexts wanting a list but a scalar value in
contexts wanting a scalar. (If this is true of an operation, it
will be mentioned in the documentation for that operation.) In
computer lingo, the operations are overloaded on their return
type. But it's a very simple kind of overloading, based only on
the distinction between singular and plural values, and nothing
else.(LIST)@stuff = ("one", "two", "three");@stuff, but the scalar
assignment:$stuff = ("one", "two", "three");three" to variable
$stuff. Like the %map = ('red',0xff0000,'green',0x00ff00,'blue',0x0000ff);%map = (); # clear the hash first
$map{red} = 0xff0000;
$map{green} = 0x00ff00;
$map{blue} = 0x0000ff;=> operator between
key/value pairs. The => operator is just a synonym for a
comma, but it's more visually distinctive and also quotes any bare
identifiers to the left of it (just like the identifiers in braces
above), which makes it convenient for several sorts of operation,
including initializing hash variables:%map = (
red => 0xff0000,
green => 0x00ff00,
blue => 0x0000ff,
);$rec = {
NAME => 'John Smith',
RANK => 'Captain',
SERNO => '951413',
};$field = radio_group(
NAME => 'animals',
VALUES => ['camel', 'llama', 'ram', 'wolf'],
DEFAULT => 'camel',
LINEBREAK => 'true',
LABELS => \%animal_names,
);%hash) in a list context, in which
case it interpolates all its key/value pairs into the list. But
just because the hash was initialized in a particular order doesn't
mean that the values come back out in that order. Hashes are
implemented internally using hash tables for speedy lookup, which
means that the order in which entries are stored is dependent on
the internal hash function used to calculate positions in the hash
table, and not on anything interesting. So the entries come back
in a seemingly random order. (The two elements of each key/value
pair come out in the right order, of course.) For examples of how
to arrange for an output ordering, see the *foo contains the values of
$foo, @foo, %foo, &foo, and several
interpretations of plain old foo.) The type prefix of a typeglob is
a * because it represents all types.$fh = *STDOUT;
$fh = \*STDOUT;
sub newopen {
my $path = shift;
local *FH; # not my() nor our()
open(FH, $path) or return undef;
return *FH; # not \*FH!
}
$fh = newopen('/etc/passwd');open function for other ways to generate new filehandles.*foo = *bar;
foo" a synonym for every corresponding
thing named "bar". You can alias just one variable from a
typeglob by assigning a reference instead:*foo = \$bar;
$foo an alias for $bar,
but doesn't make @foo an alias for
@bar, or %foo an alias for
%bar. All these affect global (package) variables
only; lexicals cannot be accessed through symbol table entries.
Aliasing global variables like this may seem like a silly thing to
want to do, but it turns out that the entire module export/import
mechanism is built around this feature, since there's nothing that
says the symbol you're aliasing has to be in your namespace. This:local *Here::blue = \$There::green;
$Here::blue an alias for
$There::green, but doesn't make
@Here::blue an alias for
@There::green, or %Here::blue an
alias for %There::green. Fortunately, all these
complicated typeglob manipulations are hidden away where you don't
have to look at them. See Section 8.2.4 and
Section 8.2.5 in Chapter 8,
Section 10.1 in Chapter 10,
and Chapter 11, for more discussion on
typeglobs and importation.print
parse as list operators and are discussed in Chapter 29.)$info = `finger $user`;
$/ to use a different line
terminator.)$? (see Chapter 28 for the interpretation of
$?, also known as $CHILD_ERROR).
Unlike the csh version of this command, no
translation is done on the return data--newlines remain newlines.
Unlike in any of the shells, single quotes in Perl do not hide
variable names in the command from interpretation. To pass a
$ through to the shell you need to hide it with a
backslash. The $user in our
finger example above is interpolated by Perl, not
by the shell. (Because the command undergoes shell processing, see
Chapter 23, for security concerns.)qx// (for "quoted execution"),
but the operator works exactly the same way as ordinary backticks.
You just get to pick your quote characters. As with similar quoting
pseudofunctions, if you happen to choose a single quote as your
delimiter, the command string doesn't undergo double-quote
interpolation;$perl_info = qx(ps $$); # that's Perl's $$ $shell_info = qx'ps $$'; # that's the shell's $$
! $x # a unary operator $x * $y # a binary operator $x ? $y : $z # a trinary operator print $x, $y, $z # a list operator
print) or any named unary operator (such as
chdir) is followed by a left parenthesi