You are on page 1of 379

 

Books.Ru
ISBN 9785932861547,
Perl, 5 
Book.Ru . 
,

. , 
 (piracy@symbol.ru), 
.

Learning Perl
Fifth edition

Randal L. Schwartz,
Tom Phoenix & brian d foy

Perl

. ,

___________________________


2009

. ,

Perl, 5
.

.

.
.
.
.
.
.

., .,
Perl, 5 . . . : , 2009. 384 .,
.
ISBN: 9785932861547
, , 1993 ,
,
Perl 5.10.
, Perl,
, , ,
, , ,
, .
Perl , .
, 
, Perl 
,

, , 
, ,
.
Perl,
Perl Perl.

ISBN: 9785932861547
ISBN: 9780596520106 ()
, 2009
Authorized translation of the English edition 2008 OReilly Media, Inc. This
translation is published and sold by permission of OReilly Media, Inc., the owner of
all rights to publish and sell the same.
,
.
, , .

. 199034, , 16 , 7,
. (812) 3245353, www.symbol.ru. N 000054 25.12.98.
27.05.2009. 70u1001/16 . .
24 . . 1500 .

199034, , 9 , 12.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Perl? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Perl? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Perl? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
print . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
if . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
chomp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
undef . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
defined . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61

3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
foreach . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73

<STDIN> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78

4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
. . . . . . . . . . . . . . . . . . . . . . . . . 80
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
. . . . . . . . . . . . 85
. . . . . . . . . . . . . . . . . . . . . . . . . . . 86
(my) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
use strict . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
return . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
. . . . . . . . . . . . . . . . . . . . . . . . . . . 94
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96

5. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
. . . . . . . . . . . . . . . . . . . . . . . . . . . 98
<> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
. . . . . . . . . . . . . . . . . . . . . . . . . . . 103
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
die . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
. . . . . . . . . . . . . . . . . . . . . . . . . 118
. . . . . . . . 119
say . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121

6. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
%ENV . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137

7. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 140

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148

8.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
m// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
=~ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167

9.
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
s/// . . . . . . . . . . . . . . . . . . . . . . . . 169
split. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173
join . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
m// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 175
. . . . . . . . . . . . . . . . . . . . 175
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183

10. . . . . . . . . . . . . . . . . . . . . . . . . . . 184
unless . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184
until . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
elsif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
?: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206

11. Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217

12. . . . . . . . . . . . . . . . . . . . . . . . . . . 218
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 218
stat lstat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
localtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230

13. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250

14. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
substr . . . . . . . . . . . . . . . . . . . . . . 253
sprintf . . . . . . . . . . . . . . . . . . . . . . 255
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263

15. given)when. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265


. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
given . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
when . . . . . . . . . . . . . . . . . . . . . . . 274
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275

16. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
system . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
exec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
. . . . . . . . . . . . . . . . . . . . . . 283
. . . . . . . . . . . . . . . . . . . . . . . . . . 286

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292

17. Perl . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294


eval. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306

A. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 307
B. , . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366

Learning Perl,
Perl 5.10 . , Q
, Perl 5.6 (
; ?).
3045 Q
Perl, , . ,
, Q
, Perl Q
, Q .
Perl Q
. , , .
Perl, Q
. 1
128 , 90% .
,
Intermediate Perl1, Q
, . Q
.
, Q
. , Q
; Q
.
Perl. , Q
, Q
. Q
, .
Perl UNIX, Q
UNIX ( ,
UNIX).
, Windows ActiveQ
Perl ActiveState, Q
Perl.
1

, Perl: . .
. .: Q, 2007.

12

Perl, Q
Q
: , ,
,
.
. Q
, Perl
, , ,
.


:

, , . Q
.

, .

, Q
(, _ ).

, URLQ, , , Q
, .

, ( ,
) . Q
, Q
. ,
.


,
, Q
Perl. ,
, Q
:
OReilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
800Q998Q9938 ( )

13

707Q829Q0515 ( )
707 829Q0104 ()
.
,

info@oreilly.com
Q
:
bookquestions@oreilly.com
Q Q
, Q
. (
Perl), ( )
. :
http://www.oreilly.com/catalog/9780596520106
Q
OReilly:
http://www.oreilly.com


,
.
.
,
. , Q
,
. , Q
OReilly . Q
,
, .

, .
, .
, , ISBN, : Learn
ing Perl, Fifth edition, by Randal L. Schwartz, Tom Phoenix, and brian d
foy. Copyright 2008 OReilly Media, Inc., 978Q0Q596Q52010Q6.
, Q
, , Q
permissions@oreilly.com.

14

Safari Enabled

Safari Enabled, ,
OReilly Network Safari Bookshelf.
Safari , .
,
, , Q
,
. Safari http://
safari.oreilly.com.


,
.
Programming Perl1
( 1991 ), Taos Mountain Software Q
.

. 2 .
( 1991 )
, : , Q
Programming Perl,
. ,
, .
.
, Taos,
Q
.
15 , :
Programming Perl
. 18
Learning Perl.
Perl Q
3,
1

. Perl, 3Q . . .
.: Q, 2002.
, QQ
, ,
. ,
Taos.
Taos , Q
Q
. .

15

, Learning Perl.
( Q
Intel Oregon)
.
1 1993
. ProQ
gramming Perl.
: Q
Perl. .
,
.
Perl
, ( !)
. Q
Web Q Perl Q
, CGI .
, Q
StoneQ
henge, , Q
.
, ,
OReilly : !
.

,
100 10 000 . Q
, 2003 .

. ,
, Q
.
OReilly ( )
Perl 6. Q
.
;
, Q
.
18 2007 perl5porters Perl 5.10 Q
Perl Q

,
,
Intel. , Q
.

16

. 5.8
. Q
5.8 , Q
Perl 6 ( ).
(, ) Q
, , Q
. ,
Perl 5.10 , .
:
Perl 5.10.
. Q
Perl 5.10 , Q
use.
:
use 5.010; # Perl 5.10

use 5.010 , ,
Perl 5.6. Perl Q
v:
promt% perl v

Perl 5.10, Q
. Q
:
, , Q
Perl 5.10: Q
( 7), ( 7) Q
( 8).
Perl 5.10 switch givenwhen.
15 .
Q
( Perl
state). Q
. Q
4.

. Stonehenge
, . (Joseph Hall),
(Tom Phoenix), (Chip Salzenberg), (brian d
foy) Q (Tad McClellan), Q
. Q
, , ,
. Q

17

Q
, , Q
.
,
.
OReilly, Q

(Allison Randal) ( , ), Q
, Q
.
, Q
, , Q
, Q
Fortune 1000, Q
.
,
, . , Q
.
. ,
OReilly.
(Linda Mui); , Q
( , ,
). Q
, . Q
; .
, Q
Stonehenge.
Q
.
, .

(OMSI). ,
.
Usenet Q
. , .
,
( ),
. Q
, .
,
,
( Q
). , ,

18

, , Q
, Q
; .
.
. ,
Perl , Q
, Q
Stonehenge 1998 . Q
.
Perl, , , , Q
, , Q
Smalltalk Perl. Q
. Q
Perl. ,
. , .
, Stonehenge
, Q
. .
, Q
Perl.
, Q
, ,
. Q
, ,
.
, , , , , Q
, , , Q
, .
. : (David H.
Adler), (Andy Armstrong), (Dave
Cross), (Chris Devers), (Pau Fenwick),
(Stephen Jenkins), (Matthew
Musgrove), (Steve Peters) (Wil Wheaton)
.
,
, Q
. .
Perl Mongers ,
. Q ?
, , Q
, .

.

!
, 1993 (
) . , Q
. , .1


, Q Perl, , Q
, ,
. .

?
,
2 : Perl
, Q
1

. ,
, ,
,
( http://www252.pair.com/comdog/style.html, Q
. . .).
, , ,
. ,
( ), ? :
. , Q
. , , Q
, .
Q , 
, . .

20

1.

, 1, Q
? , Q
, .2 ,
,
Perl; Perl ,
. Perl .

?
, . . Q
. , Perl
. ,
.
, : Q
Q
.3 , Q
. ,
(, ).
. Perl
UNIX Q . ,
, Q
Q , Q
. , ,
UNIX, Perl (
UNIX, ).
80/20.
, 80% Perl 20% Q
, 20% 80% . Q
, Q
, Q
( ,
4).
, , ,

Q
.
.
1

2
3

, Python
, . CORBA.
, , .
,
, use integer , Q
Perl 5.6.
,
.

21

?
,
Q
.1 , Q
.
, , 
.
PerlQ, Q
. ,
. Q
, Q

, ( ) .
, .
, Q
. , , ,
. Q Q
, :
.
, .
Q
, .

?
;
:
1. [2] 2 Q
?
( ) , Q
. , ( Q
, ) Q
. Q
, , Q
.

Perl?
Perl Q
( ), : Q
,
45
. Q
1

, .

22

1.

, . , Q

( , ).

Perl?
Perl Practical Extraction and Report
Language ( Q
), , Pathologically
Eclectic Rubbish Lister ( Q
). , ,
, Perl, ,
. Perl
. , Q
: .
perl p. , Perl
, perl Q
, .

Perl?
Perl 1980Q , Q
Usenet (Q Q
), awk Q
. , 1 , Q
,
. Q
Perl.

?
, ?
, .
, ,
. , Q
, awk, Q
( grep, cut, sort sed2),
, C.

; . Q
, ; ,
; Perl ,
.
, . ,
UNIXQ ,
.

Perl?

23

Perl (C, C++, Q


) ( Q
). ,
Q
; Q
. Q
. ,
, ,
; , Q

, , Q
. Perl ,
, Q .
.
Perl . , 
, Perl .
,
. Perl
, , Perl
.
Perl . , Q
Perl, . , Perl
Q
( ), Perl
, Q
:
.
Perl . , Perl,
, , Q
. Q
, , Q
,
, .
Perl Q . . Perl Q
( ,
Programming Perl1, OReilly),
( 2). Q ,
. Q
, , Q
, . Perl .
1

, Perl,
3Q , Q, 2002.
, IntermeQ
diate Perl (OReilly) Perl: , Q, 2007.

24

1.

Perl ?
Perl , . Q
, . Perl
. Q
Q ,
, .
, Perl ,
.1 Perl , Q
. , Q
, Q
, Perl
:
while (<>) {
chomp;
print join("\t", (split /:/)[0, 2, 1, 5] ), "\n";
}

Perl Q
10 12 ; Q
.
.
Perl Q
, Perl. .

;
.
.
, ,
. ,
, Q
. Perl
, Q
, Q
.
Perl
(
C) Q
, Perl Q
. Perl Q
( )


,
, . Perl ,
20 Perl.

Perl?

25

, . Q
, Perl
,
.
Perl . ,
; , Q
Perl, Q
C. Perl , Q
, ,
. ,
: , Q
Q, Q
. Q
1 ( Q
), Perl
.
Perl, ,
writeQonly , ,
.
. ,
Perl ,
Q
. Q
, Q

PerlQ.

Perl ?
Perl,
Usenet. , Q
( Q
j ) , Q
, ,
.
Perl . .
. , Q Q
UNIXQ,
, ,
Usenet (
, )

, Q
.

26

1.

, . , Q
.

Perl ?
, Q
. Perl Q
, Perl 5 Porters.
perl5Qpor
ters@perl.org, .
( 2008 ) Perl
.
: Perl 6.
Perl 5 Q
. Perl 6
. Perl 5 , ,
. Perl 5 Perl 6; , Q
. Perl 5 Porters Q
Perl 5, ,
Perl 6 Perl 5. ,
Perl 5.10, , Perl 5
Porters Perl 5.12.
2000 Perl, Q
Perl.
Parrot, Q
. 2005 (Autrijus
Tang) Pugs (Perl User Golfing System) Q
Perl 6 Haskell.
( Perl, Haskell) . Parrot
, Perl 6, . Q
. Q
Perl 6 http://perl
six.org http://www.pugscode.org. ,
Perl 6.

Perl?
Perl , Q
. , Perl
, ,
. Q
, ,
.
Perl , 90%
10% . , Q
, Q

Perl?

27

.
.
Perl.1 , Perl, Q
Q Web, Q
. Q , Perl 1990Q Q
HTML Q
, Web Q
. , Perl
CGI (, QQ
) , : Q
CGI Perl ? Perl Q
CGI?. .

Perl ?
Perl , ? Q
Perl,
, Q
, Q
( , Q
). Perl
, .
,
, . Q Q
, Q
. ,
, , , ,
. Q
; , Q
: , . Q
, , ,
.

Perl?
, . Perl Q
. , Q
. Q
Perl ,
.

, . , Q
Perl X, , Q
, .
. Perl
X, , .

28

1.

Perl . ,
Perl, . Q
Perl, Q
;
. , Perl,
: Q
.
Perl , Q
, UNIX Q
C. ,
Perl. ,

Perl .1 UNIX Perl
Perl :
Mac OS X, VMS, OS/2, MS/DOS Q
Windows , ,
.2 Perl Q
, , Q
Perl UNIX. ports CPAN.

CPAN?
CPAN (Comprehensive Perl Archive Network)
Perl, , Perl. Q
Perl, Perl Q
, UNIX3, , , Q
Perl . , CPAN Q
.
CPAN ;
http://search.cpan.org/ http://kobesearch.
cpan.org/. , CDQROM
DVDQROM CPAN, Q
. , Q

, Q
? , .
,
, ,
Q .
, Perl Blackberry
. , ,
WinCE.
UNIX Perl .
C Q
, , CPAN Q
.

Perl?

29

. CPAN ,
. Q

CPAN.

?
Q
!
, ? .
Perl,
, ,
, .
Perl.
, Perl . Q
, . Q
, , ,
Perl
Forehead ,
. (,
. , ForeQ
head .) , , Q
Forehead. ,
, , ,

. ,
, Q Q
.
Perl .
, , Q
( 10 ) .
, Perl ? Q
. , Perl?
, .

?
. Perl Mongers Q
Perl (
http://www.pm.org/). ,
, Q Q
. ,
.

30

1.

,
. manQ1
CPAN (http://www.cpan.org) . ,
http://perldoc.perl.org, HTMLQ PDFQ
Perl, http://faq.perl.org/ perlfaq.
Programming
Perl, Q Q
( ,
). Q
,
Perl. Perl 5 Pocket ReferQ
ence (OReilly), (Johan Vromans).
( ).
Usenet Q
.2 Q
, Usenet,
Perl, Perl . ,
.
FAQ,
.
Usenet comp.lang.
perl.*. , Q
. ( , Perl
) comp.lang.perl.an
nounce , Q
Perl,
. Usenet, Q
.
Q, Q
Perl. Perl Monastery (http://
www.perlmonks.org/) Perl,
. http://
learn.pearl.org/ beginners@perl.org. Perl
http://use.perl.org/. Q
Perl Perl; Q
http://planet.perl.org.
, Perl, Q
.
.

manQ UNIX Q
. UNIX, manQ Perl
.
http://lists.perl.org.

Perl?

31

Perl?
, 1
2. Perl Q
; , , , , Q
. ,
Perl; , .
99% , ,
. , Perl
Mongers, Perl. , Q .
100% , ,
. ( ?)
Q
, , Perl
() . , Q
, , perlbug
( Perl) . Q
Perl
, perlbug .
,
. Q
(), Q
. , ( ); Q
Perl .
Perl, , Q
.

Perl?
( ). Perl
; Q
. ( Q
,
Perl.
, .)
Q
. ?

, Q
1

,
.
. ,
Perl, Q
.

32

1.

Q
. UNIX Q
emacs vi ( ).
Mac OS X BBEdit TextMate,
UltraEdit PFE (Programmers FaQ
vorite Editor) Windows. manQ
perlfaq2. ,
.
, ,
. 20 30 ,
.
Q
. Q
, . ,
. ,
;
. Q
, Perl
;.
,
. Q
, text
ASCII, binary. Q Q
. Q
Perl Q
Q
.


,
UNIX,
Hello, world. Perl:
#!/usr/bin/perl
print "Hello, world!\n";

, . (
, ,
.)
. Perl
,
.1 , Q
, .plx (PerL eXecutable);

.

Perl?

33

, , Q
(. . ). Q
, ; Q
. UNIX Q
chmod :
$ chmod a+x my_program

( ) Q
. , Q
. chmod Q
755 a+x, , ,
. , Q
.
:
$ ./my_program

, Q
.
, , Q
.1 Q
, . , Q
. ;
chmod,
. (,
chmod, .)
Perl 5.10 ;
. print
say, , Q
. say Q
, Perl 5.10 , Q
use 5.010, Perl Q
:

, ? , Q
,
bowling.plx. C.
, ,
Perl? , ? , 
, , Q
. , bowling.
:
( ) . Q
, test.
( ) Q
; .

34

1.
#!/usr/bin/perl
use 5.010;
say "Hello World!";

Perl 5.10. Q
Perl 5.10 ,
use 5.010, . Perl
, ,
use 5.010 use 5.10 (Perl ,
5.100, !).

?
, Perl
(, ),
. , Perl Q
( ,
). Q
, ;
.
. Perl
# (
Perl 1). Q
,
. Q
, .
, Hello, world Q
( , ):
#!/usr/bin/perl
print
#
"Hello, world!\n"
;
# Perl !

Q
. UNIX2, Q
#!, , Q
.
/usr/bin/perl.
#!
PerlQ, Q
. , /usr/bin/perl
1

; . FAQ (perldoc perlfaq


).
.
Q 1980Q ,
, UNIX.

Perl?

35

/usr/local/bin/perl. , ,
perl, .
UNIX ,
perl :
#!/usr/bin/env perl

perl , , Q
Q
.

#!perl.
, , Q
Perl.
#! ,
.
, . , Q
; /usr/bin/perl
, . Q
, Perl; Q
. (, user Q
usr; UNIX
.)
: Q
#!. ( ,
), ,
; .
,
manQ perldiag.
Perl ( Q
, ). Perl
main, , C Java. Q
.
,
. , Q
, . Q
.
, Q
.
, 4 , .
,
(;). , Q
:
print "Hello, world!\n";

36

1.

, , Hel
lo, world!. \n,
C, C++ Java;
. Q
,
, Q
.
.
.

, Perl?
. perl
:
$ perl my_program

Perl Q
Q ( ,
). Q Perl Q
Q . Q
200 ,
2.1 Q
5000 , ; Q
.
, ,
, Q
. Q
, Q Q
, .
,
Perl,
(, ),
. Q
. Q
; Q
.
, Q
CGI; . (
.
CGI , Q
, .)
, Q
.
1

2 , Q
BEGIN use.

Perl

37

, Q
. , mod_perl Q
Apache (http://perl.apache.org/) Perl, CGI::Fast.
Q,
? Q
(, C) ? Q
, , , Q
, , Q
, , .
Perl 6 ,
( ) .

Perl
Perl? (
, ). :
#!/usr/bin/perl
@lines = `perldoc u f atan2`;
foreach (@lines) {
s/\w<([^>]+)>/\U$1/g;
print;
}

Perl . (,
, .) , Q
, . , Q
.
. Q
, .
, #!, . ,
, .
,
(` `). ( Q
1. Q
, '.)
perldoc u f atan2; Q
, . perldoc Q
Perl, Q
, .1 Q
atan2; Q
1

perldoc , , ,
, Perl Q
(, perldoc)
(piped open) . 16. ,
perldoc.

38

1.

,
.
Q
@lines. Q
. . Perl ,
.
. Q
: s/\w<([^>]+)>/\U$1/g;. , ,
,
(< >). perldoc Q
.
, , (,
) . ,
perldoc u f atan2,
.
, Q
, ,
. , Q
, Perl.

, Q
.
.
Q
, Q
. , Q
, .
1. [7] Hello, world ! (
, Q
ex11 1 1.)
2. [5] perldoc i f atan2 ; Q
. , Q
Perl,
perldoc . ( Q
.)
3. [6] ( )
, . (:
, Q
!) ,
?

Q
. Perl , Q
, . , Perl
Q, , 
( 1). Q
, Perl.
(, 255 3.25e20),
(, hello2
). , ,
Perl .
(, Q
. .); ,
. Q
. Q
.

, ,

. , .
1

Perl Q
; Perl .
Q
hello , Q
. Perl . ,
;
, , .

40

2.


, Perl
(255, 2001 . .), ( Q
3.14159, 1.351025 . .). Q
Perl 1.
, Perl

2. ,
( ), Q
(
) .3


Q
Perl. Q
/; , Q
.
Perl .
( Q
)
E 10. :
1.25
255.000
255.0
7.25e45 # 7.25 10 45 ( )
6.5e24 # 6.5 10 24
# ( )
12e24 # 12 10 24
# ( )
1.2E23 #  E

, Q
C, Perl, double.
,
IEEEQ754 15Q Q
1eQ100 1e100.
Q Perl ,
. :
. ?
, integer ,
. , Q
. .

41


:
0
2001
40
255
61298040283768

. Perl Q
,
:
61_298_040_283_768

; , Q
. , Q
, Perl (. Q
).


, Perl Q
( Q
10). ( 8) 0, Q
( 16) 0x,
( 2) 0b.1 A F
( a f) 10 15. :
0377
0xff
0b11111111

# 377 ; , 255
# FF ; 255
# 255

, , , Perl
. Perl ,
0xFF 255.000, ,

( , ,
; , Q
, Q
!)


,
.
oct() hex().
bin() , Q
oct() , 0b.

42

2.

,
. Perl
:
0x1377_0B77
0x50_65_72_7C


Perl :
, , , . . :
2 + 3
5.1 2.4
3 * 12
14 / 2
10.2 / 0.3
10 / 3

#
#
#
#
#
#

2 3 = 5
5.1 2.4 = 2.7
3 12 = 36
14 2 = 7
10.2 0.3 = 34
, 3.3333333...

Perl (%).
10 % 3 10 3 , 1.
,
10.5 % 3.2 10 % 3.1 Perl Q
FORTRAN, Q
Pascal C. Q
, 2**3 , 8.2
, Q
.

(,
hello). Q
.3
, ( Q
).
, Perl Q
. Q
1

, Q
( ), Q
. .
Q
. ,
. ,
Math::Complex.
C C++, NUL Perl
, Perl ,
Q.

43

, Q
ASCII 32 ASCII 126.
, , Q

.
, Q
Perl, Q
.
, , (
).
:
.


Q
, .
Perl
. ,
( , Q
), . Q
\ ( ),
\ . :
'fred'
# : f, r, e d
'barney' #
''
# ( )
'Don\'t let an apostrophe end this string prematurely!'
'the last character of this string is a backslash: \\'
'hello\n' # hello, n
'hello
there'
# hello, , there ( 11 )
'\'\\'
# ,

: \n , , Q
, :
n.
, Q
.


,
.
, Q
. Q

.
:

44

2.
"barney"
# , 'barney'
"hello world\n" # hello world
"The last character of this string is a quote mark: \""
"coke\tsprite" # coke, sprite

"barney" Perl
,
'barney'. Q
, , 0377 Q
255.0. Perl , Q
. , Q
(,
\n ),
.
.
1
. 2.1.
2.1.

\n

\r

\t

\f

\b

Backspace

\a

\e

Escape ( Escape ASCII)

\007

ASCII (007 = )

\x7f

ASCII (7f = )

\cC

Control ( ControlQC)

\\

\"

\l

\L


\E

\u

\U


\E

Perl Q
, .

45

\Q

, , Q
\E

\E

\L, \U \Q

: 
, Q
. ,
,
.


. (, ). Q
, ,
2+3 2 3.
()
. :
"hello" . "world"
# , "helloworld"
"hello" . ' ' . "world" # , 'hello world'
'hello world' . "\n"
# , "hello world\n"

Q
(): Q
.

, x. Q
() Q
, (). :
"fred" x 3
# "fredfredfred"
"barney" x (4+1) # "barney" 5, "barneybarneybarneybarneybarney"
5 4
# "5" 4, "5555"

. Q
,
5 "5" ( ,
). Q
,
5555. 45,
4, 44444. , Q
.
( )
(4.8 4). 1
( ).

46

2.



, Perl
. ,
? ,
. ( +), Perl Q
. (
.), Perl . ,
.
, Perl .
,
(, ), Perl Q
,
.1 Q
, "12" * "3" 36. ,
, Q
, "12fred34" * " 3" 36
Q .2 , , Q
. ,
"fred".
,
(, ), Q
. , Q
Z 5 73,
:
"Z" . 5 * 7

# , "Z" . 35 "Z35"

, , Q
( ). Perl Q
.4

Perl
, Perl
.

3
4

, , Q
, , Q
. hex() oct().
,
.
.
, . Perl Q
, .

Perl

47

,
w:
$ perl w my_program

Q
, #!:
#!/usr/bin/perl w

, UNIX,
(
Perl ):
#!perl w

Perl 5.6 use


( Q
Perl):1
#!/usr/bin/perl
use warnings;

Perl '12fred34'
:
Argument "12fred34" isn't numeric

, Q
, . Q
, , Q
. ,
. ,
,
2 diagnostics. manQ perldiag Q
, :
#!/usr/bin/perl
use diagnostics;

use diagnostics Q
. , Q
(
) , Q
. Q
,
( ), ;

, warnings Q
; , , perllexwarn.
pragma ; use diagnostics ,
diagnostics ( ). . .

48

2.

Q
, use diagnostics. (
, .)
:
Perl M Q
.
diagnostics:
$ perl Mdiagnostics ./my_program
Argument "12fred34" isn't numeric in addition (+) at ./my_program line 17 (#1)
(W numeric) The indicated string was fed as an argument to
an operator that expected a numeric value instead. If you're
fortunate the message will identify which operator was so unfortunate.

, Perl
, . Q
, Q
Perl.


Q
.1 ,

.
, , Q
.
($), Perl:
, ,
. , Q
Q ,
. Q
; $Fred $fred . Q
,
$a_very_long_variable_that_ends_in_1


$a_very_long_variable_that_ends_in_2

$.2 Q
$ ,
. awk C $ Q
1

,
, , Q
.
(sigil) Perl.

49

.
, . ( Perl Q
Q
, awk C, .)


, , Q
Q . , $r Q
, $line_length . Q
Q ,
, , $n, Q
, , Q
.

, Q
, . ,
$super_bowl $superbowl,
$superb_owl. $stopid: $sto_pid (
STOrage for Process IDentifier), $s_to_pid
( s ) $stop_id (Q
Q)? , $stupid (), Q
?
Perl Q
, . Q
. Q
(, $ARGV) .
,
$underscores_are_cool, $giveMeInitial
Caps. .
,
Perl. Q
$, $ $; Perl,
.



, .
Perl = ( Q
), ,
, . :
$fred = 17;
$barney = 'hello';
$barney = $fred + 3;

#
#
#
#

$fred 17
$barney 5 'hello'
$barney $fred
3 (20)

50

2.
$barney = $barney * 2; # $barney ,
# 2 (40)

, $barney
:
( ),
( ). Q
, . ,
, Q
, .


, $fred = $fred + 5 ( Q
),
Perl ( C Java), Q
.
, ,
=. Q
, :
$fred = $fred + 5; #
$fred += 5;
#

:
$barney = $barney * 3;
$barney *= 3;

Q Q
Q
.
Q
( . ); Q
( .= ):
$str = $str . " "; # $str
$str .= " ";
#

.
, **=.
, fred **= 3 $fred
$fred.

print
, ;
, . print()
: Q

print

51

Q
. ,
. :
print "hello world\n"; # hello world,
#
print "The answer is ";
print 6 * 7;
print ".\n";

print , Q
:
print "The answer is ", 6 * 7, ".\n";

print , Q
, .



1 (
). , 2
. :
$meal = "brontosaurus steak";
$barney = "fred ate a $meal";
# $barney
# "fred ate a brontosaurus steak"
$barney = 'fred ate a ' . $meal; #

,
,
.
3,
:
$barney = "fred ate a $meat"; # $barney "fred ate a"

,
:
print "$fred"; #
print $fred; # ,

2
3

Q
.
, .
Q
undef, .
Perl Q
.

52

2.

, Q
.1 Q
Q
, (
). Q
Perl, .
,
, ,
:
$fred = 'hello';
print "The name is \$fred.\n";
#
print 'The name is $fred' . "\n"; #

,
. ,

, , .2
Perl Q
, . Q
. Q
:
$what = "brontosaurus steak";
$n = 3;
print "fred ate $n $whats.\n";
print "fred ate $n ${what}s.\n";
print "fred ate $n $what" . "s.\n";
print 'fred ate ' . $n . ' ' . $what .

# steaks, $whats
# $what
#
"s.\n"; #



. ,
2+3*4 ?
, 5*4, 20.
( ), Q
2+12, 14. , Perl Q

, .
, , Q
.
. Q

, .
, Q
; ,
.

53

print

. , Q
, .
Q
. , , Q
(
). , , Q
, (2+3)*4;
20. ,
, ,
, 2+(3*4).
,
, , Q
, . Q
, Q
Perl (. 2.2).1 (
, , Q
, manQ
perlop.)
2.2.
( )

>
++  ( )

**

\ ! ~ +  ( )

=~ !~

* / % x

+  . ( )

<< >>
(X filetests, rand)
< <= > >= lt le gt ge
== != <=> eq ne cmp

&

| ^

&&

, C! ,
Perl C, .

54

2.

2.2 ()

||
.. ...

?: ()

= += = .= ( Q
)

, =>
( )

not

and

or xor

,
, , Q
.

.
, , ,

:
4 ** 3 ** 2 # 4 ** (3 ** 2), 4 ** 9 ()
72 / 12 / 3 # (72 / 12) / 3, 6/3, 2 ()
36 / 6 * 3 # (36/6)*3, 18

** ,
. , Q
* / , Q
.
? ! Q
. Q
, . ,
,
, . Q
: Q .


Perl Q
, : < <= == >= > !=.
(true)
(false).
.

55

if

. ,
== =, . Q
!=, Q
<> Perl .
Perl Q
>=, =>. ,
Perl Q .
, Q
.
Perl Q
, : lt lg eq ge gt ne.
, , Q
Q
( ASCII
, Q
).
( , )
. 2.3.
2.3.
( )

==

eq

!=

ne

<

lt

>

gt

<=

le

>=

ge

:
35 != 30 + 5
35 == 35.0
'35' eq '35.0'
'fred' lt 'barney'
'fred' lt 'free'
'fred' eq "fred"
'fred' eq 'Fred'
' ' gt ''

#
#
#
#
#
#
#
#

false
true
false ( )
false
true
true
false
true

if
, Q
. Perl,
, if:

56

2.
if ($name gt 'fred') {
print "'$name' comes after 'fred' in sorted order.\n";
}

if
else:
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";
}

,
( C,
). Q
, . Q
(. 1),
.


if
. ,
(true false) :
$is_bigger = $name gt 'fred';
if ($is_bigger) { ... }

Perl ,
true false? Perl
() , . Q
Perl :1
, 0 false; Q
true.
, ('')
false; true.
( Q
, )
, Q
.2

, Perl .
, .
, undef (. ) false, (Q
)
true.

57

. '0' Q
, 0, Perl Q
. , '0' Q
, false.
, Q
, !.
,
false; true:
if (! $is_bigger) {
# $is_bigger
}


, ,
Perl. : Q
<STDIN>.1
, <STDIN> ,
, Perl
( Q
) <STDIN>.
, Q
, .
<STDIN> , ( ,
), Perl Q
, Q
.2
<STDIN> Q
3, :
$line = <STDIN>;
if ($line eq "\n") {
print "That was just a blank line!\n";
1

,
STDIN, , Q
(. 5).
, ; Perl
. Q
, Backspace Q
Return , Perl.
,
Term::ReadLine CPAN.
:
. ,
!

58

2.
} else {
print "That line of input was: $line";
}

.
chomp.

chomp
chomp, Q
. . Q
. Q
, chomp . () ,
. :
$text = "a line of text\n"; # <STDIN>
chomp($text);
#

,
. Q

. , Q
chomp: Q
Perl . Perl Q
, ,
. , Q
chomp :
chomp($text = <STDIN>); #
$text = <STDIN>;
# ...
chomp($text);
# ...

chomp Q
! Q
( ,
), Q
. Q
Q
.
Perl , .
chomp , .
chomp
. , Q :
$food = <STDIN>;
$betty = chomp $food; # 1, !

, chomp Q
, . Perl: Q

while

59

, Q
.
1,
chomp . ,
chomp 0.

while
, Perl
.2 while Q
, :
$count = 0;
while ($count < 10) {
$count += 2;
print "count is now $count\n"; # 2 4 6 8 10
}

, if.
, if, Q
. ,
, , .

undef
, Q
, ?
. Q
undef, Perl Q
: .
,
.
, . Q
undef , ; Q
.

, :
, ($/) Q
, read, Q
.
.
, Q
, . Q
ControlQC;
.

60

2.

undef Q
, Q
:
#
$n = 1;
while ($n < 10) {
$sum += $n;
$n += 2; #
}
print "The total was $sum.\n";

, $sum
undef . $n 1;
$sum 1.
1 , ( undef
, ).
1. Q
, .
Q
:
$string .= "more text\n";

$string undef, ,
; "more text\n"
. ,
.
Perl Q
, undef
.
undef, Q
.
, ,
. Q
;
. , Q
Perl Q
undef,
. , undef
, print
.

defined
<STDIN> undef.
, (Q

61

, ), , undef.1
, undef, Q
, undefined.
false undef true :
$madonna = <STDIN>;
if ( defined($madonna) ) {
print "The input was $madonna";
} else {
print "No input available!\n";
}

undef, Q
undef:
$madonna = undef; #

.
1. [5] Q
12.5. Q
2 ( 2, 3.141592654) . Q
78,5.
2. [4] ,
, Q
. 12.5,
, .
3. [4] ,
( Q
).
4. [8] , Q
( ), .
5. [8] ,
( ),
. , Q
"fred" "3",
fred. "fred" "299792", Q
.

, Q
. Q
,
.

3

Perl,
2, Q
.
.
. Perl
. Q
, , .
, ,
(
). . 3.1 ,
.

. Q
, Q
.


()

35

12.4

hello

1.72e30

bye\n

. 3.1.

63

,
1. ,
.
,
,
.
, ( Q
) ( ).
.
, Q
.
, Perl.


, , Q
, Perl
.

1, :
$fred[0] = "yabba";
$fred[1] = "dabba";
$fred[2] = "doo";

( "fred") Q
, .
$fred; Perl
.2 ( ,
,
!)
$fred[2] 3, Q
$fred. ,
1

Perl ,
. Perl
( Q
, !). , , Q
.
, $[
manQ perlvar.
, Q
.
. :
foreach (. ) . Q
, Q
print printf.

64

3.

Q
,
:
print $fred[0];
$fred[2] = "diddley";
$fred[1] .= "whatsis";

, Q
. , Q
:
$number = 2.71828;
print $fred[$number  1]; # print $fred[1]

, , Q
undef. ,
;
, undef:
$blank = $fred[ 142_857 ]; # undef
$blanc = $mel;
# $mel undef


, ,

, .
Perl , Q
undef:
$rocks[0]
$rocks[1]
$rocks[2]
$rocks[3]
$rocks[99]

=
=
=
=
=

'bedrock';
'slate';
'lava';
'crushed rock';
'schist';

#
#
#
#
#

...
...
...
...
95 undef

.
Q
$#rocks.1 Q
,
:
$end = $#rocks;
# 99,
$number_of_rocks = $end + 1; # , (. )
$rocks[ $#rocks ] = 'hard rock'; #

$# ,
, :
1

C. Q
, .

65

, . Q
,
1 ( ), 2 ( ) 3 (
). , Q
, 1.
$rocks[ 1 ] = 'hard rock'; # ,
$dead_rock
= $rocks[100]; # 'bedrock'
$rocks[ 200 ] = 'crystal';
# !


( ) Q
, Q
. .
:
(1, 2, 3)
(1, 2, 3,)
("fred", 4.5)
( )
(1..100)

#
#
#
#
#

1, 2 3
( )
, "fred" 4.5

100

.., Q
.
1. :
(1..5)
# , (1, 2, 3, 4, 5)
(1.7..5.7)
# 
(5..1)
#  .. ""
(0, 2..6, 10, 12) # , (0, 2, 3, 4, 5, 6, 10, 12)
($m..$n)
# $m $n
(0..$#rocks)
#

, Q
,
. :
($m, 17)
# : $m 17
($m+$o, $p+$q) #

, ,
:
("fred", "barney", "betty", "wilma", "dino")

qw
( ) Q
. qw
:
qw( fred barney betty wilma dino ) # , ,

66

3.

qw Quoted Words ( )
Quoted by Whitespace ( ) Q
, . , Perl Q
(Q
qw, , \n
$fred). (, , ) Q
, , , . Q
( Q
, ) :
qw(fred
barney
betty
wilma dino ) # ,

,
. Q
, Perl Q
. Q
:
qw!
qw/
qw#
qw(
qw{
qw[
qw<

fred
fred
fred
fred
fred
fred
fred

barney
barney
barney
barney
barney
barney
barney

betty
betty
betty
betty
betty
betty
betty

wilma
wilma
wilma
wilma
wilma
wilma
wilma

dino
dino
dino
dino
dino
dino
dino

!
/
#
)
}
]
>

# !

,
. Q
, Q
.
, .
Q
, , .
Q ,
:
qw! yahoo\! google ask msn ! # yahoo!

, , Q
\\ .
Perl : , Q
: Q
? , Q
, .
, Q
UNIX :
qw{
/usr/dict/words

67

/home/rootbeer/.ispell_english
}

,
, Q
.


, . Q
Q
:
($fred, $barney, $dino) = ("flintstone", "rubble", undef);

, Q
. Q
,
Perl:1
($fred, $barney) = ($barney, $fred);
#
($betty[0], $betty[1]) = ($betty[1], $betty[0]);

, ( Q
) ()?
Perl
, Q , Q
, .
, undef:2
($fred, $barney) = qw< flintstone rubble slate granite >; #
#
($wilma, $dino) = qw[flintstone];
# $dino undef

, ,
:3
($rocks[0], $rocks[1], $rocks[2], $rocks[3]) = qw/talc mica feldspar quartz/;

, Perl
. @ (
), Q
. , @rocks
1

C, Q
. C Q
, .
. ,
, .
: , rocks
. , , $rocks[7] ,
.

68

3.

rocks.1
:
@rocks
@tiny
@giant
@stuff
$dino
@quarry

=
=
=
=
=
=

qw/ bedrock slate lava /;


( );
#
1..1e5;
# 100 000
(@giant, undef, @giant); # 200 001
"granite";
(@rocks, "crushed rock", @tiny, $dino);

@quarry
(bedrock, slate, lava, crushed rock, granite), @tiny Q
. ( , Q
undef, , Q
@stuff.) , Q
. Q
, ,
.2 , Q
, ( ).
undef, Q
.
, Q
.
. :
@copy = @quarry; #

pop push
, Q
. Perl Q
.3 Q
1

, $ @,
s a Scalar () Array ().
.

. ,
,
.
, .
, . .
Perl. pop, push
, ,
, 1.
Perl, Perl C
, , C ( Q
), Perl
, . Q
, .

69

Q
.
, Q
(, Q
). Q
,
.
pop :
@array = 5..9;
$fred = pop(@array); # $fred 9, @array
# (5, 6, 7, 8)
$barney = pop @array; # $barney 8, @array
# (5, 6, 7)
pop @array;
# @array (5, 6). ( 7 ).

pop
,
. ,
.
, pop (
) undef.
, , pop
, . Perl:
,
. push (
) :
push(@array, 0);
push @array, 8;
push @array, 1..10;
@others = qw/ 9 0 2 1
push @array, @others;

#
#
#
0
#
#

@array
@array
@array
/;
@array
(

(5, 6, 0)
(5, 6, 0, 8)


19)

: push Q
pop .
.

shift unshift
push pop (
, ,
). unshift shift Q
( ,
). :
@array = qw# dino fred barney #;
$m = shift(@array);
# $m "dino", @array

70

3.

$n = shift @array;

#
#
#
#
#
#
#

("fred", "barney")
$n "fred", @array
("barney")
@array
$o undef, @array 
@array (5)
@array (4, 5)

shift @array;
$o = shift @array;
unshift(@array, 5);
unshift @array, 4;
@others = 1..3;
unshift @array, @others; # @array (1, 2, 3, 4, 5)

pop, shift undef Q


.


, , , Q
. Q
:1
@rocks = qw{ flintstone slate rubble };
print "quartz @rocks limestone\n"; # ,
#

Q
; , :
print "Three rocks are: @rocks.\n";
print "There's nothing in the parens (@empty) here.\n";

, ,

:
$email = "fred@bedrock.edu"; # ! @bedrock

, Perl Q
@bedrock . Q
Perl :2
Possible unintended interpolation of @bedrock

@ ,
:
$email = "fred\@bedrock.edu"; #
$email = 'fred@bedrock.edu'; #

, Q
$", .
Perl, 5.6,
, ,
.

foreach

71


, :
@fred = qw(hello dolly);
$y = 2;
$x = "This is $fred[1]'s place";
# "This is dolly's place"
$x = "This is $fred[$y1]'s place"; #

Q
, . Q
. , $y
"2*4", 1, 7, Q
"2*4" ( $y, Q
) 2.1 Q
, ,
:
@fred
$fred
print
print

= qw(eating rocks is wrong);


= "right";
# "this is right[3]"
"this is $fred[3]\n";
# "wrong"  $fred[3]
"this is ${fred}[3]\n"; # "right" (
# )
print "this is $fred"."[3]\n"; # "right" ( )
print "this is $fred\[3]\n"; # "right" (
# )

foreach

; Perl Q
foreach. foreach
( )
:
foreach $rock (qw/ bedrock slate lava /) {
print "One rock is $rock.\n"; #
}

($rock ) Q
.
"bedrock", "lava".

. ,
, Q
. , ,
, :

, Perl ,
"2*4" .

72

3.
@rocks = qw/ bedrock slate lava /;
foreach $rock (@rocks) {
$rock = "\t$rock";
#
# @rocks
$rock .= "\n";
#
#
}
print "The rocks are:\n", @rocks; #
#

Q
? , . Perl Q

foreach.
. , Q
,
, undef, . Q
,
$rock, ,
.

: $_
foreach,
Perl $_. ( Q
) ,
. :
foreach (1..10) { # $_
print "I can count to $_!\n";
}

Perl,
. Q
, $_,
;
. Q
, : Q
print $_ :
$_ = "Yabba dabba doo\n";
print; # $_

reverse
reverse (, )
. ,
, ..
, :


@fred =
@barney =
@wilma =
@fred =

73

6..10;
reverse(@fred); # 10, 9, 8, 7, 6
reverse 6..10; #
reverse @fred; #
#

Q Q
@fred. Perl
() .
, reverse ;
. Q
, :
reverse @fred;
#  @fred
@fred = reverse @fred; #

sort
sort (, ) Q
. ASCIIQ
ASCIIQ . , ASCIIQ, Q
,
, . ASCIIQ
( 14
, Q
):
@rocks
@sorted
@back
@rocks

=
=
=
=

qw/ bedrock slate rubble granite /;


sort(@rocks);
# bedrock, granite, rubble, slate
reverse sort @rocks; # slate bedrock
sort @rocks;
#
# @rocks
@numbers = sort 97..102;
# 100, 101, 102, 97, 98, 99

, ,
, .
, 1,
, 9. re
verse, .
, :
sort @rocks;
# , @rocks
@rocks = sort @rocks; #


. , Q
. ,
, ,

74

3.

Perl.
, .
, Q
. : Q
, . ;
. Q
, Q , .
, Q
. , .
Perl Q
, .1 ,
Perl, .2
42 + #
sort #


.3
Perl ,
. 4 . Q
,
:
@people = qw( fred barney betty );
@sorted = sort @people; # : barney, betty, fred
$number = 42 + @people; # : 42 + 3 = 45

( ) Q
:
@list = @people; #
$n = @people;
# 3

, , , Q
, Q

, , Perl Q .
, . ,
Perl; Q
.
. Q
, ,
. Q
Perl , Q
.
, .
.
@people people, @
.

75

. , 1, Q
.

, ,

.
, ? Q
, .
, . , Q
, 2, Perl.
, , , Q
Perl . , , Q
, .
Q
. , sort Q
?
, Q Q
, sort undef.
: reverse. Q
.
(
, ):
@backwards = reverse qw/ yabba dabba doo /;
# doo, dabba, yabba
$backwards = reverse qw/ yabba dabba doo /;
# oodabbadabbay

, Q
. , Q
.
:
$fred = ;
@pebbles = ;
($wilma, $betty) = ;
($dino) = ;

#
#
#
#

,
, ;
. ,
, , ,
; (Q
, reverse @fred) .
Perl , Q
, !

76

3.

: Q
, . Q
; .
( ),
. Q
.
. Q
, :
$fred = ;
$fred[3] = ;
123 +
+ 654
if () { ... }
while () { ... }
$fred[] = ;

:
@fred = ;
($fred, $barney) = ;
($fred) = ;
push @fred, ;
foreach $fred () { ... }
sort
reverse
print

, ,

:
, Q
:
@fred = 6 * 7; # (42)
@barney = "hello" . ' ' . "world";

, :
@wilma = undef; # ! (undef)
# :
@betty = ( );
#

undef , undef
, , . Q
.1
1

,
, , Q
Perl. Q
.

<STDIN>

77



, Perl .
scalar.
Perl
:
@rocks = qw( talc quartz jade obsidian );
print "How many rocks do you have?\n";
print "I have ", @rocks, " rocks!\n";
# ,
print "I have ", scalar @rocks, " rocks!\n"; # ,

,
. , Q
. .

<STDIN>
<STDIN>
. ,
<STDIN> . Q
.
. :
@lines = <STDIN>; #

, <STDIN> .
? UNIX Q
, Linux Mac OS X, Q
ControlQD1; Perl2, Q
. DOS/Windows
ControlQZ.3 Q
,
.
, , ,
, , Q

2
3

;
stty.
UNIX, Q
.
Control .
Perl DOS/Windows ,
Q ControlQZ
.
("\n") .

78

3.

.
, .
,
chomp! , chomp
, Q
. :
@lines = <STDIN>; #
chomp(@lines);
#

, Q
:
chomp(@lines = <STDIN>); #

, Q
,
, .
(, , ), Q
.1 Q
.
, 400Q Q
? ,
.2 Perl Q
, (
) .
Q
.

.
1. [6] , ,
.
. Q
, ,
, ControlQD UNIX ControlQZ
Windows.

Q, seek, Q
. .
, . 400QQ
, , , ,
. , Perl
, : ,
; , .

79

2. [12] , (
) ,
. (
.) , Q
1, 2, 4 2,
fred, betty, dino betty:
fred betty barney dino wilma pebbles bammbamm

3. [8] , Q
( ) .
ASCIIQ ,
fred, barney, wilma betty, Q
barney betty fred wilma.
?
?


chomp, reverse, print . . Perl, ,
,
(subroutines).1 Q
Q
.
Perl ( ,
, ) Q
&. Q
, & , ;
. Q
& , ( ).
, , , , .
Q
. Q
&fred $fred, Perl
, .



sub, ( &) 2

1
2

, .
, , : Q
. Perl , Q
,
. , , .

81

, . 
:
sub marine {
$n += 1; # $n
print "Hello, sailor number $n!\n";
}


, C Pascal
.
, . Q
.
.1 ; Q
Q
.2
, Q
.3
, .
, Q
. ,
, ; ,
.
,
Perl
. , , Q

.


Q
( &):4

3
4

, ,
.
; Q
manQ perlsub.
,
, () ,
Perl.
, .
, .
@_
, . Q
, Q
!

82

4.
&marine;
&marine;
&marine;
&marine;

#
#
#
#

Hello,
Hello,
Hello,
Hello,

sailor
sailor
sailor
sailor

number
number
number
number

1!
2!
3!
4!


, Q
. &marine
, , ,
.
Q
, . Q
Perl ; Q
, , Q
, . , Q
Perl .
Perl
, Q
Q
. : Q
Perl
. , Q
, .
,
:
sub sum_of_fred_and_barney {
print "Hey, you called the sum_of_fred_and_barney subroutine!\n";
$fred + $barney; #
}

, ,
$fred $barney; $fred $barney
. :
$fred = 3;
$barney = 4;
$wilma = &sum_of_fred_and_barney;
# $wilma 7
print "\$wilma is $wilma.\n";
$betty = 3 * &sum_of_fred_and_barney; # $betty 21
print "\$betty is $betty.\n";

:
Hey, you called the sum_of_fred_and_barney subroutine!
$wilma is 7.
Hey, you called the sum_of_fred_and_barney subroutine!
$betty is 21.

83

print ,
. , Q
. ,
:
sub sum_of_fred_and_barney {
print "Hey, you called the sum_of_fred_and_barney subroutine!\n";
$fred + $barney; # !
print "Hey, I'm returning a value now!\n";
# !
}


, print.
print 1 ( ),
. , Q
,
.
() $fred
$barney? , Perl
. , Perl Q
,
, , , Q
. Q
,
.
Q
, . ,
$fred $barney:
sub larger_of_fred_or_barney {
if ($fred > $barney) {
$fred;
} else {
$barney;
}
}

$fred, $barney;
. Q
, $fred
$barney,
.
. Q
,
( Q
). , .

84

4.

larger_of_fred_or_barney , Q
Q
fred $barney. ,
$wilma $betty larger_of_fred_or_barney, Q
$fred $barney.
Q ,
(, $save_fred $save_barney), Q
$fred $barney.
, Perl Q
. , Q
:
$n = &max(10, 15); #

,
, . , Q Q
, Perl
( ) Q
@_ . Q
, ,
.
, $_[0],
$_[1] . . ( !)
$_ $dino[3]
( @dino) $dino ( Q
). Q
Q , Q
, Perl @_.
&max, &larger_of_
fred_or_barney. $fred Q
($_[0]), $barney ($_[1]).
:
sub max {
# &larger_of_fred_or_barney
if ($_[0] > $_[1]) {
$_[0];
} else {
$_[1];
}
}

, . Q Q
, , , Q
. .

85

:
&max , Q
:
$n = &max(10, 15, 27); # !

;
$_[2]. Perl , Q Q
.
@_ Q
undef, .
, &max, Q
.
@_ Q
;1 @_ ,
, Q
.2 ,
,
@_ @_.
, Q
@_, @_
.

Perl @_ ,
, Q
? , .
Perl ;
, . Q
, 
, my:
sub max {
my($m, $n);
# ,
($m, $n) = @_;
#
if ($m > $n) { $m } else { $n }
}
1

&,
( ), @_ Q
. ,
.
, Q
foreach (. ). Perl Q
.

86

4.

, Q
; $m $n Q
. :
Q
, .1 , Q
Perl , ,
$m $n ( Q
).2 , if
, , Q
. Perl ; ,
,
.
. ,
($m, $n) ? my Q
, Q
:
my($m, $n) = @_; #

Q
, Q
$m, $n.
. ,
,
$m $n.


Perl Q
. Q
, Q
Perl. , Perl
,
(. .
). , ,
Perl , ,
&max, Q
.
,
@_. , &max :

,
,
.
, Q
&max, .

87


sub max {
if (@_ != 2) {
print "WARNING! &max should get exactly two arguments!\n";
}
# ...
.
.
.
}

if Q
(. 3).
Q
; Q
.

&max
&max ,
:
$maximum = &max(3, 5, 10, 4, 6);
sub max {
my($max_so_far) = shift @_; #
#
foreach (@_) {
#
if ($_ > $max_so_far) {
#
$max_so_far = $_;
}
}
$max_so_far;
}

Q
; , Q
, , Q
. @max_fo_far
,
.
$max_so_far 3 ( Q
); shift Q
@_. @_ (5, 10, 4, 6),
3 . , Q
,
3 ( ).
foreach Q
@_.
$_ ( , @_ $_ Q
;

88

4.

). $_ Q
5. if , @max_so_far,
@max_so_far 5 .
$_ 10.
, $max_so_far.
$_ 4. , Q
$max_so_far (10); if Q
.
$_ 6, if Q
. , .
$max_so_far.
,
, : 10.


&max Q
, . Q
, ?
. Q
&max ? , , Q Q
:
$maximum = &max(@numbers);

, @numbers ; Q
, . , Q
, &max Q
?
$max_so_far shift
@_, () . ; , shift
undef, $max_so_far.
foreach @_, ,
0 .
Perl $max_so_far undef Q
. Q ,
.
, , , , Q
undef, , Q
.

(my)

89

(my)
, Q
, . ,
if, while foreach:
foreach (1..10) {
my($square) = $_ * $_; #
print "$_ squared is $square.\n";
}

$square ;
foreach.
, Q
. ,
. , Q
Q
. ,
$square, , Q
. Q
$square Q
, .
( Q
),
Q
.
, my
:
my($num) = @_; # , ($num) = @_;
my $num = @_; # , $num = @_;

$num Q
; Q
. Q
;
, Perl
(,
,
;
). Q
, ,
my.

90

4.

my() ,
, my
:1
my $fred, $barney;
my($fred, $barney);

# ! $barney
#

, my :2
my @phone_number;


undef , .

use strict
Perl .3

; use strict.
, Q
Q . Q
use strict Perl, Q
Q
.
? , Q
:
$bamm_bamm = 3; # Perl

. Q
, Q
:
$bammbamm += 1; # !

( Q
!), Perl Q
1. ,
, Perl , ( )
.
, , , Perl
.

2
3

, Perl Q
my; Q
1Q800QLEXICALQABUSE. strict, Q
, .
, 6.
?

use strict

91

Perl , Q
use strict ( , Q
):
use strict; # Enforce some good programming rules

, 1, Perl Q
my:2
my $bamm_bamm = 3; #

, Perl Q
, $bammbamm , Q
.
$bammbamm += 1; # :
#

, ;
Perl, $_
@_.3 use strict Q
, Q
.
, Q
use strict. .
( ) Q
, use strict,
. , Q
my , .
, use strict ,
.

2
3

Q
strict . Q
, perldoc strict (
) . ,
Q
() . Q
.
.
Q
$a $b, sort. Q
.
, use strict , Q
, .

92

4.

return
return
:
my @names = qw/ fred barney betty dino wilma pebbles bammbamm /;
my $result = &which_element_is("dino", @names);
sub which_element_is {
my($what, @array) = @_;
foreach (0..$#array) { # @array
if ($what eq $array[$_]) {
return $_;
#
}
}
1;
# ( return )
}

("dino")
@names. my :
$what @array , .
@names.
foreach @array ( 0, Q
$#array, 3).
foreach , 1
$what @array . , Q
. Q
return Perl Q
.
, ? Q
1 . ,
undef Perl,
1. return 1 Q
, return .
return Q
. , ,

, &larger_of_fred_or_bar
ney. , . ,
Perl, Q
.

, , == Q
eq?

93

return

&
, , ,
& . Q
Perl
, , Q
&
. ( ,
.)
, Perl ,
, & . Q
, , ,
:1
my @cards = shuffle(@deck_of_cards); # & shuffle
#

Perl Q
, & ; Q
:
sub division {
$_[0] / $_[1];
}

my $quotient = division 355, 113; # &division

, ,
, .
Q
, , .
Q
,
.
:
Perl, 
&.
Q
:
sub chomp {
print "Munch, munch!\n";
}
&chomp; # & !

&shuffle. ,
, .

94

4.

& chomp, ,
chomp. ,
:
Perl, Q
& (,
). ,
& , Q
; , , Perl
.1 Q
Perl,
Perl Q
. ,
; , Q
Perl ( perlmod perlsub) Q
Q
.


Q
. , Q
2, .
, , Q
.., ,
, . Q
, Q
:
sub list_from_fred_to_barney {
if ($fred < $barney) {
# $fred $barney
$fred..$barney;
} else {
# $fred $barney
reverse $barney..$fred;
}
}
$fred = 11;
$barney = 6;

,  ; , Q
, manQ perlfunc
perlop. Perl Q
.
,
, wantarray. Q
.

95

@c = &list_from_fred_to_barney; # @c (11, 10, 9, 8, 7, 6)

6 11, Q
reverse , $fred (11)
$barney (6).
, . return Q
undef Q
. ,
, Q
.


, my, Q
; Q
. state Q
Q Q
, Perl .
Q
marine, :
sub marine {
$n += 1; # $n
print "Hello, sailor number $n!\n";
}

use strict, Q
, Q
$n . $n Q
my,
.

state.
,
:
use 5.010;
sub marine {
state $n = 0; # private, persistent variable $n
$n += 1;
print "Hello, sailor number $n!\n";
}


strict. Q
Perl $n,
.
Perl $n.

96

4.

state
, . Q
Q
state:
use 5.010;
running_sum( 5, 6 );
running_sum( 1..3 );
running_sum( 4 );
sub running_sum {
state $sum = 0;
state @numbers;
foreach my $number ( @_ ) {
push @numbers, $number;
$sum += $number;
}
say "The sum of (@numbers) is $sum";
}

,
:
The sum of (5 6) is 11
The sum of (5 6 1 2 3) is 17
The sum of (5 6 1 2 3 4) is 21

, Q
: Perl 5.10 :
state @array = qw(a b c); # !

, Q
Perl:
Initialization of state variables in list context currently forbidden ...

.
1. [12] total,
. (:
/; Q
.)
. Q
25:
my @fred = qw{ 1 3 5 7 9 };
my $fred_total = total(@fred);
print "The total of \@fred is $fred_total.\n";
print "Enter some numbers on separate lines: ";

97

my $user_total = total(<STDIN>);
print "The total of those numbers is $user_total.\n";

2. [5] ,
1 1000.
3. [18] :
&above_average,
, . (Q
:
.) Q
:
my @fred = above_average(1..10);
print "\@fred is @fred\n";
print "(Should be 6 7 8 9 10)\n";
my @barney = above_average(100, 1..10);
print "\@barney is @barney\n";
print "(Should be just 100)\n";

4. [10] greet. Q
, Q
. , Q

greet( "Fred" );
greet( "Barney" );

:
Hi Fred! You are the first one here!
Hi Barney! Fred is also here!

5. [10] ,
, . ,

greet(
greet(
greet(
greet(

"Fred" );
"Barney" );
"Wilma" );
"Betty" );

:
Hi
Hi
Hi
Hi

Fred! You are the first one here!


Barney! I've seen: Fred
Wilma! I've seen: Fred Barney
Betty! I've seen: Fred Barney Wilma

5

/;
.
/ , Q
80% /
. Q
, , Q
. , .
, ,
.


. Q
<STDIN>.1
:
$line = <STDIN>;
chomp($line);

#
#

chomp($line = <STDIN>);

# ,


undef; :
while (defined($line = <STDIN>)) {
print "I saw $line";
}
1

, <STDIN>, Q
( Q
), .
.

99

:
, ,
( ),
while. , $line1
. Q
; , Perl Q
, :
while (<STDIN>) {
print "I saw $_";
}

Q
. :

( ). ,
while ! , Q
;
Perl.
.
, Perl ,
: Q
( , ,
) while. Q
$line, Perl $_, Q
:
while (defined($_ = <STDIN>)) {
print "I saw $_";
}

, :
. Q
(, Q
), $_ . Q
, while2 Q
, . Q
Q , .
(<STDIN>)
Perl $_.
.
1

, ,
chomp. chomp Q
, , ,
. .
, : for
while, .

100

5.

, Q
()
:
foreach (<STDIN>) {
print "I saw $_";
}

:
.
foreach $_. Q
, $_
.
:
while. ?
. while Perl
, , Q
. foreach Q
(
foreach ). , Q
Q
. 400Q Q
! Q
while,
( ).

<>
<>.
, Q
UNIX.1
Perl, Q
cat, sed, awk, sort, grep, lpr , Q
<> . Q , <>,
, .
, Q
.2 Q
1

UNIX.
.
Q
, . Q
,
, . ,
.
, Q
.

<>

101

,
:
$ ./my_program fred barney betty

my_program (
) fred,
barney, betty.
, Q
. ,
(), .1
,
fred  betty, , Q
fred, , betty.
?
,
, ; , Q
, ( Q
). Perl, Q
,
UNIX, . Q , Q

UNIX. Q
, , Q
, Q
. ,
Perl , .
<> Q
.
, , Q
:2
while (defined($line = <>)) {
chomp($line);
print "It was $line that I saw!\n";
}

, fred, bar
ney betty, : It was [ fred] that I
saw!, It was [ fred] that I saw! . .,
fred.
barney, Q
betty. Q
; <>
1

: , cat sed,
, . . .
, .

102

5.

,
.1 <> undef (
while) .

, Q
$_ :
while (<>) {
chomp;
print "It was $_ that I saw!\n";
}

, ,
. chomp ;
, chomp $_. Q
, !
<>
,
. , <>
(
while, ),
, .2 Q
, Q
<>, $_. : <> ,
( ) $_.
<> Q
, ( ) Q

can't open wimla: No such file or directory

<> Q
. cat
.


<> Q
@ARGV. , Q
Perl . , Q
( ),
1

( ), Q
Perl $ARGV.
, Q
"".
@ARGV <>,
. @ARGV .

103

@ARGV
.1
@ARGV , Q
; , shift
foreach. , Q
Q ,
(, , Perl w).2
<> @ARGV, , Q
. , Q
;
. , Q
, @ARGV Q
@ARGV. ,
, Q
:
@ARGV = qw# larry moe curly #; #
while (<>) {
chomp;
print "It was $_ that I saw in some stoogelike file!\n";
}


print
( , ) . Q
, .3 Q
, Q
, Q
:
1

C argc ( Perl )
, (
Perl $0, @ARGV).
,
.
manQ perlrun.
Q , Q
. Q
Getopt::Long Getopt::Std,
.
, , (
Perl) . Q
,
, ,
. , Q
, manQ perlvar.

104

5.
$name = "Larry Wall";
print "Hello there, $name, did you know that 3+4 is ", 3+4, "?\n";

, , print Q
:
print @array;
print "@array";

#
# ( )

print , ,
. ,
@array ,
@array, .1 ,
@array qw/ fred barney betty /2,
fredbarneybetty, fred barney betty
.
, ,
, @array , Q
chomp. , Q
. print Q
fred, barney betty .
:
fred
barney
betty

, ? Perl
. , Q
(fred ), ,
(barney ), Q
(betty Q
). , , Q
. Q
,
:
Perl , .
, , Q
.
.
,
,
1

, ; Q
perlvar.
, , ? Q
Perl.

105

print @array;

, Q
:
print "@array\n";

, print ()
\n. , ,
print.
. , Q

, .
, Q
() ,
Q
. , Q
, (
) Q
(, ).
.
( ) , Q
, Q
, .
Q
manQ Perl.
print , Q
. <> (
)
, :
print <>;

# 'cat'

print sort <>;

# 'sort'

, UNIX cat sort


, Q
. !
UNIX Perl

Perl , UNIX
. , Q
.1
1

, PPT (Perl Power Tools),


UNIX Perl,
( !), , Q
. PPT
UNIX .

106

5.

, : print Q
, Q
. , Perl , Q
. ,
:
print("Hello, world!\n");
print "Hello, world!\n";

. Perl , :
print , .
, ?
, 1 Q
:
print (2+3);

, , Q
. 5, , Q
, . print true false
, .
( Q
/), $result
1:
$result = print("hello world!\n");

Q ? , Q
4:
print (2+3)*4; # !

, Perl 5, .
print, 1, 4 Q
, , Q
. Q ,
: Perl ! 20, 5!
; ,
, , . Q
print , Q
;
. print Q
, print Q
1

, Perl

. Perl
, . Q
, . Q
, manQ.

107

, .
Perl :
( print (2+3) ) * 4; # !

, Perl ,
.
w use warnings, , Q
.
, Q Q
, Q
1 Perl, print. print
. print (
) ,
,
.


print Q
. Q
printf C. : Perl Q
.
printf , Q
. 2
:
printf "Hello, %s; your password expires in %d days!\n",
$user, $days_to_die;

(conver
sions). (%) Q
. ( ,
.)
; , Q
. Q
,
:
Hello, merlyn; your password expires in 3 days!

1
2

, 0 1 , .
. Perl
formats, Q
B ( ), Q
. .
, .

108

5.

%g, Q
: Q
, :
printf "%g %g %g\n", 5/2, 51/17, 51 ** 17; # 2.5 3 1.0683e+29

%d 1, Q
:
printf "in %d days!\n", 17.85; # in 17 days!

: , . ,
, .
Perl printf
, Q
. , Q
, :
printf "%6d\n", 42; # ````42 ( ` )
printf "%2d\n", 2e3 + 1.95; # 2001

%s ;
, :
printf "%10s\n", "wilma"; # `````wilma


( ):
printf "%15s\n", "flintstone"; # flintstone`````

%f () Q
:
printf "%12f\n", 6 * 7 + 2/3;
# ```42.666667
printf "%12.3f\n", 6 * 7 + 2/3; # ``````42.667
printf "%12.0f\n", 6 * 7 + 2/3; # ``````````43

, Q
%%; , :2
printf "Monthly interest rate: %.2f%%\n",
5.25/12; # "0.44%"

%x %o
, .
, , % \.
, . ,
, "\%" '%'.
, printf
, . , C Q
printf.

109

printf

printf. , Q
, Q
. ,
.
,
. ,
,
( ):
my @items = qw( wilma dino pebbles );
my $format = "The items are:\n" . ("%10s\n" x @items);
## print "the format is >>$format<<\n"; #
printf $format, @items;

x (. 2) @items Q
( ). Q
3,
. ,
The items are:\n%10s\n%10s
\n%10s\n. Q

10 . , ?
, :
printf "The items are:\n".("%10s\n" x @items), @items;

@items Q
, .



Perl, Perl /
. ,
/, .
,
Perl ( , Q
, ). Q
Q
, Q
10. ,

, ,
Q
( ).

110

5.

Perl
: STDIN, STDOUT, STDERR, DATA, ARGV ARGVOUT.1 Q
Q
, ,
.2
, .
STDIN /Q
Perl ,
( ). Q
, Q
, .3
STDOUT. Q
, , Q
.
Q
/ UNIX,
.4 ,
STDIN
STDOUT, ,
( , ). Q
:
$ ./your_program <dino >wilma

, Q
dino, Q
wilma. STDIN, Q
(, )
STDOUT, .
1

Q
(, stdin). ,
, . Q
, , ,
. , , , Q
, .

. , , ,
Perl, .
/,
UNIX . ,
. Q
16 , Perl.
,
, UNIX, manQQ
perlport UNIX (Q
,
) .

111

,
(pipelines). Q
UNIX,
:
$ cat fred barney | sort | ./your_program | grep something | lpr

UNIX, .
, cat Q
fred, barney. Q
sort,
your_program. your_prog
ram grep, Q
, lpr .
UNIX
, , Q
.
;
.
/
. ( ) your_program Q
Q Q
, . grep Q
, , ,
, . Q
, , Q
. 
STDERR. Q
, , Q
. 1,

$ netstat | ./your_program 2>/tmp/my_errors


, Perl STDIN, STDOUT
STDERR, ,
(, ).
, Q
1

. ,

(, ), Q
. , ,
, Q
, .

112

5.

open.
/
. :
open
open
open
open

CONFIG, "dino";
CONFIG, "<dino";
BEDROCK, ">fred";
LOG, ">>logfile";

CONFIG
dino. , () dino ,
Q
CONFIG. Q
STDIN

<dino. , Q
. , , <
, ,
.1
< ,
, , , Q
> . BEDROCK
fred.
, > Q
, Q
fred. ,
.
, > (
)
. , ,
. , Q
>. ,
; Q
. ,
LOG (),
logfile.
1

. Q
( 14),
. $name
, , $name
. ,
. "< $name" Q
, , Q
. . Q
(
, ) manQQ
perlopentut.

113

Q
, :
my $selected_output = "my_output";
open LOG, "> $selected_output";

>. Perl 1,
, $selec
ted_output ">passwd" (
, ).
Perl ( Perl 5.6)
open :
open CONFIG, "<", "dino";
open BEDROCK, ">", $file_name;
open LOG, ">>", &logfile_name();

, Perl Q
( ) ( Q
), .2
(, Q
CPAN), ,
Perl.3


Perl . ,
, Q
. , Q
Q ,
.
Q
(. . , Q
), .
( /, ,
undef

, , ,
Perl. , perlfunc per
lopentut.

:
.
( 7),
.
, Q
Perl / manQ perlsec.
, use 5.6.

114

5.

.) Q
, .
, . Q
, w Q
use warnings Perl , Q
. open ,
, true false
. :
my $success = open LOG, ">>logfile"; #
if ( ! $success) {
# open
...
}

, . , Q
.


Q
close:
close BEDROCK;

Perl
, ,
, Q
.1 Perl
(
open) .2
1

/, , Q
.
: , Q
. , Q
. Q
, (. .
).
, .
/ .
( ) Q
, Perl, Q
.
, Q
, Perl , Q
. Q
Perl (, Q
),
. .

die

115

Perl
close. , Q
open close.
Q
, Q
.1

die
. , Q
/ ( ).
, Q
.
Perl (,
, Q
, ), Q

.2 Q
die, Q
.
die , ( Q
, ), Q
.
, , ,
UNIX ( ), Q
, ,
. , Q
(, make), ,
.
, Q Q
. 0 Q
, . Q
, 1 Q
, 2 , 3 Q

Q
.
, Q
. , Q
, Q ,
.
, Q
, , .
, ;
eval, 17.

116

5.

;
. 0 , Q
. Q
, (, make) , Q
.
,
:
if ( ! open LOG, ">>logfile") {
die "Cannot create logfile: $!";
}

open , die Q
, . $! Q
? , Q
. ,
(, ), $!
(, ).
perror C
. Perl
$!.1 ;
, .
die , Q
, $!
; ,
Perl. Q
, Q
.
.
, die :
Perl 2,
, die Q
. Q
(,
$! permission denied):
Cannot create logfile: permission denied at your_program line 1234.

, UNIX, $! Q
error number 7; ,
. Windows VMS Q
$^E.
,
( ) Q
; Q
.

die

117

Q
, .
,
,
:
if (@ARGV < 2) {
die "Not enough arguments\n";
}

,
.
, ,
( , Q
). : Q
,
, ,
.1
open,
.

warn
die ,
Perl (, ),
warn , Q
Perl (, undef ,
, ).
warn , die,
. , die2,

.

$0; Q
: $0:Not enough arguments\n. ,
Q
, , Q
. , $0
. ,
, Q
__FILE__ __LINE__ ( caller) ;
.
, , Q
eval. Q
, __WARN__ ( manQQ
perlvar).

118

5.

,
/.
.


,
,
STDIN. ,
UNIX :
if ( ! open PASSWD, "/etc/passwd") {
die "How did you get logged in? ($!)";
}
while (<PASSWD>) {
chomp;
...
}

die $!
. ,
. ( Perl
.) , , Q
, Q
: ( ) Q
.
, , Q
print printf.
, :
print LOG "Captain's log, stardate 3.14159\n"; # LOG
printf STDERR "%d percent complete.\n", $done/$total * 100;

,
?1 .
:
printf (STDERR "%d percent complete.\n", $done/$total * 100);
printf STDERR ("%d percent complete.\n", $done/$total * 100);

. Q
, : , ! , Q
!
,
: , Q
.

119



, print ( printf ,
, )
, STDOUT.

select. Q
BEDROCK:
select BEDROCK;
print "I hope Mr. Slate doesn't find out about this.\n";
print "Wilma!\n";

, , Q
. ,
STDOUT Q
.1 Q
. $| 1, Q
(
) .
, , Q
(, Q
, Q
), :
select LOG;
$| = 1; # LOG
select STDOUT;
# ... , , ...
print LOG "This gets written to the LOG at once!\n";



, Q
(
FRED,
FRED) . ,

1

, STDOUT Q Q
, ,
select manQ perlfunc. Q
manQ, , Perl
select manQ
perlfunc. select ,
select .

120

5.

, Q
. , die warn
Perl Q
STDERR. , , Q

:1
#
if ( ! open STDERR, ">>/home/barney/.error_log") {
die "Can't open error log for append: $!";
}

STDERR , Q
Perl, . Q
die , Q
?
Q
STDIN, STDOUT STDERR , Perl Q
.2 Perl Q
( ) , ,
. ,

3 ,
Q
/.

say
Perl 5.10 say Q
Perl 6 (, , println
Pascal). say , print, Q

. Q
, Q
.
(Q
, Q cron at). Q
: , (Q
, system exec . 16) , Q
/.
, Perl $^F,
Perl,
.
.
STDIN . Q
,
.

121

.
:
use 5.010;
print "Hello!\n";
print "Hello!", "\n";
say "Hello!";

, Q
print
say. Q
,
:
use 5.010;
my $name = 'Fred';
print "$name\n";
print $name, "\n";
say $name;

,
. Q
:
use 5.010;
my @array = qw( a b c d );
say @array;

# "abcd\n"

say "@array"; # "a b c d\n";

print say Q
:
use 5.010;
say BEDROCK "Hello!";

Perl 5.10, Q
, Q
Perl 5.10. print Q
, , Perl
(
\n).

.
1. [7] , cat, Q
. (
tac.) Q

122

5.

./tac fred barney betty,


betty , barney
fred ( ).
./ , Q
tac, !
2. [8] ,


20 . ,
, (Q
). ,
19 ! , Q
hello,goodbye :
123456789012345678901234567890123456789012345678901234567890
hello
goodbye

3. [8] ,
. , 30,hel
lo,goodbye ( )
30 . (: , Q
, 2.) Q
, Q
.

Perl,
: .1
Q
, Q
.
Perl, , .

?
, , , Q

. ,
, Q
. , ( ) Q
, (. 6.1).
. Q
3
wilma.
Q
.
:
3, wilma.
(. 6.2), Q
.
1

Q . 1995 Q
Perl , ,
.

124

6.

foo

35

bar

12.4

2.5

hello

wilma

1.72e30

betty

bye\n

. 6.1.

2.5
quark
apple
hammer

time
pi
Q5
cow
larry

. 6.2.

, ,
. ,
. Q
0, 1, 2 . .
, . Q
Q.

125

Q
, . , Q
50/20 1, Q
"2.5",
. 6.1.
, Perl Q
:
Q Q
.
(, awk,
) Q
. Perl Q
.2 , Q
Q, Perl Q
.
, Q
. .
, ,
. , ,
undef .3
, .

?
(
, Q
), :
? , Q
, Q .
, Q
Perl:
,
() (). Q
, tom phoenix. ,
;
randal, .
1

, "50/20". Q
, , , Q
.
Perl Q , . Q
, ,
Q.
, ,
.

126

6.

, IPQ
, ,
( http://www.stonehenge.com) IPQQ
123.45.67.89. Q
, . Q
Q
. IPQ
.
IPQ,
.
IPQ , Q
, IPQ Q
. Q
: Q
; Q
.
! , Q
: IPQ,
. , ,
.
,
. ,
!
: , Q
. , Q
, fred , Q
fred , ,
. Q
. Q
, fred Q
, fred, 1. ,
fred , 2,
3. fred Q
, undef ( ) 1.
, []

:
,
.
,
,
. Q
, .

127

,
.
, Q
, , Q
, , .


, Q
:
$hash{$some_key}

,
Q
.1 , :
$family_name{"fred"} = "flintstone";
$family_name{"barney"} = "rubble";

. 6.3 , .
:
foreach $person (qw< barney fred >) {
print "I've heard of $person $family_name{$person}.\n";
}

, Q
Perl ( , Q
, ). , Q
, . . $family_na
me{"fred"} , ,
&family_name. , ,
. Perl ,
$family_name

fred

flintstone

barney

rubble

. 6.3.
1

: Q
, , Q
, .

128

6.

$family_name[5]. , , ,
Perl, , ,
. $, Q
, , .
, , Q
:
$foo = "bar";
print $family_name{ $foo . "ney" }; # "rubble"

Q
:
$family_name{"fred"} = "astaire"; #
#
$bedrock = $family_name{"fred"}; #
#



"astaire";

,
: $pebbles[17] $dino,
.
$family_name{"fred"}, .
:
$family_name{"wilma"} = "flintstone";

#
# ( )
$family_name{"betty"} .= $family_name{"barney"}; #
#

, : Q
$pebbles[17] $dino ,
. $fami
ly_name{"betty"} , .

undef:
$granite = $family_name{"larry"}; # larry : undef

, :
$pebbles[17] $dino Q
, undef. $fami
ly_name{"larry"} ,
undef.


( ), Q
% (). , , Q
, Q
%family_name.

129

, . Q
( . 6.1)
, Q:1
%some_hash = ("foo", 35, "bar", 12.4, 2.5, "hello",
"wilma", 1.72e30, "betty", "bye\n");

( )
Q:
@any_array = %some_hash;

Q
Q . , Q
:
print "@any_array\n";
# :
# betty bye ( ) wilma 1.72e+30 foo 35 2.5 hello bar 12.4

, Perl Q
,
. , Q
Q
.
, Q, Q

. , ,
foo, ,
(38) .


, Q
:
%new_hash = %old_hash;

Perl , Q
. Pascal C,
, Q
Perl . , Q
Perl %old_hash /,
, , %new_hash.

Q
, , Q
Q. , ,
, Perl
.

130

6.

,
. , , Q
:
%inverse_hash = reverse %any_hash;

%any_hash QQ
; (, , , ). Q
reverse : (
, , , ). ,
, . %inverse_hash Q
, %any_hash,
%inverse_hash . Q
, %any_hash.
, ( )
( ).
, Q
, ,
,
. Perl Q
: .
, , , Q
. , , Q
,
, .
, ,
.1 IPQ Q
:
%ip_address = reverse %host_name;

IPQ,
.


, Q
, . ,
, 2.5 Q
( ),
, , , :
%some_hash = ("foo", 35, "bar", 12.4, 2.5, "hello",
"wilma", 1.72e30, "betty", "bye\n");
1

. ,
%family_name ( , Q
) , Q
. , slate,
, .

131

QQ
, Q
, ? , Q
=>.1 Perl Q
Q
, .
, Perl , Q
(,), ; Perl
.2 ,
:
my %last_name
"fred" =>
"dino" =>
"barney" =>
"betty" =>
);

= ( #
"flintstone",
undef,
"rubble",
"rubble",

(, , )
, ,
. Q
. Q
, , . Q
, , Q
Q .
Perl ,
() .


, Perl
.

keys values
keys , values Q
. Q
, :
1

, (>), Q
. ; , Q
manQ perlreftut perlref.
Q :
(bareword) ( , ,
, + )
. ,
.
,
.

132

6.
my %hash = ("a" => 1, "b" => 2, "c" => 3);
my @k = keys %hash;
my @v = values %hash;

@k "a", "b" "c", @v 1, 2


3. ; ,
Perl . Q
, :
, "b" ,
2 ; "c"
, 3 , . .
, Q
. Perl
, , Q
.1 Q
( Q).
, :
my $count = keys %hash; # 3 ( "")

(true/false) Q
:
if (%hash) {
print "That was a true value!\n";
}

( ) ,
Q.2 , Q
:
.

each
,
. Q
each, QQ
.3 Q
1

, keys values
,
.
.

, Perl.
"4/16",
, Q
.
foreach
; .

133

Q,
. ,
each .
each
while :
while ( ($key, $value) = each %hash ) {
print "$key => $value\n";
}

. each %hash
Q Q
; , "c" 3,
("c", 3). ($key, $value),
$key "c", $value 3.

while, . (
true/false Q
.)
,
2. 2 Q
, c = >3.
each %hash Q
; , ("a", 1).
( each , ,
; ,
1.) Q
($key, $value). Q
2, ; while , Q
, a => 1.
. ,
, b => 2.
. Perl
each %hash, Q , Q

, Q
each , Q
. , : Q
Q , Q
, keys values.

each. Q
, Q
, . Q
, , , Q
, each .

134

6.

each .1
($key, $value), $key $value
undef.
,
while. Q

; 0. 0
false, while ,
.
, each Q Q
. (, , Q
keys values; .)
, Q
; :
foreach $key (sort keys %hash) {
$value = $hash{$key};
print "$key => $value\n";
# $value:
# print "$key => $hash{$key}\n";
}

14.


.
Perl ,
, Q
:
$books{"fred"} = 3;
$books{"wilma"} = 1;

, ;
:
if ($books{$someone}) {
print "$someone has at least one book checked out.\n";
}

:
$books{"barney"} = 0;
#
$books{"pebbles"} = undef; # 
#
1

, Q
undef ; (
) () (undef).

135

pebbles ,
undef 0.
,
. (. . ) Q
, undef,
.

exists
, (. . Q
),
exists. true,
, :
if (exists $books{"dino"}) {
print "Hey, there's a library card for dino!\n";
}

, exists $books{"dino"} true ( )


, keys %books dino.

delete
delete (
) . ( ,
, .)
my $person = "betty";
delete $books{$person}; # $person

Q
undef ! exists($books{"betty"})
; Q
, undef
.
delete undef
, Q
.


,
, , :
foreach $person (sort keys %books) {
#
if ($books{$person}) {
print "$person has $books{$person} items\n"; # fred has 3 items
}
}

136

6.

: Perl Q
"%books" ,
(%books1). , , Q
\ ,
: $ @, Q
; ",
; \, Q
. , ,
.2

%ENV
Perl, , Q
(environment) .
Perl %ENV. , %ENV
PATH:
print "PATH is $ENV{PATH}\n";


:
PATH is /usr/local/bin:/usr/bin:/sbin:/usr/sbin

, Q
.
:
Bourne
$ CHARACTER=Fred; export CHARACTER
$ export CHARACTER=Fred

csh
% setenv CHARACTER=Fred

command (DOS Windows)


C:> set CHARACTER=Fred

:
Q, . Q
, %
printf; Q
.
('), ([),
({), (>) (::) Q
Q ,
.

137

,
Perl:
print "CHARACTER is $ENV{CHARACTER}\n";

.
1. [7] ,
.
(
, ) Q
:

fred

flintstone

barney

rubble

wilma

flintstone

2. [15] , (
1),
. (: , undef
Perl 0. Q
, .)
, fred, barney, fred, dino, wilma, fred (Q
); Q
, fred 3 . Q
, ASCIIQ.
3. [15]
%ENV. ASCIIQ Q
. , Q
. length Q
. , Q
,
.

, , Q
.

Perl ,
.
, Q
.
.
Q, Q
, Perl. (, Q
!1 , .)
, (Q
) Perl. ,
Perl.
Perl;
sed awk, procmail, grep, Q
(, vi emacs) Q
. , , Q
. , , Q
: Q
Web ( Perl),
. . , Q
,
, ( , ) Q
.

Q , Q
. .

139

?
, Q
, . , Q
;
: ,
, ,
. QQQQ
; , .
, ,
. Q
, , ,
.1 Q
Q,
. ,

: , , .2
.
, Q
UNIX grep,
. , UNIX grep
, flint,
stone,
:
$ grep 'flint.*stone' chapter*.txt
chapter3.txt:a piece of flint, a stone which may be used to start a fire by
striking
chapter3.txt:found obsidian, flint, granite, and small stones of basaltic
rock,
which
chapter9.txt:a flintlock rifle in poor condition. The sandstone mantle held
several

Q
, . ,
*.pm UNIX,
.pm.
chapter*.txt. (, , Q
; , Q

, ,
.
. , .
, Perl Q
. , Q
, .

140

7.

.) ,
, .1 Q
13 , .


, () Q
$_, /,
:
$_ = "yabba dabba doo";
if (/abba/) {
print "It matched!\n";
}

/abba/ $_;
, true. $_
, . Q
, ; , ,
.
Q
true false, if
while.

, . Q
, /coke\tsprite/ Q
11 : coke, sprite.


, Q
, . , Q
, Q
.
, (.) ,
(
"\n"). , /bet.y/ betty, betsy,
bet=y, bet.y , bet, Q
( )
y. bety betsey , t y

(!) . , Q
UNIX ( , Q
) , Q
, , , .
UNIX.

141

.
, .
,
.
( ), Q
. ,
,
. , Q
Perl: Q
. ,
/3\.14159/ .
, .
\,
Perl.


Q
. (*)
. , /fred\t*barney/
fred barney: "fred\tbarney"
, "fred\t\tbarney" ,
"fred\t\t\tbarney" , "fredbarney"
. , * Q
, , . ,
* ,
, ( Q
,
*).
Q
? 1, .* Q
, . , Q
/fred.*barney/ fred barney, Q
. , fred (Q
) barney, .
.* ,
.
, Q
. Q
1

. Q
, , , .
, ,
, . Q
Q Q
, ?

142

7.

; (+),
: /fred +barney/ Q
, fred barney ( , Q
!). .
fredbarney , Q
, . Q
, + Q
, ( ) .
, * +, Q
. (?) , Q
. , Q
.
, Q
.
( ) (
). . , /bamm?bamm/
: bammbamm bammbamm. Q
; : Q
, ? ?
Q ,

.


, ()
. ,
. , /fred+/
, fredddddd,
. , /(fred)+/ Q
fredfredfred, ,
. /(fred)*/?
, , hello, world.1

, . Q
, Q
. Q
, : \1, \2
. . .

fred. Q
, !
, .

143

,
. ,
, \1:
$_ = "abba";
if (/(.)\1/) { # 'bb'
print "It matched same character next to itself!\n";
}

(.)\1 , ,
. (.) a, Q
, a,
. Perl
, (.) b.
\1 ,
b, .
Q
. Q
, , y;
\1 , Q
d:
$_ = "yabba dabba doo";
if (/y(....) d\1/) {
print "It matched the same after y and d!\n";
}

,
. Q
,
, ,
, .
\2,
\1. (Q
, abba):
$_ = "yabba dabba doo";
if (/y(.)(.)\2\1/) { # 'abba'
print "It matched the same after y and d!\n";
}

: , Q
? , ,
, :
, :
$_ = "yabba dabba doo";
if (/y((.)(.)\3\2) d\1/) {
print "It matched!\n";
}

144

7.

,
(
1):
(

#
(.) #
(.) #
\3
\2

Perl 5.10 .
Q
\g{N}, N . Q
.
, ,
. \1
,
, 11:
$_ = "aa11bb";
if (/(.)\111/) {
print "It matched!\n";
}

Perl , : \1, \11 \111? Perl Q


, ,
, \111. Q
111 ( 11) , Perl
.
\g{1}
:2
use 5.010;
$_ = "aa11bb";
if (/(.)\g{1}11/) {
print "It matched!\n";
}

\g{N} .

.
, 1:
1


/x, .
\g{1} ; Q
\g1, .
, .

145

use 5.010;
$_ = "aa11bb";
if (/(.)\g{1}11/) {
print "It matched!\n";
}

, Q
. Q
, Q

, :
use 5.010;
$_ = "aa11bb";
if (/(.)(.)\g{1}11/) {
print "It matched!\n";
}

(|) ,
, . ,
, Q
. ,
/fred|barney|betty/ ,
fred, barney betty.
/fred( |\t)+barney/,
, fred barney , Q
. +
; ( |\t) Q
Q
.1 , ,
.
, fred barney Q
, /fred( +|\t+)barney/.
,
.
/fred (and|or) barney/ ,
: fred and barney fred or barney.2
/fred and barney|fred or
barney/, . ,
1


(. ).
: and or
! ,
.

146

7.

, Q
.


, Q
([]), , . Q
, Q
.
, [abcwxyz] Q
.
(),
[acwz]. Q
,
[azAZ], 52.1 Q
,
, ; , [\000\177] Q
ASCIIQ.2 ,
; Perl Q
. ,
:
$_ = "The HAL9000 requires authorization to continue.";
if (/HAL[09]+/) {
print "The string mentions some model of HAL computer.\n";
}

, , Q
. (^) Q
. , [^def]
, .
[^n\z] , n, z. (
: ,
. ,
/HAL[09]+/ , Q
.)


, Q
. ,
[09] \d. Q

..

, E, I^, O
/ U.
52 , A

, .
, ASCII, EBCDIC.

147

, /HAL[09]+/
/HAL\d+/.
\w : [AZa
z09_]. ,
, . Q
, Q
, .
Perl Q
, .1 ,
,
, .
, \w , Q
. Q
+. /fred \w+barney/ Q
fred, , ,
barney. , , Q
fred barney , Q
.
, , , Q

. \s Q
; [\f\t\n\r ]. ,
, : , Q
, , .
;
. Q
\s
, (
) \s*,
\s+. ( , \s Q
.)
, Q
.
Perl 5.10 Q
. \h Q
( );
[\t ]. \v ,
[\f\n\r]. \R ;
, ,

; \R .

( ) Q
; . manQ perllocale.

148

7.



. ,
[^\d], [^\w] [^\s], , 
, .
: \D,
\W \S. , Q
.

( )
. , Q
/[\dAFaf]+/ Q
, ABCDEF ( Q
) .
, [\d\D], Q
Q , ! Q
,
( , ,
). ,
[^\d\D], , Q
Q. , !

. (
, . , Q
, Q
. .)
1. [10] ,
, fred ( Q
).
Fred, frederick Alfred?
, fred flintstone .1 Q

.
2. [6] ,
Fred. Q
Fred, frederick Alfred? (
.)
3. [6] , Q
, (.);
1

The Flintstones . 
.

149

. Q
; Mr. Slate?
4. [8] , Q
, (
!) Fred,
fred FRED?
5. [8] ,
,
. , Q
Mississippi, BammBamm llama.
6. [8] :
, wilma
fred.

.
, Perl.

m//
/, Q
/fred/. Q
m//. Q
qw//, Q
. , Q
m(fred), m<fred>, m{fred} m[fred]
, m,fred,, m!fred!, m^fred^, Q
.1
, m
. Perl
, Q
// Q
/fred/.

, Q
;
.

151

, ,
.1 , , Q
URLQ, : /http:\/\//. Q
, , Q
: m%http://%.2
.
Q
; Q
.


, .
.

(/i)
, Q
FRED, fred Fred, Q
/i:
print "Would you like to play a game? ";
chomp($_ = <STDIN>);
if (/yes/i) { #
print "In that case, I recommend that you go bowling.\n";
}

(/s)
(.) ;
,
.
, Q

Q
,
. , m(fred(.*)bar
ney), m{\w{2,}} m[wilma[\n\t]+betty] , ,
;
. (< >) Q
, Q
. , m{(\d+)\s*>=?\s*(\d+)} Q
, > Q
,
.
: ,
, .

152

8.

, /s.
1
[\d\D], ,
. , Q
, :
$_ = "I saw Barney\ndown at the bowling alley\nwith Fred\nlast night.\n";
if (/Barney.*Fred/s) {
print "That string mentions Fred after Barney!\n";
}

/s , Q
.

(/x)

, :
/?\d+\.?\d*/
/ ? \d+ \.? \d* /x

# ?
#

/x , Q
.

\t ( ), \s
( \s*, \s+).
, Perl . Q
, , ,
:
/
?
\d+
\.?
\d*
/x

#
#
#
#
#

# , Q
, , Q
\# [#]. , Q
,
.


,
( ):
1

, Q
, [\d\D].

153

if (/barney.*fred/is) { # both /i and /s


print "That string mentions Fred after Barney!\n";
}

:
if (m{
barney #
.*
#
fred #
}six) { # : /s, /i /x
print "That string mentions Fred after Barney!\n";
}

Q
;
.


Q
.
. manQ perlop,
m// ,
.

, Q
Perl , Q
.
, .
^1 (, ) ,
$ 2. , /^fred/
; manfred mann
. /rock$/ c rock
; knute rockne .
1

, .
. Q

. ,
.
, ,
.
, .
,
, /^fred$/ "fred",
"fred\n".

154

8.

; ,
. /^\s*$/,
. , Q
(, ),
. , , Q
, Q
. .


. Q
, \b, .1 ,
/\bfred\b/ fred, frederick, alfred
manfred mann. Q
2 .
, , Q
; ,
, . \b
\w.
. 8.1 , Q
, \b. Q
, Q
.
, ;
, ,
/\w+/. : That, s, a, word
boundary.3 : word Q
, \w.

That ' s

"word"

boundary!

. 8.1. \b
1


, Perl \b.
Microsoft Word. 
. .
, :
That's , , Q
. , ,
soupon .

=~

155

, ,
\b
.
cat deli
catessen, dog boondoggle fish selfishness.
, /\bhunt/
, hunt, hunting hunter, shunt, /sto
ne\b/ , sandstone flintstone, capstones.
\B ,
\b. , /\bsearch\B/ Q
searches, searching searched, search researching.

=~
$_ ; 
=~ Perl
( $_1). :
my $some_other = "I dream of betty rubble.";
if ($some_other =~ /\brub/) {
print "Aye, there's the rub.\n";
}

Q
. ! Q
: ,
$_, .
, Q
$_.
( ) , ,
$likes_perl ,
. Q
, Q
. , Q
.2 $_
.
print "Do you like Perl? ";
my $likes_perl = (<STDIN> =~ /\byes\b/i);
... # ...
if ($likes_perl) {

, Q
.
, $_ ,
while
(<STDIN>).

156

8.
print "You said earlier that you like Perl, so...\n";
...
}

,
, Q
, , Q
( ) :
my $likes_perl = <STDIN> =~ /\byes\b/i;



( ).
grep Q
:
#!/usr/bin/perl w
my $what = "larry";
while (<>) {
if (/^($what)/) { #
print "We saw $what in beginning of $_";
}
}

$what.
, Q
/^(larry)/ larry Q
.
$what ;
@ARGV:
my $what = shift @ARGV;

fred|bar
ney, /^(fred|barney)/ fred bar
ney .1 ( Q
larry) ;
fred barney .
, @ARGV,
UNIX grep.
. $what
1

, fred|barney Q
, Q
. Q

.

157

'fred(barney',
/^(fred(barney)/, Q
.
1, Q
(
) . Q
: Q
, .



. Q
Q
. , Q
.
, . Q
,
.
, Q
; Perl
$1 $2.
. Q
, $4 , .2
Q
,
:
$_ = "Hello there, neighbor";
if (/\s(\w+),/) {
#
print "the word was $1\n"; # the word was there
}

:
$_ = "Hello there, neighbor";
if (/(\S+) (\S+), (\S+)/) {
print "words were $1 $2 $3\n";
}
1

eval,
quotemeta ( Q
\Q).
\4 Q
. , Q
; \4 , $4
. Q
manQ perlre.

158

8.

: Hello there
neighbor. .
,
. Q
, , Q
.
1, Q
. ,
:
my $dino = "I fear that I'll be extinct after 1000 years.";
if ($dino =~ /(\d*) years/) {
print "That said '$1' years.\n"; # 1000
}
$dino = "I fear that I'll be extinct after a few million years.";
if ($dino =~ /(\d*) years/) {
print "That said '$1' years.\n"; #
}


Q
.2 , Q
,
. , Q
Q
; Q
, . ()
$wilma.
, Q
:
$wilma =~ /(\w+)/; # BAD! Untested match result
print "Wilma's word was $1... or was it?\n";

, Q
if while:
if ($wilma =~ /(\w+)/) {
print "Wilma's word was $1.\n";
} else {
1

undef.
, $4
undef.
( Q
), ,
,
.

159

print "Wilma doesn't have a word.\n";


}

Q
, Q
.
$1 Q
,
$1 . Q
Q
, Q
. Q
:
if ($wilma =~ /(\w+)/) {
my $wilma_word = $1;
...
}

9 , 
Q
$1.


,
Q
. ,
?
, .
bronto Q
, , Q
. Q
steak burger, Q
, .
if (/(bronto)?saurus (steak|burger)/) {
print "Fred wants a $2\n";
}

bronto , Q
$1. : , Q
, Perl Q
. $2.
Q
.
, Perl Q
Q
, . Q
, .

160

8.

Q
(?:)1; Perl, Q
.
bronto Q
; , Q
, $1:
if (/(?:bronto)?saurus (steak|burger)/) {
print "Fred wants a $1\n";
}

, ,
BBQ ( Q).
,
, , Q
$1.
, Q
:
if (/(?:bronto)?saurus (?:BBQ )?(steak|burger)/) {
print "Fred wants a $1\n";
}

Perl Q
, Q
: ,
Q
. manQ perlre.



, $1, $2 . .
. Q
Q
.
$names:
use 5.010;
my $names = 'Fred or Barney';
if( $names =~ m/(\w+) and (\w+)/ ) { #
say "I saw $1 and $2";
}

?, Q
: (), Q
0 1, (. ),
.

161

say, and or.


, Q
and or; Q
:
use 5.010;
my $names = 'Fred or Barney';
if( $names =~ m/(\w+) (and|or) (\w+)/ ) { #
say "I saw $1 and $2";
}

! , ,
Q
. $2 ,
$3 ( ):
I saw Fred and or

Q
, : ,

. , Q
.
$1, Perl 5.10

. %+:
( ),
. (?<>),
.1 Q
name1, name2,
$+{name1} $+{name2}:
use 5.010;
my $names = 'Fred or Barney';
if( $names =~ m/(?<name1>\w+) (?:and|or) (?<name2>\w+)/ ) {
say "I saw $+{name1} and $+{name2}";
}

:
I saw Fred and Barney

, Q

:

Perl Python (?P<


>...).

162

8.
use 5.010;
my $names = 'Fred or Barney';
if( $names =~ m/((?<name2>\w+) (and|or) (?<name1>\w+))/ ) {
say "I saw $+{name1} and $+{name2}";
}

, ; Q
. Q
\1 \g{1}.
\g{}:
use 5.010;
my $names = 'Fred Flinstone and Wilma Flinstone';
if( $names =~ m/(?<last_name>\w+) and \w+ \g{last_name}/ ) {
say "I saw $+{last_name}";
}

.
\g{} \k<>:1
use 5.010;
my $names = 'Fred Flinstone and Wilma Flinstone';
if( $names =~ m/(?<last_name>\w+) and \w+ \k<last_name>/ ) {
say "I saw $+{last_name}";
}


, Q
2 ,
. Q
, .
, Q Q
, $gazoo $ozmodiar. ,
Q ?
Perl
Perl Q

\k<> \g{}. , Q
,
\k<> \g{} ,
\\g{N} . PyQ
thon (?P=).
, .
, Q
. .

163

1, Q
Perl , . Q
: $&, $` $'. ,
, , .2 ,
, $&:
if ("Hello there, neighbor" =~ /\s(\w+),/) {
print "That actually matched '$&'.\n";
}

, " there," (,
). $1 , Q
$& .
, ,
$`, , , $'.
: $` ,
, $' ,
. ,
:
if ("Hello there, neighbor" =~ /\s(\w+),/) {
print "That was ($`)($&)($').\n";
}

, (Hello)( there,)( neighbor), Q


.
, ( Q
). Q
, . Q
, Q
.
. , Q
. : Q
Q
, Q
.3 ,
, Perl Q
1

Q
(, $ARGV),
. manQ
perlvar.
, English,
Q
. ;
Perl , Q
.
, .

164

8.

.1 Q
. , Q
$&,
$1 (, Q
).
( , )
. , Q
.


Q
.
*, + ?. , Q
({}), Q
.
, /a{5,15}/ 5 15 a.
a , , Q
. a , . 10 Q
Q . a 20 ,
15 , .
( ), Q
. ,
/(fred){3,}/ fred (
). Q
; 88 fred,
.
, ,
Q
: /\w{8}/ (,
) /,{5}chameleon/
chameleon.
, , Q
, .
, {0,} (. . ); {1,} ( );
1

,
, ,
; , .
, Q
, Q
, Q
.
? , Perl Q
, Perl 6 , , .

165

, {0,1}. Q
, Q
.

;
Q
? , ,
.
,
; Q
. . 8.1.
8.1.

( Q
)

(...), (?:...), (?<>...)

a* a+ a? a{n,m}

abc ^a a$

a|b|c

a [abc] \d \1

1. Q
(()), . Q
, Q
.
2. ,
: (*), (+) (?),
{5,15}, {3,} {5}.
.
3. Q
. : (^),
($), \b Q Q
\B. ( Q
) , Q
. , Q
,
.
4. (|),
.
. ,
/fred|barney/

166

8.

, . Q
, Q
fre, d b,
arney. Q
, .
5. , Q
: ,
.


,
, Perl, Q
, .
, /^fred|barney$/ Q
. , Q
; Q
. fred , bar
ney . ,
/^(fred|barney)$/, ,
fred barney.1
/(wilma|pebbles?)/ ?
2, wilma, pebbles pebble Q
, ( ).
/^(\w+)\s+(\w+)$/ , ,
, Q
. , Q
fred flintstone. ,
, ; ,
Q
.
, Q
, . ,
; Q
, Q
.


Q
, , Q
1

, ,
$.
s s Q
pebbles.

167

.
; ,
Perl, manQ perlre, perlrequick perl
retut.1


Perl Q
, ,
. , Q
, .
, , ,
.
Q
, :
#!/usr/bin/perl
while (<>) {
#
chomp;
if (/ /) {
print "Matched: |$`<$&>$'|\n"; #
} else {
print "No match: |$_|\n";
}
}

,
; , Q
. Q

, .
, , Q
($`, $& $') , Q
. , /match/ beforematchafter
: |before<match>after|.
, .
, .

Q
. , ,

YAPE::Regexp::Explain
.

168

8.

, .1 Q
, Q
OReilly, . Q
pattern_test.2
.
1. [8] match. Q
beforematchafter.
?
2. [7] ,
( \w), a. Q
wilma, barney? Mrs. Wilma Flint
stone? wilna&fred?
(
, ).
3. [5] ,
, a, $1. Q
, $1
contains 'Wilma'.
4. [5] ,
$1 .
, Q
, 'word' contains 'Wilma'.
5. [5] :
, , Q
a, (
, ) .
, . , Q
I saw Wilma yesterday,
yest. I, Wilma!
. Q
wilma?
6. [5] ( !),
, ( Q
). , Q
.

, , Q
(`) , (').
( , ) Q
1.
, Q
, .


. ,
, Q
.

s///
m// Q
, Perl s/// Q
. Q
1, , :
$_ = "He's out bowling with Barney tonight.";
s/Barney/Fred/; # Barney Fred
print "$_\n";

, Q
:
# ; $_ "He's out bowling with Fred tonight."
s/Wilma/Betty/; # Wilma Betty ( )

m//,
, s/// ,
(lvalue).
, ,
.

170

9.

, , .
Q
$1, :
s/with (\w+)/against $1's team/;
print "$_\n"; # "He's out bowling against Fred's team tonight."

(,

):
$_ = "green scaly dinosaur";
s/(\w+) (\w+)/$2, $1/; # "scaly, green dinosaur"
s/^/huge, /;
# "huge, scaly, green dinosaur"
s/,.*een//;
# : "huge dinosaur"
s/green/red/;
# : "huge dinosaur"
s/\w+$/($`!)$&/;
# "huge (huge !)dinosaur"
s/\s+(!\W+)/$1 /;
# "huge (huge!) dinosaur"
s/huge/gigantic/;
# "gigantic (huge!) dinosaur"

s/// ;
, true, Q
false:
$_ = "fred flintstone";
if (s/fred/wilma/) {
print "Successfully replaced fred with wilma!\n";
}

(/g)
, , , s///
, Q
. , . /g
, s/// Q
1 :
$_ = "home, sweet home!";
s/home/cave/g;
print "$_\n"; # "cave, sweet cave!"

,
:
$_ = "Input data\t may have
extra whitespace.";
s/\s+/ /g; # "Input data may have extra whitespace."


:
1

, Q
, Q
.

s///

171

s/^\s+//; #
s/\s+$//; #


/g, (
, ). , Q
; , Q Q
( ),
(Jeffrey Friedl) Mastering Regular ExpresQ
sions1 (OReilly).
s/^\s+|\s+$//g; #


m// qw// s/// Q
.
, , .
() ,
, ,
/.
(#):
s#^https://#http://#;

:
, . Q
.
, !
:
s{fred}{barney};
s[fred](barney);
s<fred>#barney#;


/g2, Q
/i, /x /s,
( ):
s#wilma#Wilma#gi; # WiLmA WILMA Wilma
s{__END__.*}{}s; #

, 3Q . . .
.: Q, 2008.
/i, Q
.

172

9.


m// s/// Q
:
$file_name =~ s#^.*/##s; # $file_name " UNIX"


Q
( Q
). Perl Q
. \U
:
$_ = "I saw Barney with Fred.";
s/(fred|barney)/\U$1/gi; # $_ "I saw BARNEY with FRED."

\L
. :
s/(fred|barney)/\L$1/gi; # $_ "I saw barney with fred."

(Q
) ;
\E:
s/(\w+) with (\w+)/\U$2\E with $1/i; # $_ "I saw FRED with barney."

(\l \u) Q
:
s/(fred|barney)/\u$1/ig; # $_ "I saw FRED with Barney."

. ,
\u \L : ,
:1
s/(fred|barney)/\u\L$1/ig; # $_ "I saw Fred with Barney."

Q
, , Q
:
print "Hello, \L\u$name\E, would you like to play a game?\n";

\L \u . ,
; Perl
, Q
, Q
. .

split

173

split
split,
. Q
, , Q
, ,
.1 split ,
( , Q
). Q
:
@fields = split //, $;

split Q
(), .
. Q
, , , Q
. split :
@fields = split /:/, "abc:def:g:h"; # ("abc", "def", "g", "h")

,
:
@fields = split /:/, "abc:def::g:h"; # ("abc", "def", "", "g", "h")

,
: , Q
. :2
@fields = split /:/, ":::a:b:c:::"; # ("", "", "", "a", "b", "c")

Q
/\s+/. Q
:
my $some_input = "This is a \t
test.\n";
my @args = split /\s+/, $some_input; # ("This", "is", "a", "test.")

split $_ :
my @fields = split; # split /\s+/, $_;

, /\s+/,
, .
1

, ( CSV Comma
Separated Values). split ; Q
Text::CSV CPAN.
, , Q
. Q
, split 1; . manQ
perlfunc.

174

9.

, , Q
. (
, Q
: split ' ', $other_string.
split.)
Q
. ,
, Q
( Q
manQ perlfunc). Q
split, Q
(?:).

join
join , , Q
split. split ,
join . join Q
:
my $result = join $glue, @pieces;

join
. . Q
join
:
my $x = join ":", 4, 6, 8, 10, 12; # $x "4:6:8:10:12"

,
(). Q
,
. ,
1 .
,
:
my $y = join "foo", "bar";

#
#
my @empty;
#
my $empty = join "baz", @empty; #

"bar",
foo

,

$x , Q
:
my @values = split /:/, $x; # @values (4, 6, 8, 10, 12)
my $z = join "", @values; # $z "4681012"

split join , Q
, join , .

m//

175

m//
split ( ,
).
, .
(m//)
Q
, , ( Q
):
$_ = "Hello there, neighbor!";
my($first, $second, $third) = /(\S+) (\S+), (\S+)/;
print "$second is my $third\n";

,
.
( , =~,
$_.)
/g, s///, Q
m//;
. Q
:
my $text = "Fred dropped a 5 ton granite block on Mr. Slate";
my @words = ($text =~ /([az]+)/ig);
print "Result: @words\n";
# Result: Fred dropped a ton granite block on Mr Slate

split : Q
, , .
,
. ,
, :
my $data = "Barney Rubble Fred Flintstone Wilma Flintstone";
my %last_name = ($data =~ /(\w+)\s+(\w+)/g);

Q
. Q Q
.


(!) , Q
, ,
Perl. Perl Q
,
Perl; .
Q , .

176

9.


, ( 7 8), Q
(greedy). , Q

, Q
. : , /fred.+barney/
fred and barney went bowling last night. ,
, , .1 , Q
, fred Q
. .+, ,
, . +
: . Q

, night. ( ,
.)
barney, Q
. . .
.+ ,
, + t . (
, Q
, .)
barney, Q
. .+ h Q
. , .+ ,
Q barney. Q
barney .
Q
, ,
, Q
.2 , Q
, Q
, Q
.

, Q
, Q
Perl. ,
. Q
, , .
!
, Q
! Perl
; Q
, . .
, 3Q , Q, 2008.

177

() Q
. (+) Q
+?. +, Q
,
( ). Q
, /fred.+?barney/.
fred .
.+?
, Q
fred. barney
( and barney).
.+? a .
barney , .+? Q
n . . .+? , barney Q
, .
, Q
, Q
. , Q
, barney fred.
fred ,
barney , Q
. Q
.

. ( )
, ,
. , HTMLQ
1 , <BOLD>
</BOLD>, . :
Im talking about the cartoon with Fred and <BOLD>Wilma</BOLD>!

. ?
s#(.*)#$1#g;

*.2 Q
:
1

HTML,
.
HTML , Q
, .
: Q
/s,
. , :

.

178

9.
I thought you said Fred and <BOLD>Velma</BOLD>, not <BOLD>Wilma</BOLD>

<BOLD>
</BOLD>, . Q
! Q
. *
*?,
s#<BOLD>(.*?)</BOLD>#$1#g;

.
, + +?, * *?. ,
, .

,
, {5,10}? {8,}?.1 ? Q
: ??. Q
, .


Q
. Perl Q
, Perl
, . Q
, :
$_ = "I'm much better\nthan Barney is\nat bowling,\nWilma.\n";

^ $ (.
8). /m Q
. , Q
, . Q
:
print "Found 'wilma' at start of line\n" if /^wilma\b/im;

. Q
2, Q
:
open FILE, $filename
or die "Can't open '$filename': $!";
my $lines = join '', <FILE>;
$lines =~ s/^/$filename: /gm;
1

,
, {3}?.

,
.
,
.

179



, , Q
. ,
, ,
.
, Q
. , fred03.dat,
:
Program name: granite
Author: Gilbert Bates
Company: RockSoft
Department: R&D
Phone: +1 503 5550095
Date: Tues March 9, 2004
Version: 2.1
Size: 21k
Status: Final beta

. Q
:
Program name: granite
Author: Randal L. Schwartz
Company: RockSoft
Department: R&D
Date: June 12, 2008 6:38 pm
Version: 2.1
Size: 21k
Status: Final beta

, . (Author)
; (Date) ; Q
(Phone) . Q
.
Perl Q
<>.
, , Q
, .
$^I. Q
, .
#!/usr/bin/perl w
use strict;
chomp(my $date = `date`);
$^I = ".bak";
while (<>) {

180

9.
s/^Author:.*/Author: Randal L. Schwartz/;
s/^Phone:.*\n//;
s/^Date:.*/Date: $date/;
print;
}

, Q
date. , ( Q
) Perl
localtime :
my $date = localtime;

$^I;
.
<> . Q
, . (
, , Q

, .) Q
: s/// Q
, .
, Q
.
,
.
, , ,
, .
$^I. undef,
. Q , Q
<> .
<>: Q
Q
, . $^I Q
,
. , .
, <> fred03.dat.
, , fred03.dat.bak.1
,
. <>
fred03.dat. ;
. <>

, UNIX, Q
, . Q
Perl.

181

, .1
while ,
.
. , ?
, ? Q
: , ! Perl fred03.dat,
Q
fred03.dat.bak! Q : Perl Q
. , !
, .
.
$^I ~ (),
emacs .
$^I . Q
, Q
. Q
, Q
,
.
. Q Q
, Perl Q
(. 14).


, , .
, .
, ,
Randal l (Randall). , Q
.
:
$ perl p i.bak w e 's/Randall/Randal/g' fred*.dat

Perl , Q
.2
, .
, perl, , #!/usr/bin/
perl : , perl Q
.

<> Q
. ,
, Q
.
manQ perlrun.

182

9.

p Perl .
, ; Q
:1
while (<>) {
print;
}

, n;
print , , Q
. ( p n awk.) , ,
, .
, i.bak $^I
".bak" . ,
i . ( ,
, .)
w .
e : . Q
, s/Randall/Randal/g Perl.
while ( p), Q
print. Q
e .
e ( ,
),
.
fred*.dat ,
@ARGV ,
. : , Q

fred*.dat:
#!/usr/bin/perl w
$^I = ".bak";
while (<>) {
s/Randall/Randal/g;
print;
}

.
. , Q
?

, print continue. Q
manQ perlsyn perlrun.

183

.
1. [7] , Q
$what. , $what
fred, fredfredfred. $what
fred|barney, fredfredbarney,
barneyfredfred, barneybarneybarney .
(: $what
$what = 'fred|barney';.)
2. [12] , Q
. Fred ( Q
) Larry ( Q
, Manfred Mann ManLarry Mann).
( Q
!),
.out.
3. [8] , Q
Fred Wilma, Wilma
Fred. fred&wilma Q
Wilma&Fred.
4. [10] : ,
Q
:
## Copyright (C) 20XX by Yours Truly

.
.
,
.
5. [15] : Q
, , Q
. (:
, <> ,
$ARGV.)

10


Perl. ,
.
, Q
Q
,
( , , Q
).

unless
if
, .
, if unless:
unless ($fred =~ /^[AZ_]\w*$/i) {
print "The value of \$fred doesn't look like a Perl identifier name.\n";
}

, unless if Q
. , unless Q
else. Q
unless, , (Q
) if:
if ($fred =~ /^[AZ_]\w*$/i) {
#
} else {
print "The value of \$fred doesn't look like a Perl identifier name.\n";
}

until

185

,
Q.
, (!):
if ( ! ($fred =~ /^[AZ_]\w*$/i) ) {
print "The value of \$fred doesn't look like a Perl identifier name.\n";
}

, Q
, , , Q
. Q
, . Q
unless .

else unless
unless
else. , Q
:
unless ($mon =~ /^Feb/) {
print "This month has at least thirty days.\n";
} else {
print "Do you see what's going on here?\n";
}

,
(, Q
), . Q
if ,
if:
if ($mon =~ /^Feb/) {
print "Do you see what's going on here?\n";
} else {
print "This month has at least thirty days.\n";
}

, : Q
, , , Q
. , ,
.

until
while .
until:
until ($j > $i) {
$j *= 2;
}

186

10.

,
true. Q
while; until , Q
( , while).
, until, while,
.1 if unless,
until while
. Q
until , .


, Q
. , if Q
if:
print "$n is a negative number.\n" if $n < 0;

, Q
( ,
):2
if ($n < 0) {
print "$n is a negative number.\n";
}

, Perl
. Q
: , $n .
, Q Q
, . Q
.
Perl, , Q
Perl, ; Q
, .
:
&error("Invalid input") unless &valid($input);
$i *= 2 until $i > $j;
print " ", ($n += 2) while $n < 10;
&greet($_) foreach @person;
1

Pascal, : Pascal repeatQuntil Q


, Perl until Q
, .
. , Q
. Q
, ,
.

187

, , . Q
if Q
. :
while ($n < 10) {
print " ", ($n += 2);
}

Q
print: $n 2 $n.
print.
, Q
: &greet @person
. $i, $j.1
Q
:
print "fred is '$fred', barney is '$barney'\n"

if $I_am_curious;

Q
. Q
, .2 Q

, if Q
, ; Q
if :
print "fred is '$fred', barney is '$barney'\n"
if $I_am_curious;

Q
( ), .
.
, Q if Q
while Q until Q unless Q foreach Q; Q
. , Q
.
, ,
.
if,
(),
. foreach Q
$_.
1
2

.
, $I_am_curious;
Perl. , ,
$TRACING , Q
constant.

188

10.

, ,
foreach.


(naked block)
. ,
while, :
while () {
;
;
;
}

while , Q
:
{
;
;
;
}

while foreach, Q
; , Q
.

, (scope) Q
( Q
):
{
print "Please enter a number: ";
chomp(my $n = <STDIN>);
my $root = sqrt $n; #
print "The square root of $n is $root.\n";
}

$n $root Q
, . Q
Q
.
, Q
. , $n $root
, Q
.
, sqrt ,
, , , . Perl Q
, .

elsif

189

manQ
perlfunc.

elsif
Q
, .
elsif if, :
if ( ! defined $dino) {
print "The value is undef.\n";
} elsif ($dino =~ /^?\d+\.?$/) {
print "The value is an integer.\n";
} elsif ($dino =~ /^?\d*\.\d+$/) {
print "The value is a _simple_ floatingpoint number.\n";
} elsif ($dino eq '') {
print "The value is the empty string.\n";
} else {
print "The value is the string '$dino'.\n";
}

Perl .
, Q
, Q
1 .
, else. (, Q
else , .)
elsif , , Perl
99 , 100Q.
Q elsif, ,
. Perl FAQ (. manQ
perlfaq)
switch/case . Perl 5.10
given
when, 15.
, , elsif
e. elseif, Perl Q
. ? .2

switch C, Q
.
, Q
. elsif e, .
1 . 2 .

, . , elseunless
.

190

10.



1. ,
( Q
). (++) Q
1 C
:
my $bedrock = 42;
$bedrock++; # $bedrock 1; 43

, Q
:
my @people = qw{ fred barney fred wilma dino barney fred pebbles };
my %count;
#
$count{$_}++ foreach @people; #
#

foreach $count{$_} .
, $count{"fred"} undef
( ) 1. Q
$count{"barney"} 1; $count
{"fred"} 2.
%count , . Q
$count{"fred"} 3. Q
, Q
.
() Q
1:
$bedrock; # $bedrock 1; 42


.
++ ,
, .
:
my $m = 5;
my $n = ++$m; # $m 6, $n

,
, (
):
my $c = $m; # $m 5, $c

: Q
(), Q

191

. 
:
my $d = $m++; #
#
my $e = $m; #
#

$d (5), $m
6
$e (6), $m
5

, . Q
.
, Q
( ), .
,
() , .
, , Q
.
1, Q
( ),
:2
$bedrock++; # $bedrock 1
++$bedrock; # ; $bedrock 1

Q
:
my @people = qw{ fred barney bammbamm wilma dino barney betty pebbles };
my %seen;
foreach (@people) {
print "I've seen you somewhere before, $_!\n"
if $seen{$_}++;
}

barney , $seen{$_}++ ,
$seen{$_}, $seen{"barney"}, Q
undef. Q
$seen{"barney"}. barney Q
, $seen{"barney"} , Q
.

1
2

.
, ,
,
, Perl . Perl Q
.

192

10.

for
Perl for Q
, C. :
for (; ; ) {
;
;
}

Perl
while :1
;
while () {
;
;
;
}

, for
c :
for ($i = 1; $i <= 10; $i++) { # 1 10
print "I can count to $i!\n";
}

,
.
$i 1. while
, $i 10.
Q
, ; Q
($i) 1.
, $i 1.
10, . Q
,
, . , Q
$i 2; 10, Q
, $i 3.
10, . .
, 9.
$i 10. Q
10, ,
, 10. , Q
$i 11; 10.

continue, Q
. manQ perlsyn.

193

for

,
.
, :
, $i 1 10.
: Q
.
11. for ; Q
. , Q
10 1:
for ($i = 10; $i >= 1; $i) {
print "I can count down to $i\n";
}

150 1000 3:1


for ($i = 150; $i <= 1000; $i += 3) {
print "$i\n";
}

, (, Q
) ; Q
. ( Q
) ,
:
for ($_ = "bedrock"; s/(.)//; ) {

# , s///
#

print "One character is: $1\n";


}

( while)
, true .
b bedrock.
. Q
, Q
.
( ) ,
,
. , Q
. , ,
.
for (;;) {
print "It's an infinite loop!\n";
}

, 1000 . Q
999, $i 3.

194

10.

1,
while; Q
Perl:
while (1) {
print "It's another infinite loop!\n";
}

C ,
Perl , 1 Q
. , Q
, . Perl Q
,
, .

foreach for
, Perl foreach Q
for. , , Perl
, .
, , Perl .
, , for (Q
, ).
, , Perl foreach:
for (1..10) { # foreach 1 10
print "I can count to $_!\n";
}

foreach,
for. Q
foreach , .
, Perl
?2 , , Q
for. , ,
Perl ;.
Perl foreach
. foreach (
for) , 1
10. , , Q
1

,
ControlQC. , Q
Q ControlQC; Q
/ . !
, . Q
( Perl) Q
. , Q Q
Perl Mongers.

195

? ,
, :1
for ($i = 1; $i < 10; $i++) { # !  !
print "I can count to $_!\n";
}


, , Perl Q
. ,
. Q

, . Q
, , , while,
. , Q
. Perl
,
.

last
last . (
break C , .)
, last .
. :
# fred __END__
while (<STDIN>) {
if (/__END__/) {
#
last;
} elsif (/fred/) {
print;
}
}
## last #

__END__, Q
. ,
1

. Q, Q
, 9 10.
1: Q
, 30Q Q
3 . ? (10
). Q, $i, Q
$_. , ,
, .
, Perl foreach.

196

10.

; .
, .
Perl : for,
foreach, while, until .1 if
2 .
last ,
. ,
? ; .

next
, Q
. next, Q
.3 Q
next (
continue C ):
#
while (<>) {
foreach (split) { # $_ ,
# $_
$total++;
next if /\W/;
#
$valid++;
$count{$_}++;
#
## next ##
}
}
print "total things = $total, valid words = $valid\n";
foreach $word (sort keys %count) {
print "$word was seen $count{$word} times.\n";
}

,
; . while

1
2

, last .
, ,
,
. ,
last, ,
,
. Q
Perl, .
. next
( ) continue.
manQ perlsyn.

197

<> $_; Q
. $_ .
foreach Q
split. split
?1 $_ , $_
. foreach Q
, $_. , $_ Q
.
, $_
? , . Q
foreach $_ . Q
$_ ;
.
, foreach $_ Q
. $total Q
; .
( ) , Q
, , Q
. , Tom's fullsized,
,
, Q
, .
, , , fred.
$valid 1; $count{$_},
. ,
Q
, .
. ,
, .
last, next
: for, foreach, while, until . Q
next .
, , .

redo
redo.

. ( Q
C , . Q
.) :

, .
, perldoc.

198

10.
#
my @words = qw{ fred barney pebbles dino wilma betty };
my $errors = 0;
foreach (@words) {
## redo ##
print "Type the word '$_': ";
chomp(my $try = <STDIN>);
if ($try ne $_) {
print "Sorry  That's not right.\n\n";
$errors++;
redo; #
}
}
print "You've completed the test, with $errors errors.\n";

, redo Q
, Q
.
next redo ,
next , redo Q
.
, :1
foreach (1..10) {
print "Iteration number $_.\n\n";
print "Please choose: last, next, redo, or none of the above? ";
chomp(my $choice = <STDIN>);
print "\n";
last if $choice =~ /last/i;
next if $choice =~ /next/i;
redo if $choice =~ /redo/i;
print "That wasn't any of the choices... onward!\n\n";
}
print "That's all, folks!\n";

Return Q (Q
Q ),
. last 4, Q
, 5 . next 4,
5
onward!. redo , 4 Q
.

OReilly (,
), lnrexample.

199


, Q Q
, . Perl
, Q
, . ,
,
.
, print if .
.
,
, .
Q
Perl.
,
.
last, next redo :
LINE: while (<>) {
foreach (split) {
last LINE if /__END__/; # LINE
...
}
}

Q
, .
: ,
.1 __END__ Q
. ,
( ).
.2 , Q
,
LINE. ,
WORD, . Q
next WORD
redo LINE.

1
2

goto.
, , Perl Q
, XYZZY
PLUGH. (XYZZY PLUGH CoQ
lossal Cave. . .) , Colossal
Cave 70Q , , .

200

10.

?:
, Perl,
C, Perl
C.1 , Perl
C ?:.
.
ifQthenQelse,
. ,
. :
? __true : __false

Perl ,
. Q
, .
, . ,
, Q
, . ,
, .
&is_weekend , Q
:
my $location = &is_weekend($day) ? "home" : "work";

QQ
, :
my $average = $n ? ($total/$n) : "";
print "Average: $average\n";

?: Q
if, :
my $average;
if ($n) {
$average = $total / $n;
} else {
$average = "";
}
print "Average: $average\n";

, Q
:
my $size =
1

, Perl, , Q
.
(, ), Q
C .

201

($width < 10) ? "small" :


($width < 20) ? "medium" :
($width < 50) ? "large" :
"extralarge"; #

Q
?:. ,
.
, . ,
.
, ,
,
.


, Perl
() true/
false. , Q
AND (&&) OR (||):
if ($dessert{'cake'} && $dessert{'ice cream'}) {
#
print "Hooray! Cake and ice cream!\n";
} elsif ($dessert{'cake'} || $dessert{'ice cream'}) {
# ,
print "That's still good...\n";
} else {
# 
}

Q
. AND , Q
, AND Q
Q
. ,
. ,
$hour 3:
if ( (9 <= $hour) && ($hour < 17) ) {
print "Aren't you supposed to be at work...?\n";
}

OR
. , Q
$name fred:
if ( ($name eq 'fred') || ($name eq 'barney') ) {
print "You're my kind of guy!\n";
}

202

10.

Q
(shortQcircuit). , , Q
. Q
. Q
:
if ( ($n != 0) && ($total/$n < 5) ) {
print "The average is below five.\n";
}

,
.
.


C ( ),
,
, . Q
: Q
, , , Q
.
. ,
OR Q
:
my $last_name = $last_name{$someone} || '(No last name)';

$someone , undef,
false. , OR
,
.
undef; Q
.
:
my $last_name = defined $last_name{$someone} ?
$last_name{$someone} : '(No last name)';

, $last_name{$someone}
. Perl 5.10 Q
; Q
.

//
,
||. Q
, ( ,

203

) . Q
.
Perl 5.10 //,
Q
Q
. $last_name{$someone} 0,
:
use 5.010;
my $last_name = $last_name{$someone} // '(No last name)';

, Q
, Q
. , Q
VERBOSE. ,
VERBOSE %ENV. ,
:
use 5.010;
my $Verbose = $ENV{VERBOSE} // 1;
print "I can talk to you!\n" if $Verbose;

, //: Q
,
default:
use 5.010;
foreach my $try ( 0, undef, '0', 1, 25 ) {
print "Trying [$try] > ";
my $value = $try // 'default';
say "\tgot [$value]";
}

, default
: $try undef:
Trying
Trying
Trying
Trying
Trying

[0] >
[] >
[0] >
[1] >
[25] >

got
got
got
got
got

[0]
[default]
[0]
[1]
[25]

,
. , Q
,
:
use warnings;
my $name; # , undef!
printf "%s", $name; # Use of uninitialized value in printf ...

204

10.

, .
, Q
, :
use 5.010;
use warnings;
my $name; # , undef!
printf "%s", $name // '';



, , &&, ||, //
?:, :
. , .
.
Q
.1 , Q
Perl . Q
, Q
. ,
,
, .
,
, Q
Q . ,
:
($m < $n) && ($m = $n);

, AND
.2 ?
$m $n, , Q
.
$m $n, Q
, . ,
, :
if ($m < $n) { $m = $n }

,
:
($m > 10) || print "why is it not greater?\n";

1
2

, ?
, (
).

205

$m 10, Q
OR .
. Q
( )
, if unless.
,
C Perl
. ? , Q
. , .
, Q .

. $x
:
($m < $n) ? ($m = $x) : ($n = $x);

$m , $x , $x Q
$n.
:
and or.1 Q
, , Q
. Q
,
:
$m < $n and $m = $n; # if

: .
. ,
,
. Q
, ,
. , ,
( ) , .

, Q
. Perl Q
:
open CHAPTER, $filename
or die "Can't open '$filename': $!";

or Q
, Perl: !
open , Q
1

not ( Q
!) xor.

206

10.

or . Q
or , Q
.
, Q
Perl. Q
, Q
. .1

.
1. [25] , Q
1 100,
. Q
int(1+rand 100).2 Q
, Too high
Too low. quit exit,
, . ,
, Q
!
2. [10] ,
(,
). , Q
,
. Perl 5.10, Q
//. .
3. [10] 3 6 ( Q
) , , Q
, (undefined value).
. , Q
Q
. Perl 5.10, Q
//. .

( or die) Q
.
int rand,
manQ perlfunc.

11
Perl

Perl ,
. Q
. Q , ,
Q CPAN
(Comprehensive Perl Archive Network)
, Perl,
.
; , ,
. ,
.


: Perl ( Q
, ) , Q
CPAN . Q
, Perl.
, Perl, CPAN SeQ
arch (http://search.cpan.org) Kobes Search (http://kobesearch.cpan.
org/).1
.
, Q
.

.
1

, URLQ s,
.

208

11. Perl

, ,
. , Q
perldoc. CGI.pm Q
Perl ( ), Q
:
$ perldoc CGI

Q
:
$ perldoc Llamas
$ No documentation found for "Llamas".


(, HTML). , ,
.1


, ,
, Q
. README
INSTALL .
MakeMaker2, :
$ perl Makefile.PL
$ make install

Q
, PREFIX Make
file.PL:
$ perl Makefile.PL PREFIX=/Users/fred/lib

Perl Q
Module::Build. Q
:
$ perl Build.PL
$ ./Build install


. Q
1

Perl Intermediate Perl (OReilly)


(Perl: , Q, 2007), ,
Q
.
Perl ExtUtils::MakeMaker, Perl.
Q
, Perl.

209

, , Q
Perl, CPAN.pm.1
CPAN.pm :
$ perl MCPAN e shell

,
cpan,
Perl
perl .
:
$ cpan Module::CoreList LWP CGI::Prototype

, Q : !
ActiveState ( Windows, Linux Solaris), Q
PPM2 (Perl Package Manager),
. ActiveState CD DVD.3 Q
, , Q
, Q
Perl.


,
/usr/local/bin/perl, . Q
, , Q
/ ( perl):
my $name = "/usr/local/bin/perl";
(my $basename = $name) =~ s#.*/##; # !

, Perl Q
, . ,
, (. . ), Q
, .
. Q
.
1

2
3

.pm Perl Module. Q


.pm, Q .
CPAN CPAN, Q
CPAN.pm.
http://aspn.activestate.com/ASPN/docs/ActivePerl/faq/ActivePerlfaq2.html
CD DVD,
. CPAN 4 , miniQ
cpan (Q ) Q
800 . .
CPAN::Mini.

210

11. Perl

Q, UNIX
( ,
). (.)
, "/home/fred/flint
stone\n/brontosaurus" Q
, "flintstone\n/brontosaurus".
/s (
); Q
: s#.*/##s. ,
UNIX. ,
,
UNIX, , .
( ) , Q
. Perl Q
, Perl
. , CPAN Q
,
. ( )
, Q
.
Q
, Q
Perl. ( ;
.)
, ,
;
,
.1 , , Q
. , Q
, Q
. Q
B.

File::Basename
, Q
. , Q
Q
(
).
, ,
( ) .

, ,
.

211

, , Q
. Perl File::Base
name. , , perldoc
File::Basename .
(
).
, Q
use :1
use File::Basename

Perl Q
. Perl ,
, .2
basename:
my $name = "/usr/local/bin/perl";
my $basename = basename $name;

# 'perl'

UNIX .
MacPerl, Windows, VMS ? Q
, ,
. (,
$name ,
.)
.
dirname
. Q
.3


,
File::Basename , Q
&dirname (
). Q
1

, Q
, , , Q
. , Q
.
, : ,
. Q
( ),
Perl, , ,
. manQ perlmod.
? , Q
UNIX Windows ,
FTP.

212

11. Perl

, dirname Q
Perl ( ). ?
use File::Basename ,
. Q
. ,

basename:
use File::Basename qw/ basename /;

:
use File::Basename qw/ /;

:
use File::Basename ();

? Perl
File::Basename, , .
, Q
basename dirname. ,
, Q
:
use File::Basename qw/ /;

my $betty = &dirname($wilma);

#
# &dirname ( )

my $name = "/usr/local/bin/perl";
my $dirname = File::Basename::dirname $name; # dirname

dirname File::Basename Q
File::Basename::dirname.
( , ) Q
, dirname .
,
, Q
.
Q
, . Q
( ) , Q
.
, Q
.
, Q
( ), Q
,
, File::Basename.
.

213

File::Spec
. , Q
: Q
. ,

/home/rootbeer/ice2.1.txt:
use File::Basename;
print "Please enter a filename: ";
chomp(my $old_name = <STDIN>);
my $dirname = dirname $old_name;
my $basename = basename $old_name;
$basename =~ s/^/not/;
#
my $new_name = "$dirname/$basename";
rename($old_name, $new_name)
or warn "Can't rename '$old_name' to '$new_name': $!";

, ? ,
UNIX,
. , Perl Q
.
File::Spec Q
, , Q
. File::Basename, Q
, ,
. , File::Basename, Q
File::Spec Q ( Q
) .
Q
, . Q
; Q. Q
.
, , .
File::Spec , Q
catfile. ?
( , Q
). ,
File::Spec :
use File::Spec;
.
. # $dirname $basename,
.
my $new_name = File::Spec>catfile($dirname, $basename);

214

11. Perl
rename($old_name, $new_name)
or warn "Can't rename '$old_name' to '$new_name': $!";

(
), (>) Q
. ,
.
,
? . Q Q
, Q
Q
File::Spec.
? , .
,
UNIX, , Q
UNIX1, ,
. Q
,
Q
.

CGI.pm
CGIQ (
), CGI.pm.2
, ( ),
, Q
. CGI.pm Q
(Lincoln Stein) , Q
Q
. Q
.
CGI :
Q .
. ,
CGI.pm. CGI
CGI Q
. :all

, UNIX
, 
, ?
CPAN.pm, .pm CGI.pm,
.

215

, Q
( ).1
#!/usr/bin/perl
use CGI qw(:all);
print header("text/plain");
foreach my $param ( param() )
{
print "$param: " . param($param) . "\n";
}

HTML, CGI.pm
.
CGI, HTML
start_html(), HTML Q
, h1() H1:
#!/usr/bin/perl
use CGI qw(:all);
print header(),
start_html("This is the page title"),
h1( "Input parameters" );
my $list_items;
foreach my $param ( param() )
{
$list_items .= li( "$param: " . param($param) );
}
print ul( $list_items );
print end_html();

, ? , CGI.pm Q
; , . Q
CGI.pm,
.
CGI.pm : Q
cookies, ,
. . ,
Q
.


. , ,
CGI, :cgi; ,
HTML, :html4. Q
CGI.pm.

216

11. Perl

DBI
DBI (Database Interface) Perl, Q
, Q
. DBI
, Q
: , Q
, Oracle. Q
ODBC,
Q. Q
, Programming the Perl DBI1 Q
(Alligator Descartes) (Tim Bunce) (OReilly).
DBI http://dbi.perl.org/.
DBI DBD ( Q
, Database Driver). DBD
CPAN Search.
, Q
.
DBI Q ,
Q Q
. , .
, use
connect:
use DBI;
$dbh = DBI>connect($data_source, $username, $password);

$data_source , Q
; DBD. ,
PostgreSQL DBD::Pg, $data_source
:
my $data_source = "dbi:Pg:dbname=name_of_database";

, Q
.
$sth = $dbh>prepare("SELECT * FROM foo WHERE bla");
$sth>execute();
@row_ary = $sth>fetchrow_array;
$sth>finish;

:
$dbh>disconnect();

DBI .
.
1

Perl DBI. .
. .: Q, 2000 ( ).

217

.
1. [15] Module::CoreList CPAN.
, Perl 5.008. ,
Perl, Q
:
my %modules = %{ $Module::CoreList::version{5.008} };

12

, .
, Q
. , , Q
. , ,
. ,
, Q
.
Perl
.


, ,
.

.
e:
die "Oops! A file called '$filename' already exists.\n"
if e $filename;

: $! die, Q
. Q
. Q

. ,
(, Q
).
28 , , Q :

219

warn "Config file is looking pretty old!\n"


if M CONFIG > 28;

. , Q
Q
, .
1 , Q
100 . , Q
,
90 ( , Q
):2
my @original_files = qw/ fred barney betty wilma pebbles dino bammbamm /;
my @big_old_files; #
foreach my $filename (@original_files) {
push @big_old_files, $filename
if s $filename > 100_000 and A $filename > 90;
}

: foreach Q
my. , Q
, Q
use strict. my Q
$filename.
( ),
.
true/false,
. . 12.1
, .
r, w, x o , Q
3; ,
, 4. Q
, Q
.
1

, , Q
, Q
(. 13).
, .
, Q
.
o O ,
.
: Q
R, W, X O
, setQID.
, setQID, UNIXQQ
.

220

12.

ACL (Access Control List), Q


. , 
; , Q
, . , w Q
CDQROM,
, x Q
, .
12.1.

r

()

w

()

x

() Q

o

()

R

()

W

()

X

()

O

()

e

z

( false Q
)

s

(Q
)

f

d

l

S

p

(fifo)

b

(, )

c

(, /
)

u

setuid

g

setgid

k

(sticky bit)

221

t

TTY (
isatty(); )

T

B

M

( )

A

( )

C

( )

s true, , Q
true: Q
, true.
UNIX1 ()
, : f, d, l, S,
p, b c. Q
. , , Q
f, l. Q
, , Q
, l. ( Q
13.)
M, A C ( ) Q
, ,
.2 (Q
;
manQ
stat UNIX.) Q
,
, 2.00001.
(
; , 1:30 , Q
23:00, M 0.1,
.)

,
UNIX, .
, Q
.
, UNIX, Q
, .
, ctime ( C)
( UNIX )
; . manQ perlport.

222

12.


1.2, , Q
30 ! Q
1,
, Q
, Q
. , Q
( ) .
T B ,
. , ,
, , , ( Q
UNIXQ ) Perl
? , Perl : , Q
Q
. Q, Q

, , . Q
, . Q
, . Q
( Q
, ,
ISOQ885 ), Perl
, . , Q
,
HTML
PNG, .
, T B Q
, , Q
, Q
. ,
,
, . , Q
, ,
.
t true, TTY
, , Q
. t STDIN true,
, .
false, , , Q
, .

$^T, (Q
$^T = time;), Q
.

223

,
, , , Q
. , Q
UNIX.1 (
, UNIX, undef
. ,
.)
(
r s), Q
, $_.2 Q
, , Q
, :
foreach (@lots_of_filenames) {
print "$_ is readable\n" if r; # same as r $_
}

, ,
, , .
, ,
, s 1000 (
1024):
# $_
my $size_in_K = s / 1000;

# !

Perl , .
s, ,
, .
, : Q
:
my $size_in_k = (s) / 1024;

# $_

,
.



. , Q
, Q
, .
and:
1

UNIX. Q
. . . .: Q, 2007.
t,
( TTY).
STDIN.

224

12.
if( r $file and w $file ) {
... }

. Q
Perl Q
( Perl Q
stat, ).
r, Perl Q
w. ! Q
Q
.
Perl ,
. _
( ) ,
. Q
Perl :
if( r $file and w _ ) {
... }

_ Q
. if:
if( r $file ) {
print "The file is readable!\n";
}
if( w _ ) {
print "The file is writable!\n";
}

, _ Q
, . Q
Q ,
, . Q
, lookup, Q
.
_ $file,
, $other_file:
if( r $file ) {
print "The file is readable!\n";
}
lookup( $other_file );
if( w _ ) {
print "The file is writable!\n";
}
sub lookup {
return w $_[0];
}

225


Perl 5.10, Q
, (
, _ ).
, ,
.
, :
if( r $file and w _ ) {
print "The file is both readable and writable!\n";
}

, . Perl 5.10

:
use 5.010;
if( w r $file ) {
print "The file is both readable and writable!\n";
}

, Q
. , Q
, Perl ,
. .
Q
. , , Q
, ,
. Q
:
use 5.010;
if( r w x o d $file ) {
print "My directory is readable, writable, and executable!\n";
}

Q
, true false,
. , Q
, ,
512 , :
use 5.010;
if( s d $file < 512) { # WRONG! DON'T DO THIS
print "The directory is less than 512 bytes!\n";
}

226

12.

, ,
. Q
:
if( ( d $file and s _ ) < 512 ) {
print "The directory is less than 512 bytes!\n";
}

d false, Perl false


512. , false
0, 512. Q
,
, :
if( d $file and s _ < 512 ) {
print "The directory is less than 512 bytes!\n";
}

stat lstat
Q
, Q
, . ,
Q
(UID) .
, stat, Q
, UNIX stat (,
, 1).
stat ( Q
_) , . Q
, ,
stat ( Q , ),
13 , Q
:

, UNIX, stat lstat,


Q
. , ,
(
UNIX),
, Q
. stat lstat , Q
. , Q
, (
), undef.
, , manQ
perlport.

stat lstat

227

my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev,


$size, $atime, $mtime, $ctime, $blksize, $blocks)
= stat($filename);

stat,
manQ stat(2). Q
:
$dev $ino
, Q
. .
( ),
.
$mode
, Q
. Q UNIX
ls l () , Q
,
rwxrxrx. 1 Q
$mode, Q
0755. , 9 Q
, .
$mode ,
.
$nlink
() ; Q
. Q
2 , ( ) 1.
13,
. ls l $nlink
.
$uid $gid
,
.
$size
, s.
$atime, $mtime $ctime
, : 32QQ
, , Q

,
: , d , l Q
. . ls , 9
.

228

12.

, Q
. UNIX
1970Q ,
.
, Q
.
stat Q
, , (Q
). Q
( ) Q
, lstat stat;
. Q
, lstat , stat.
stat lstat Q
$_; , stat
, Q
$_.

localtime
(, stat) Q
, 1180630098.
, Q
. , Q
Thu May 31 09:48:18 2007.
Perl localtime :
my $timestamp = 1180630098;
my $date = localtime $timestamp;

localtime , Q
:
my($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst)
= localtime $timestamp;

$mon 0 11 Q
. $year ,
1900 ; ,
1900. $wday 0 () 6 (Q
), $yday , 0 (1 ) 364 365 (31 ).
,
. gmtime localtime, Q
(Q
).
, time. localtime, gmtime

229

Q
time:
my $now = gmtime; #

Q
B.


( Q
, stat) Q
.
. (&) , Q
. , Q
10 & 12 8. Q
,
1. ,
10 (1010 ) 12 (1100 Q
) 8 (1000 ,
1 ); . . 12.1.

1010
& 1100
1000
. 12.1.

. 12.2.
$mode,
stat.
chmod (. 13):
# $mode  , stat CONFIG
warn "Hey, the configuration file is worldwritable!\n"
if $mode & 0002;
#
my $classical_mode = 0777 & $mode;
#
#
my $u_plus_x = $classical_mode | 0100;
#
my $go_minus_r = $classical_mode & (~ 0044); #

230

12.

12.2.

10 & 12

,
( 8)

10 | 12

,
( 14)

10 ^ 12

,
( 6)

6 << 2

Q
, ,
( 24)

25 >> 2

Q
, , Q
( 6)

~ 10

, Q
, Q
( 0xFFFFFFF5, . )


,
. Q
, ( 32Q,
, . Q
, 64Q ~10 Q
64Q 0xFFFFFFFFFFFFFFF5 32QQ
0xFFFFFFF5).
,
Perl .
, "\xAA" | "\x55" "\xFF".
: ; Q
, 8 .
.
, Perl Q
. Q
manQQ
perlop.

.
1. [15] ,
,

231

, , . (: Q
,
.) , Q
chmod 0? ( Q
UNIX, chmod 0 some_file,
, .) Q
Q
. , ./ex122 * Q
.
2. [10] ,
, , Q
. , (
)?
3. [10] ,
, Q
,
.

13

, , Q
. Q
,
Beatles MP3 Q
MP3 Q
. Perl , Q
Q
.


, Q
. Q
, fred, fred Q
.
chdir. Q
, cd UNIX:
chdir "/etc" or die "cannot chdir to /etc: $!";

, Q
$!. $!
chdir false,
Q .
, Perl
( 16). Q
, ,

233

Perl, .1 , Q
Perl, cd Q
.
, Perl , Q
, Q
( cd,
). ,
$_.
cd
~,
(, cd ~merlyn).
, , Perl
, Q
~ chdir.


, .
(glob). , Q
echo *.pm, Q
:
$ echo *.pm
barney.pm dino.pm fred.pm wilma.pm
$

echo *.pm, Q
.
Perl:
$ cat >showargs
foreach $arg (@ARGV) {
print "one arg is $arg\n";
}
^D
$ perl showargs *.pm
one arg is barney.pm
one arg is dino.pm
one arg is fred.pm
one arg is wilma.pm
$

Perl, UNIX, Windows


.
, .

234

13.

: showQargs
@ARGS.
Perl *.pm.
?
glob:
my @all_files = glob "*";
my @pm_files = glob "*.pm";

@all_files , Q
( Q
). @pm_files , Q
*.pm .
, ,
() glob, Q
, :
my @all_files_including_dot = glob ".* *";

.*
, .
: , Q
, , .1 Q
Q
? , Perl 5.6 Q
glob /bin/csh2 .
, Q
( ) .
Perl ,
,
. , Perl,
.


, glob,
glob , .
? , Q
glob . Q
, Q
:
my @all_files = <*>; ## my @all_files = glob "*";
1

Windows , *.* Q
. ,
Perl Windows.
, csh .

235

Q
; , Perl
:
my $dir = "/etc";
my @dir_files = <$dir/* $dir/.*>;

( ) Q
, $dir
.
,
, , Perl ,
Q
? .
Perl. ,
Perl, Q
; . :
my
my
my
my

@files = <FRED/*>; ##
@lines = <FRED>;
##
$name = "FRED";
@files = <$name/*>; ##

:
(
) , Q
:1
my $name = "FRED";
my @lines = <$name>; ## FRED

Q
,
.
Q
readline2; Q
:
my $name = "FRED";
my @lines = readline FRED; ## FRED
my @lines = readline $name; ## FRED

,
, Q
use strict. Q
typeglob /;
use strict.
Perl 5.005 .

236

13.

readline , Q

.


Q
.
,
. (opendir open), Q
(readdir readline), (closedir
close).
( ). :
my $dir_to_process = "/etc";
opendir DH, $dir_to_process or die "Cannot open $dir_to_process: $!";
foreach $file (readdir DH) {
print "one file in $dir_to_process is $file\n";
}
closedir DH;

, ,
Q
.
, Perl Q
, Q
. ,
.
, , Q
.
, 1,
, , Q
(, *.pm, ). ,
. ...2 Q
, pm,
:
while ($name = readdir DIR) {
next unless $name =~ /\.pm$/;

,
, ls l find.
,
UNIX: , . ..
( ). Q
, , ,
. , .

237

... ...
}

: Q
, . ,
:
next if $name =~ /^\./;

, , , Q
. ( ) .. ( ), Q
:
next if $name eq "." or $name eq "..";

, ,
. ,
readdir, . Q
. , /etc/passwd, passwd. ( Q
, Q
.)
, Q
:
opendir SOMEDIR, $dirname or die "Cannot open $dirname: $!";
while (my $name = readdir SOMEDIR) {
next if $name =~ /^\./;
# ,
$name = "$dirname/$name";
#
next unless f $name and r $name; #
...
}

Q
, , $dirname.

.



PerlQ. ,

find, , Perl Q
File::Find, Q
. ,
( Q
Q ), Q
: ?
?

238

13.


Perl .
Perl UNIX
, ,
UNIX. , Perl
(, ) , Q
UNIX.


.
.
UNIX Q
rm:
$ rm slate bedrock lava

Perl unlink:
unlink "slate", "bedrock", "lava";

.
unlink , glob
,
:
unlink glob "*.o";

rm *.o Q
, , Q
rm. Q
!
unlink Q
. , ,
:
my $successful = unlink "slate", "bedrock", "lava";
print "I deleted $successful file(s) just now\n";

, 3, , Q
, 0 . Q
1 2? , Q
. ,
:
foreach my $file (qw(slate bedrock lava)) {
unlink $file or warn "failed on $file: $!\n";
}

239

, Q
0 (), 1 ( );
Q
warn. or warn or die ,
(. 5). Q
warn ,
Q .
unlink , Q
$! ,
, .
, Q
.
unlink ( ,
rm). ,
, rmdir.
UNIX. , Q
, (
, ),
. , Q
;
, .
, Perl
unlink: , Q
chmod 0 ( , ) Q
, unlink . Q
.1 unlink,
/etc/passwd .
,
.2


rename :
rename "old", "new";

UNIX mv, old


new .
:
rename "over_there/some/place/some_file", "some_file";
1

, rm
. rm , unlink . Q
, .
, Q
, .

240

13.

some_file
, , , Q
.1 Q
, , rename Q
false $! Q
, ( )
or die or warn.
, Q
UNIX, 2 : Q
.old , Q
, .new? Perl:
foreach my $file (glob "*.old") {
my $newfile = $file;
$newfile =~ s/\.old$/.new/;
if (e $newfile) {
warn "can't rename $file to $newfile: $newfile exists\n";
} elsif (rename $file, $newfile) {
## ,
} else {
warn "rename $file to $newfile failed: $!\n";
}
}

$newfile Q , rename
Q
( Q
). , Q
. , Q
wilma.new, e .
:
(my $newfile = $file) =~ s/\.old$/.new/;

$newfile, Q
$file, $newfile Q
. $file $newfile
. Q
Q .
, ,
, . Q

.
, .
, ; Q
.
FAQ
. . .

241

: ,
.
/\.old$/, .old (
, .old
betty.old.old),
.new.


Q
, UNIX,
, Q
. , Q
; Q
UNIX.
(
, ,
, Q, CDQROM DVDQROM). Q
. Q
,
.
613, 7033 . .
, Q
. ,
.
.1 Q
Q
. (.) , (..)
2, Q
. . 13.1 .
chicken, /home/barney/
poems, . 613,
919. ( poems Q
, .) Q
( chicken) (
919);
1

UNIX ( , Q
. .)
i ls. ls ail.
Q
,
.
root UNIX . ..
, .,
root.

242

13.

613

919
1

A Jurassic chicken named Meg


With two beaks, three wings, and one leg,
As her third eye she winked,
Quoth Ill soon go extinct,
But Ill lay first a cubical egg.

2
.
..
dodgson
chicken
abacus

919
8002
7033
613
11320

. 13.1. UNIX

Q
.
, Q
.
, ?
,
. 0,
, Q
.
, Q
. chicken
1 .

. , ,
., . Q
, 2:
. Q
, Q
, ...1
. 13.1 2 Q
.
.2
? , . , Q
Perl link
:
1

,
2 + .
, .
ls l
( rwxr
xrx). , 1,
1.

243


link "chicken", "egg"
or warn "can't link chicken to egg: $!";

, "ln chicken egg" Q


UNIX. link
, true. Q
false $!,
. egg Q
chicken, ; Q
, , ,
, . . 13.2

613.
, .
chicken 200 , egg 200
( 200 ,
).
egg, chicken.1 Q
( ) chicken, Q
egg. :
egg chicken. ,
.2
:

613

919
2

A Jurassic chicken named Meg


With two beaks, three wings, and one leg,
As her third eye she winked,
Quoth Ill soon go extinct,
But Ill lay first a cubical egg.

2
.
..
dodgson
chicken
abacus
egg

919
8002
7033
613
11320
613

. 13.2. egg chicken

Q
, , Q
, .
egg , ,
egg chicken
.
, Q

. ?

244

13.

.1 Q
, (Q
, ) Q
. rename Q
,
,
( ).
, Q
, Q
.
: Q
.
, . Q
, , find pwd,
.
, Q
. , Q
: .2
( , Q
, ) Q
,
. ,
poems ;
Perl symlink:
symlink "dodgson", "carroll"
or warn "can't symlink dodgson to carroll: $!";

,
lnQs dodgson carroll . . 13.3 Q
Q
7033. /home/barney/po
ems/carroll, , /home/
barney/poems/dodgson ,
.
, ( )
7033 Q 1. Q
: Q
carroll, dodgson.
,
Q

.. root Q
, .
UNIX ,
.

245

7033

919
1

Yet what are all such gaieties to me


Whose thoughts are full of indices
and surds?
x2 + 7x + 53
= 11/3

2
.
..
dodgson
chicken
abacus
egg
carroll

>

919
8002
7033
613
11320
613
dodgson

. 13.3. 7033

. ,

, ! ,
( )
, .
dodgson, Q
.1 carroll , Q
.
l 'carroll' true, e 'carroll' false:
, .
, Q
, .

/home/barney,
, : /usr/lo
cal/opt/system/httpd/rootQdev/users/staging/barney/cgiQbin.
/home/barney/my_stuff,
,
. ( )
my_stuff/bowling, /usr/local/opt/sys
tem/httpd/rootQdev/users/staging/barney/cgiQbin/bowling. Q

/usr/local/opt/internal/httpd/wwwQdev/users/staging/barney/cgiQbin,
,
Q .
/usr/bin/perl /usr/local/bin/perl ( Q
)
Perl . Perl.
1

, carroll Q
, .

246

13.

, , ,
Perl. , ,
. , Q
Q ; , Q
#!/usr/bin/perl,
. , Q
, Perl , Q
. (, , , Q

/usr/bin/perlQ7.2, , Q
Q
, #!/usr/bin/perl6.1.)
, ,
. , Q
UNIX, ,
. Q
(shortcuts) (aliases)
manQ perlport.
, , Q
readlink.
, undef, Q
:
my $where = readlink "carroll";

# "dodgson"

my $perl = readlink "/usr/local/bin/perl"; # , ,


# perl

unlink. Q
, , Q
, , .


.
mkdir:
mkdir "fred", 0755 or warn "Cannot make fred directory: $!";

true, Q
$!.
, 0755? Q
1 ( Q
). ,
UNIX Q
1

, , umask. Q
manQ umask(2).

247

3 , Q
. , Windows MacPerl
mkdir Q UNIX.
0755 ,
( Q
).
mkdir ,
( Q
). , Q
0755 493,
Perl. ,
755, 1363
.
2, ,
, Q
, 0. , Q
:
my $name = "fred";
my $permissions = "0755"; #
mkdir $name, $permissions;

,
01363 Q , 0755
. ,
oct,
:
mkdir $name, oct($permissions);

, , Q
. oct
. Q
, :
my ($name, $perm) = @ARGV; # 
mkdir $name, oct($perm) or die "cannot create $name: $!";

$perm , oct
.
rmdir. Q
unlink, :
foreach my $dir (qw(fred barney betty)) {
rmdir $dir or warn "cannot rmdir $dir: $!\n";
}

, rmdir .

unlink, ,

248

13.

. ,
:
my $temp_dir = "/tmp/scratch_$$";

#
# ; .
mkdir $temp_dir, 0700 or die "cannot create $temp_dir: $!";
...
# $temp_dir
...
unlink glob "$temp_dir/* $temp_dir/.*"; # $temp_dir
rmdir $temp_dir;
#

Q
,
$$ ( ).
,
. (

; quarry,
/tmp/quarry_$$.)
unlink
, rmdir
. ,
unlink , rmdir
. , Q
rmtree File::Path Q
Perl.


UNIX chmod
. Perl chmod:
chmod 0755, "fred", "barney";

, chmod Q
,
$! ,
. UNIX ( Q
Perl, ). , Q
mkdir, Q
.
(+x go=uw), Q
UNIX chmod, chmod .1
1

File::chmod
CPAN, chmod
.

249


, Q
( )
( ) chown. Q
, Q
. :
my $user = 1004;
my $group = 100;
chown $user, $group, glob "*.o";


(, merlyn)? . getpwnam, Q
, getgrnam1,
:
defined(my $user = getpwnam "merlyn") or die "bad user";
defined(my $group = getgrnam "users") or die "bad group";
chown $user, $group, glob "/home/merlyn/*";

defined ,
undef ( ,
).
chown $!
.


,
Q
, utime .
, Q
, Q
.
(, stat . 12).
(
)
time. , , Q
, ,
. :
my $now = time;
my $ago = $now  24 * 60 * 60; #

, .
; , Q
.

250

13.
utime $now, $ago, glob "*";

#  ,
# 

, , Q
( Q
UNIX 1970 2038 Q
, 64Q
). , Q
,
.
(ctime)
, ctime
( ).
, ctime
: ctime ,
.

!
, Q
.
.
1. [12] ,
.
, Q
. Q
( Q
, ) .
(:
?)
, , Q
.
2. [4] ,
( , Q
).
3. [5]
, .
, Q
.
4. [6] , rm;
, Q
. ( rm .)
5. [10] , mv;
,

251

, , .
( mv Q
.) ,
; Q
.
6. [7] Q
, , ln;
Q
. ( ln Q
.) Q
, , Q
. (:
, , Q
.)
7. [7] Q
, ,
s;
Q
. ( , Q
.)
8. [7] Q
,
( ,
ls l: > ).

14

, Perl 90% Q
10% Q
. , Perl
, Q
. Q
, Q
,
.


? , . Q
, , ,
index . :
$where = index($big, $small);

Perl Q
.
, index Q
0. , Q
1, . . ,
, 1.1 $where 6:
my $stuff = "Howdy world!";
my $where = index($stuff, "wor");

C index C. Q
, C, ,
C.

substr

253

index
,
. $where 6, , Q
$stuff, wor.
index Q
. ,
Q
:
my
my
my
my

$stuff
$where1
$where2
$where3

=
=
=
=

"Howdy world!";
index($stuff, "w");
# $where1 2
index($stuff, "w", $where1 + 1); # $where2 6
index($stuff, "w", $where2 + 1); # $where3 1
# ( )

(,
.) Q
;
, 1.
, Q
.1 rindex.
/, Q
4:
my $last_slash = rindex("/etc/passwd", "/"); # 4

rindex ,

:
my
my
my
my

$fred =
$where1
$where2
$where3

"Yabba dabba doo!";


= rindex($fred, "abba"); # $where1 gets 7
= rindex($fred, "abba", $where1  1); # $where2 1
= rindex($fred, "abba", $where2  1); # $where3 1

substr
substr .
:
$part = substr($string, $initial_position, $length);

: , Q
( index)
1

Perl Q
Q
, . , Q
, ,
.

254

14.

. Q
:
my $mineral = substr("Fred J. Flintstone", 8, 5); # "Flint"
my $rock = substr "Fred J. Flintstone", 13, 1000; # "stone"

,
( 1000 ) Perl , Q
. , Q
, (Q
),
():
my $pebble = substr "Fred J. Flintstone", 13; # "stone"

Q
; (
1 ).1 Q
3 , i:
my $out = substr("some very long string", 3, 2); # $out "in"

, index substr Q
. ,
l:
my $long = "some very very long string";
my $right = substr($long, index($long, "l") );

: 2, Q
:
my $string = "Hello, world!";
substr($string, 0, 5) = "Goodbye"; # $string "Goodbye, world!"

, ()
. Q
. Q
, (=~)
. fred
barney 20 :
1

3. ,
0 ( ) ,
1 ( ) .
0 ( ) Q
1 ( ) .

(lvalue). ; ,
, = Q
. , ,
substr.

sprintf

255

substr($string, 20) =~ s/fred/barney/g;

, Q
. , .
, Perl , Q
Q , ?
, substr index, Q
. Q
, . substr index Q
, , Q
: Q
, ,
, .
substr ( Q
), substr
1 , Q
:
my $previous_value = substr($string, 0, 5, "Goodbye");

, , , Q
,
.

sprintf
sprintf , printf ( Q
, ), , Q
. , Q
,
, Q
printf:
my $date_tag = sprintf
"%4d/%02d/%02d %2d:%02d:%02d",
$yr, $mo, $da, $h, $m, $s;

$date_tag "2038/01/19 3:00:08".


( sprintf) Q
; printf Q
5 . Q
, Q
.
/ Q
: "2038/ 1/19 3: 0: 8".
1

, Q
Perl .

256

14.

sprintf

sprintf Q
. ,
2.50, 2.5 ,
2.49997! "%.2f":
my $money = sprintf "%.2f", 2.49997;

,
Q
, .
,
(, ) Q
:1
sub big_money {
my $number = sprintf "%.2f", shift @_;
#
1 while $number =~ s/^(?\d+)(\d\d\d)/$1,$2/;
#
$number =~ s/^(?)/$1\$/;
$number;
}

,
, , Q
. ( Q
) ,
. , 12345678.9,
$number "12345678.90".
while. Q
10,
while:
while ($number =~ s/^(?\d+)(\d\d\d)/$1,$2/) {
1;
}

? , Q
( ).
! Perl , Q
,
(), . 1 Q
,
1

, , Q
, , Q
$. !

sprintf

257

.1 , Q
:
'keep looping' while $number =~ s/^(?\d+)(\d\d\d)/$1,$2/;

, , .
? , $number
"12345678.90". ,
. ( , ?) Q
$1 "12345", $2
"678", $number "12345,678.90" ( : Q
,
).
, ? (:
.) ,
.
. Q
, Q
.
, $number "12,345,678.90". Q
, .
. Q
, .
, Q
; .
/g, Q
1 while?
, ,
. Q
s///g .2 , , ?
 . Q
, $ ,
$number "$12,345,678.90" (, ,
"$12,345,678.90", ). :
(
). ,
.

. , Q
, Perl , Q
.
, Q
, . Q Q
Perl Perl,
.

258

14.


3 , ASCIIQQ
sort.
?
? , Q
, ? Perl Q
;
.
Perl
. ,
Q
, ;
: , ! ,
. Perl ; ,
.
, .
? , Q
,
. ,
. Q
, , Q
Q
. Perl , , Q
. Q
.
Q
. .
, Perl Q
( )
.
() Q
. Q
.
, , Q
. , Q
:
sub any_sort_sub { #
my($a, $b) = @_; #
# $a $b
...
}

,
. $a $b Q

259

, , Q
,
.
, . ( Q
, .) ,
Perl Q
.
; $a $b .
.
, Q
( C qsort(3), Q
Perl). $a
$b , Q
, 1. $b Q
$a, 1.
$a $b , 0. Q
? , Q
fred Fred Q
.
:
sub by_number {
# , $a $b
if ($a < $b) { 1 } elsif ($a > $b) { 1 } else { 0 }
}

, (
&) sort .

@result:
my @result = sort by_number @some_numbers;

:
$a and $b ,
. Perl
$a $b, .
( Q
). Q
, Perl
: <=>. Q
1, 0 1, . Q
, :
sub by_number { $a <=> $b }

<=> , ,
: cmp.

260

14.

. Q
<=> >=,
,
. cmp
ge, Q
.1 , cmp ,
. , Q
, :2
sub ASCIIbetically { $a cmp $b }
my @strings = sort ASCIIbetically @any_strings;

cmp Q
, :
sub case_insensitive { "\L$a" cmp "\L$b" }

$a ( ) Q
$b ( ); Q
.
: ,
. : Q
$a $b .

, .
.
,
( ),
: Q
:
my @numbers = sort { $a <=> $b } @some_numbers;

PerlQ Q
. ,
.
,
. reverse:
my @descending = reverse sort { $a <=> $b } @some_numbers;

. (<=>
cmp) ; , $a
1

. ,
Perl . , Q
, , .
, , Perl ,
.

261

$b, , . ,
$a $b , Q
. ,
:
my @descending = sort { $b <=> $a } @some_numbers;


. ( $b
$a), (Q
<=> cmp). ,
. ( Perl Q
; reverse
sort. , Q
,
.)


,
. , Q
,
.
, ,
:
my %score = ("barney" => 195, "fred" => 205, "dino" => 30);
my @winners = sort by_score keys %score;

, ;
. ! Q
sort Q
( ASCIIQ ). Q
, Q
. Q
, .
. , ,
Q
. , $a $b ( ) Q
$score{$a} $score{$b} ( ). Q
, :
sub by_score { $score{$b} <=> $score{$a} }

, . ,
$a barney, $b fred. ,
$score{"fred"} <=> $score{"barney"}, ( ) 205 <=>
195. <=>: 205 195,
: , ;

262

14.

$b $a. Perl,
fred barney.
$a barney, $b dino.
30 <=> 195 ,
; $a Q
$b ( barney dino). Perl Q
: fred
, barney dino.
$score{$b} $score{$a}, ?
,
. ( Q
) : $score{$b}
<=> $score{$a} , Q
, .


, Q
. :
my %score = (
"barney" => 195, "fred" => 205,
"dino" => 30, "bammbamm" => 195,
);

, bammbamm barney.
Q
? , ( Q
) .
, , ,
, .
,
. Q
ASCIIQ .
?
:
my @winners = sort by_score_and_name keys %score;
sub by_score_and_name {
$score{$b} <=> $score{$a} #
#
or
$a cmp $b
# ASCII
}

? <=> ,
.
1 1 ( ), Q

263

or ,
(, or Q
). <=> Q
, 0 ( ). Q
cmp, Q
. ,
.
, by_sco
re_and_name 0. ( , ? Q
1.) , , Q
; ,
.
,
. , Q
.
( Q
%fine, ), (
%items), ( , ,
) , , ,
:
@patron_IDs = sort {
&fines($b) <=> &fines($a) or
$items{$b} <=> $items{$a} or
$family_name{$a} cmp $family_name{$a} or
$personal_name{$a} cmp $family_name{$b} or
$a <=> $b
} @patron_IDs;

.
1. [10] , Q
.
. Q
numbers
OReilly (. ):
17 1000 04 1.50 3.14159 10 1.5 4 2001 90210 666

2. [15] ,
( ) Q
1

0 :
. , Q
. , sort , 0
, .

264

14.

. Q
, ( Q
) . Q
Fred,
Betty.
. ;
, . ( Q
sortable_hash,
.)
my %last_name = qw{
fred flintstone Wilma Flintstone Barney Rubble
betty rubble BammBamm Rubble PEBBLES FLINTSTONE
};

3. [15] , Q
. ,
"This is a test." "is" Q
2 5, "a" 8.
"t"?

15
given)when
, ,
, ! Perl ,
, ,
. Perl 5.10
givenwhen .


~~ Q
, .
, .
, . Q
, .
, Q
, .
~~ =~, Q
8, ~~ . ,
.
, $name Q
:
print "I found Fred in the name!\n" if $name =~ /Fred/;

, Q
:
use 5.010;
say "I found Fred in the name!" if $name ~~ /Fred/;

, Q
, , Q

266

15. givenHwhen

, . , Q
. .

. , Q
, %names Fred. Q
exists ,
. foreach, Q
,
. Q
, $flag
last:
my $flag = 0;
foreach my $key ( keys %names ) {
next unless $key =~ /Fred/;
$flag = $key;
last;
}
print "I found a key matching 'Fred'. It was $flag\n" if $flag;

! , Q
Perl 5. Q
,
:
use 5.010;
say "I found a key matching 'Fred'" if %names ~~ /Fred/;

, ,
. ,
%names Q
. ,
true.
.
~~ ; , Q
. , Q
.
, ( Q
). Q
.
, ,
$equal. $equal Q
@names1, :
my $equal = 0;
foreach my $index ( 0 .. $#names1 ) {
last unless $names1[$index] eq $names2[$index];
$equal++;

267

}
print "The arrays have the same elements!\n"
if $equal == @names1;

. Q
Q ? Q! Q
? ~~.
, ,
:
use 5.010;
say "The arrays have the same elements!"
if @names1 ~~ @names2;

. , Q
, Q
. max() 4:
. Q
, max
, Q
:
my @nums = qw( 1 2 3 27 42 );
my $result = max( @nums );
my $flag = 0;
foreach my $num ( @nums ) {
next unless $result == $num;
$flag = 1;
last;
}
print "The result is one of the input values\n" if $flag;

, : ! ~~
.
:
use 5.010;
my @nums = qw( 1 2 3 27 42 );
my $result = max( @nums );
say "The result [$result] is one of the input values (@nums)"
if @nums ~~ $result;

,
. , Q
:
use 5.010;
my @nums = qw( 1 2 3 27 42 );
my $result = max( @nums );

268

15. givenHwhen

say "The result [$result] is one of the input values (@nums)"


if $result ~~ @nums;

.
, ,
, .

; Q
, . :
use 5.010;
say "I found a name matching 'Fred'" if $name ~~ /Fred/;
say "I found a name matching 'Fred'" if /Fred/ ~~ $name;


, , Q
. ,
.
Smart matching in detail perlsyn. . 15.1
, ~~.
15.1. ,

%a ~~ %b

%a ~~ @b

%a @b

%a ~~ /Fred/

%a ~~ 'Fred'

: exists $a{Fred}

@a ~~ @b

@a ~~ /Fred/

@a ~~ 123

123 ( )

@a ~~ 'Fred'

'Fred' ( )

$name ~~ undef

$name

$name ~~ /Fred/

123 ~~ '123.0'

'Fred' ~~ 'Fred'
123 ~~ 456

, Perl Q
, . Q
.

given

269

. ,
:
use 5.010;
if( @array ~~ %hash ) { ... }

Perl , ,
@array %hash.
,
. ?
use 5.010;
if( $fred ~~ $barney ) { ... }

, ;
,
. Perl Q
, . Q
?
, $fred $barney, Perl Q
.
, , Q
. Q
: Perl (
numish strings).
'123', '3.14149' . . Q
, Q
, Perl Q
. Perl Q
, .
.

given
given , Q
. , PerlQ
switch C; ,
Perl, given , Q
.
Q
$ARGV[0], when , Q
Fred. when
Fred, :
use 5.010;
given( $ARGV[0] ) {
when( /fred/i ) { say 'Name has fred in it' }

270

15. givenHwhen
when( /^Fred/ ) { say 'Name starts with Fred' }
when( 'Fred' ) { say 'Name is Fred' }
default
{ say "I don't see a Fred" }
}

given $_,
$_. Q
,
, :
use 5.010;
given( $ARGV[0]
when( $_ ~~
when( $_ ~~
when( $_ ~~
default
}

) {
/fred/i ) { say
/^Fred/ ) { say
'Fred' ) { say
{ say

'Name has fred in it' }


'Name starts with Fred' }
'Name is Fred' }
"I don't see a Fred" }

$_ when,
default. :
$ perl5.10.0 switch.pl
Name has fred in it
$ perl5.10.0 switch.pl
Name has fred in it
$ perl5.10.0 switch.pl
I don't see a Fred
$ perl5.10.0 switch.pl
Name has fred in it

Fred
Frederick
Barney
Alfred

, . ifQ
elsifQelse. Q
$_, my. Q
my,
Perl 5.10:
use 5.010;
{
my $_ = $ARGV[0]; # lexical $_ as of 5.10!
if( $_ ~~ /fred/i ) { say 'Name has fred in it' }
elsif( $_ ~~ /^Fred/ ) { say 'Name starts with Fred' }
elsif( $_ ~~ 'Fred' ) { say 'Name is Fred' }
else
{ say "I don't see a Fred" }
}

given , ifQelsifQelse,
. , ifQelsifQ
else, givenwhen
. , ifQelsifQ
else
.

271

given

, Q
. ,
break, Perl Q
givenQwhen . Q
, break,
:
use 5.010;
given( $ARGV[0]
when( $_ ~~
when( $_ ~~
when( $_ ~~
default
}

) {
/fred/i ) { say
/^Fred/ ) { say
'Fred' ) { say
{ say

'Name has fred in it'; break }


'Name starts with Fred'; break }
'Name is Fred'; break }
"I don't see a Fred"; break }

.
, Q
/fred/i Perl when. Q
Fred , Q
when Q
.
when continue, Perl
,
. ifQelsifQelse Q
. when , Perl
( break,
). continue
, Perl :
use 5.010;
given( $ARGV[0]
when( $_ ~~
when( $_ ~~
when( $_ ~~
default
}

) {
/fred/i ) { say
/^Fred/ ) { say
'Fred' ) { say
{ say

'Name has fred in it'; continue }


'Name starts with Fred'; continue }
'Name is Fred'; continue } # OOPS!
"I don't see a Fred" }

. ,
, default Q
:
$ perl5.10.0 switch.pl Alfred
Name has fred in it
I don't see a Fred

default when ,
. when default continue,
Perl default. ,
default when:

272

15. givenHwhen
use 5.010;
given( $ARGV[0] ) {
when( $_ ~~ /fred/i
when( $_ ~~ /^Fred/
when( $_ ~~ 'Fred'
when( 1 == 1
}

)
)
)
)

{
{
{
{

say
say
say
say

'Name has fred in it'; continue }


'Name starts with Fred'; continue }
'Name is Fred'; continue } # OOPS!
"I don't see a Fred" } # default

,
continue. when :
use 5.010;
given( $ARGV[0] ) {
when( $_ ~~ /fred/i
when( $_ ~~ /^Fred/
when( $_ ~~ 'Fred'
when( 1 == 1
}

)
)
)
)

{
{
{
{

say
say
say
say

'Name has fred in it'; continue }


'Name starts with Fred'; continue }
'Name is Fred'; break } # OK now!
"I don't see a Fred" }

, , ,
,
:
use 5.010;
given( $ARGV[0] )
when( /fred/i
when( /^Fred/
when( 'Fred'
default
}

{
) { say 'Name has fred in it'; continue }
) { say 'Name starts with Fred'; continue }
) { say 'Name is Fred'; }
{ say "I don't see a Fred" }


givenQwhen
, . , ,
Q
, . when Q
( ) , Perl
, :
use 5.010;
given( $ARGV[0]
when( $_ =~
when( $_ =~
when( $_ eq
default
}

) {
/fred/i ) { say
/^Fred/ ) { say
'Fred' ) { say
{ say

'Name has fred in it'; continue }


'Name starts with Fred'; continue }
'Name is Fred' }
"I don't see a Fred" }

Q
; when Q
:

given

273

use 5.010;
given( $ARGV[0] ) {
when( /fred/i )
{ #smart
say 'Name has fred in it'; continue }
when( $_ =~ /^Fred/ ) { #dumb
say 'Name starts with Fred'; continue }
when( 'Fred' )
{ #smart
say 'Name is Fred' }
default
{ say "I don't see a Fred" }
}

,
Q
$_.
( Q
), Q
. Q
:
use 5.010;
given( $ARGV[0] ) {
when( /^?\d+\.\d+$/ ) { #
say 'Not a number!' }
when( $_ > 10 )
{ #
say 'Number is greater than 10' }
when( $_ < 10 )
{ #
say 'Number is less than 10' }
default
{ say 'Number is 10' }
}

Perl Q
. , when Q
1, Perl (true/false)
:
use 5.010;
given( $ARGV[0] ) {
when( name_has_fred( $_ ) ) { #
say 'Name has fred in it'; continue }
}

Q
Perl defined, exists eof, .
Q
, .
1

Perl , QQ
. IntermeQ
diate Perl (OReilly) Perl: , Q, 2007.

274

15. givenHwhen

, Q
:
use 5.010;
given( $ARGV[0] ) {
when( ! $boolean ) { #
say 'Name has fred in it' }
when( ! /fred/i } { #
say 'Does not match Fred' }
}

when
Q
, given . ,
given foreach. , Q
@names, $name
given:
use 5.010;
foreach my $name ( @names ) {
given( $name ) {
...
}
}

? , : . (
?)
@names , given Q
! , Perl Q
! ,
.
given
. foreach $_.
, Q
$_.
use 5.010;
foreach ( @names ) { #
when( /fred/i ) { say
when( /^Fred/ ) { say
when( 'Fred' ) { say
default
{ say
}

!
'Name has fred in it'; continue }
'Name starts with Fred'; continue }
'Name is Fred'; }
"I don't see a Fred" }

, , Q
. foreach Q
, say:

275

use 5.010;
foreach ( @names ) { # !
say "\nProcessing $_";
when( /fred/i ) { say 'Name has fred in it'; continue }
when( /^Fred/ ) { say 'Name starts with Fred'; continue }
when( 'Fred' ) { say 'Name is Fred'; }
default
{ say "I don't see a Fred" }
}


when,
default ( given):
use 5.010;
foreach ( @names ) { # !
say "\nProcessing $_";
when( /fred/i ) {
when( /^Fred/ ) {
when( 'Fred' ) {
say "Moving on to
default
{
}

say 'Name has fred in it'; continue }


say 'Name starts with Fred'; continue }
say 'Name is Fred'; }
default...";
say "I don't see a Fred" }

.
1. [15] 1 10 ,
given.
? Q
.
2. [15] givenQwhat,
, Fizz, Q
3, Bin, 5, Sausage,
7. , 15 Fizz
Bin, 15 3, 5. Q
Fizz Bin Sausage?
3. [15] forQwhen, , Q
, Q
, . Q
.
4. [20] given ,
,
( 1 ). , 99 Q
3, 9, 11 33.
(. . ),
. , Q

276

15. givenHwhen

Q
. if
, .
,
.
1 $number:
sub divisors {
my $number = shift;
my @divisors = ();
foreach my $divisor ( 2 .. $number/2 ) ) {
push @divisors, $divisor unless $_ % $divisor;
}
return @divisors;
}

5. [20] ,
, Q
, ( Q
, 1 ),
. Q
.

16


, Q
. , , Q
Perl.
, Perl, :
, Q
. Q
, , Q
, .
Perl ; Q
, ,
UNIX , Windows , VMS Q. ,
, : MacQ
intosh , Cray . Q
UNIX;
.

system
Perl
system. , UNIX date Perl
:
system "date";

date, Perl
, . , Q
,

278

16.

date, , Perl Q
STDOUT.
system , Q
. Q
, (, ls l $HOME) Q
:
system 'ls l $HOME';

: ,
$HOME . Q
$,
Perl. ,
:
system "ls l \$HOME";

.
date . , Q
, :
?1 Q
,
( STDIN). Q
, , date .
, Perl .
date 37 , Perl Q
37 . , Q

:2
system "long_running_command with parameters &";

, & Q
long_running_command Q
. , Perl
. long_running_com
mand Perl; Q
, .
,
. , date ls Perl Q
,
1

, date,
.
, , ? Q
UNIX (/bin/sh) & Q
. Q
, , .

system

279

PATH.1 Q (, Q
: $, ; |), Q
Bourne Shell (/bin/sh2).
,
( Q
). ,
Q :
system 'for i in *; do echo == $i ==; cat $i; done';

, $
, Perl. Perl
$i Q
.3 , Q
,
; , .


system Q
.4 ,
:
my $tarfile = "something*wicked.tar";
my @dirs = qw(fred|flintstone <barney&rubble> betty );
system "tar", "cvf", $tarfile, @dirs;

("tar" ) Q
, PATH, Q
. Q
, Q
(, $tarfile @dirs), Q
. ,
tar .
:

PATH $ENV{'PATH'}. Q
,
( ).
, . Q
PATH ,
(), , UNIX.
,
Perl. UNIXQ /bin/sh.
, $i = '$i', Q
, Q .
, system { 'fred' }'bar
ney'; barney, ,
'fred'. . manQ perlfunc.

280

16.
system "tar cvf $tarfile @dirs"; # !

: system Q
:
system $command_line;
system "/bin/sh", "c", $command_line;

,
, Q
, C Shell:
system "/bin/csh", "fc", $command_line;

, Q
1 .
system
.2 UNIX 0 , Q
,
:
unless (system "date") {
# 
print "We gave you a date, OK!\n";
}

true
, false , , Q
or die Q
true false. system
! ( ):
!system "rm rf files_to_delete" or die "something went wrong";

$! . Q
Q rm, Q
, system, Q
$!.

/bin/sh Bourne , Q
UNIX. ,
Perl , Q
(. Q
Perl).
, ,
128 ,
, ( ). Q
, Q
true/false .

exec

281

exec
, system,
exec ( ) Q
. system , Q
, Perl . exec Q
Perl . Q
goto, .
, bedrock /tmp.
o args1, Q
, . Q
:
chdir "/tmp" or die "Cannot chdir /tmp: $!";
exec "bedrock", "o", "args1", @ARGV;

exec Perl bedrock Q


. Perl 1, Q
, bedrock.
bedrock Perl, ,
,
(, ).
? , Perl
.
, .
system exec, Perl
system , Q
, Q
.
exec ,
fork (. ). sys
tem exec, system, .
Perl Q
, Perl exec
, ,
:
exec "date";
die "date couldn't run: $!";

, , exec
die2, Perl .
1

, Q
UNIX exec(2) ( ).
.
exit. . Perl Q
.

282

16.


( )
. Q
,
, . Q
.
PATH.
( , , Q
.) UNIX
PATH ,
.
(, rm fred), rm
. Perl ( ) PATH
, . Q
,
PATH. (,
, /bin/echo, PATH ,
.)
Perl
%ENV; . Q
%ENV ,
( ). Q
, Q
Perl. ,
make (
) , (
make) . ,
IFS ,
make .
:
$ENV{'PATH'} = "/home/rootbeer/bin:$ENV{'PATH'}";
delete $ENV{'IFS'};
my $make_result = system "make";

Q
, , ,
, .
Q
. (, Q

, .)

283


system exec Q
Perl.
Q
. :
` `:
my $now = `date`;
# date
print "The time is now $now"; #

date Q
30 .
.
date , Perl date,
( )
$now.

UNIX.
, Q
. Perl : Q
. Perl,

chomp:
chomp(my $no_newline_now = `date`);
print "A moment ago, it was $no_newline_now, I think.\n";

sstem
( Q
\
).1 ,
Perl perldoc :
my @functions = qw{ int rand sleep length hex eof not exit sqrt umask };
my %about;
foreach (@functions) {
$about{$_} = `perldoc t f $_`;
}

$_ , Q
,
. ,
, .

, \,
. \\
( Windows), .

284

16.

Q
1: \ Q
. system Q
( Q
). ,
UNIX Bourne Shell (
, ).
,
.2 :
print "Starting the frobnitzigator:\n";
`frobnitz enable`; # !
print "Done!\n";

, Perl Q
( Q
), system Q
Q
. , , Q
system .
Q
Perl. Q
, , ;
, frobnitz.
Q
, Q

; UNIX 2>&1:
my $output_with_errors = `frobnitz enable 2>&1`;

Q
,
(, , Q
). Q
, .3
Perl.
, , , Q
, Q
. , date , Q
1

2
3

: qx'...'
, , Q
( Q
).
.
IPC::Open3 Perl
(. ).

285

(. ).
, , Q
date . Q
, !
, .
, , Q
. , Q
, /dev/null:
my $result = `some_questionable_command arg arg argh </dev/null`;


/dev/null, some_questionable_command Q
Q
.


,
Q
. Q
,
. ,
UNIX who Q
:
merlyn
rootbeer
rootbeer

tty/42
console
tty/12

Dec 7 19:41
Dec 2 14:15
Dec 6 23:00

, tty (. .
),
( ,
, ). Q
,
:
my $who_text = `who`;


:
my @who_lines = `who`;

@who_lines , Q
. , Q
chomp, .
foreach,
, Q
$_:

286

16.
foreach (`who`) {
my($user, $tty, $date) = /(\S+)\s+(\S+)\s+(.*)/;
$ttys{$user} .= "$tty at $date\n";
}

. (Q
, .)
; Q
(=~) $_, Q
, Q
.
, ,
, , Q
, ( Q
).1 ,
$1 "merlyn", $2 "tty/42", $3
"Dec 7 19:41". Q
,
(. 8). Q
$user "merlyn" . .
tty , Q
(, undef),
( Q
"rootbeer" ).



, Perl , Q
, () .
Perl ,
2 Perl
.
Q
open,
.
:
open DATE, "date|" or die "cannot pipe from date: $!";
open MAIL, "|mail merlyn" or die "cannot pipe to mail: $!";

,
: , , Q
.
(pipes) Q
, .

287

, | ,
DATE, Q
, date | your_program
. , | Q
, MAIL, Q
, your_program | mail merlyn.

Perl.1 , open Q
. ,
() ,
. .
, Q
, , ,
, . ,
, Q
, :
my $now = <DATE>;

mail (
merlyn ),
print :
print MAIL "The time is now $now"; # , $now
#

, , Q
: date, Q
mail.
, Q
, , Q
, . Q
, Q
, . , Q
:
close MAIL;
die "mail: nonzero exit of $?" if $?;

, ,
, Perl .
$? ( Q
Bourne Shell). , Q
system: , Q
. Q
1

Perl ,
, Q
.

288

16.

, , Q
. ( $?
system ` `, Q
.)
,
. , ,
( Q
) , Q Q
. ,
, , Q
.
( 8 ), Q
.
? Q
, Q
. Q
, Q
.
, UNIX find Q
(, Q
) . Q
find ,
:
open F, "find / atime +90 size +1000 print|" or die "fork: $!";
while (<F>) {
chomp;
printf "%s size %dK last accessed on %s\n",
$_, (1023 + s $_)/1024, A $_;
}

find , Q
90 , 1000 . (
Q
.) Perl .
Perl Q
.
, Q
find. ,
.

, , Perl Q

UNIX . Q

289

1, , . Q
, , ,
:
system "date";


:
defined(my $pid = fork) or die "Cannot fork: $!";
unless ($pid) {
#
exec "date";
die "cannot exec date: $!";
}
#
waitpid($pid, 0);

fork, undef
. , Q
, Q
$pid,
exec.
waitpid,
.
, ,
system, .
Q
, Q
( Q
). ,
. manQ
perlipc ( Q
).


UNIX ,
. ;
? ,
, , ,
, , ?
, UNIX ,

fork . Perl
,
UNIX.

290

16.

.1
(, SIGINT Q
) ( 1 16, 1 32
1 63 UNIX).
. ,
( ControlQC)
, ,
SIGINT.2 Q
, Q
.
Perl ,
. Q
3, , Q
SIGINT 4201. :
kill 2, 4201 or die "Cannot signal 4201 with SIGINT: $!";

kill, Q
, Q
. 2 'INT',
2 SIGINT.
4, false, Q
, . 0 Q
: ,
, ,
. ,
:
unless (kill 0, $pid) {
warn "$pid has gone away!";
}

, .
SIGHUP, SIGCONT, SIGINT SIGZERO.
, ControlQC ?
SIGINT, Q
. , Q
,
SIGINT.
, Q
, fork; Q
.
, Q
,
.
, Q
, Q . ,
SIGINT .

291

, ,
. ? ,
/tmp,
. Q ControlQC ,
/tmp , Q
. , Q
:
my $temp_directory = "/tmp/myprog.$$"; #
mkdir $temp_directory, 0700 or die "Cannot create $temp_directory: $!";
sub clean_up {
unlink glob "$temp_directory/*";
rmdir $temp_directory;
}
sub my_int_handler {
&clean_up;
die "interrupted, exiting...\n";
}
$SIG{'INT'} = 'my_int_handler';
.
. # , ,
. # .  ControlC.
.
#
&clean_up;

%SIG Q
( ).
( SIG), 1 Q
( &). SIGINT Perl Q
Q
. , Q
. ControlQC,
&clean_up
.
die,
, .
, Q Q
. , Q
,
, Q
.
:

,
.

292

16.
my $int_count;
sub my_int_handler { $int_count++ }
$SIG{'INT'} = 'my_int_handler';
...
$int_count = 0;
while (<SOMEFILE>) {
... ...
if ($int_count) {
# !
print "[processing interrupted...]\n";
last;
}
}

$int_count 0.
ControlQC, .
Q
$int_count, Q
.
, , Q
; , Q
. , Q
1;
,
.

.
1. [6] ,
(, ) Q
ls l Q
. ( UNIX,

.)

Perl.
, Q
Perl 6. , Q
, Perl . Perl, , Q
, Q
, .
, Perl , XSUB ( Q
C) . Q

Perl.

293

2. [10] , Q
ls.out . Q
ls.err. (
, Q
.)
3. [8] ,
date . Q
get to work,
go play. date Mon
(Monday1). date , Q
, Q
date.
, :
#!/usr/bin/perl
print localtime( ) . "\n";

. Q
.

17
Perl

, , Perl
, Perl.
. , Q
. Q
.
; ,
. Q
, Q
. ( Q
) , Perl.
Q, Q
Perl. .1

eval
, Q
.
:
$barney = $fred / $dino;

# ?

print "match\n" if /^($wilma)/; # ?


open CAVEMAN, $fred
# die?
or die "Can't open file '$fred' for input: $!";

,
. ( $wilma Q
, ?)
1

, OReilly .

eval

295

, Perl Q
eval:
eval { $barney = $fred / $dino } ;

$dino ,
. eval ( Q
, while foreach), Q
.
eval ( Q
) , , Q
. , eval
, Q
.
$@. , $@ Q

my_program 12. , Q
$@ . , , $@ Q
(true ),
eval :
print "An error occurred: $@" if $@;

eval , Q
(my) . Q
eval :
foreach my $person (qw/ fred wilma betty barney dino pebbles /) {
eval {
open FILE, "<$person"
or die "Can't open file '$person': $!";
my($total, $count);
while (<FILE>) {
$total += $_;
$count++;
}
my $average = $total/$count;
print "Average for file $person was $average\n";
&do_something($person, $average);
};
if ($@) {
print "An error occurred ($@), continuing\n";
}
}

? Q
, .

296

17. Perl

, .
&do_something ,
eval , Q
. ( , ,
, ,
, .)
, Q
, Q
.
eval eval.
, Q
. (,
eval die,
.) eval
, ,
( ).
, eval , Q
Q
. , eval
.
:
, Q
return. Q
, :
my $barney = eval { $fred / $dino };

eval ,
undef, (
). , $barney Q
, undef; $@ Q
(, , $barney
defined($barney)).
, eval Q
. , Q
Perl,
. Perl ,
.1 , eval
Q
$@.
exit , Q
eval. ( ,

, (X)
manQ perldiag.

297


die exit.)
,
eval, ( warn)
( w Q
use warnings).
, eval; Q
__WARN__ Perl.
eval,
. ,
, eval Q
. , eval
, eval eval
. eval
,
eval .



. , Q
, Q
Fred. Q
, Q
grep.
Q
. :
my @odd_numbers;
foreach (1..1000) {
push @odd_numbers, $_ if $_ % 2;
}

(%), Q
2. Q
2 0, .
1; ,
.
,
, , Perl
grep:
my @odd_numbers = grep { $_ % 2 } 1..1000;

500
. ? grep ,
$_ .

298

17. Perl

(true/false).
, . Q
grep Q
foreach. ,
, Q
grep.
grep $_
. Q
foreach. , $_ grep
,
.
grep UNIX,
. Q
Perl grep ,
.
, fred:
my @matching_lines = grep { /\bfred\b/i } <FILE>;

grep . Q
( ),
, . Q
:
my @matching_lines = grep /\bfred\b/i, <FILE>;


.
, ,
, &big_money (. Q
14). ;
, .
:
my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
my @formatted_data;
foreach (@data) {
push @formatted_data, &big_money($_);
}

,
grep, ? , , Q
grep:
my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
my @formatted_data = map { &big_money($_) } @data;

299

map grep, :
, $_, .
: Q
, $_ Q
.
map :
, .1 grep
map foreach Q
,
, . map grep Q
, . Q

:
print "The money numbers are:\n",
map { sprintf("%25s\n", $_) } @formatted_data;

, Q
@formatted_data:
my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);
print "The money numbers are:\n",
map { sprintf("%25s\n", &big_money($_) ) } @data;

map, grep, .
( Q
), , Q
, :
print "Some powers of two are:\n",
map "\t" . ( 2 ** $_ ) . "\n", 0..15;


Perl , Q
. , : Q
.2
, , Q
. Q
. ,
,
.
(barewords).
1

, , Q
map, Q
( ).
, ,
(). . .

300

17. Perl

Q
:
. , $score{"fred"} Q
$score{fred}. , Q
. :
, Perl Q
.

Q. (=>)
, Q
(
):
#
my %score = (
barney => 195,
fred
=> 205,
dino
=> 30,
);

Q
;
( , ,
). Q
, Q
.

,
. ,
.
, :: ,
, , , Q
. Q
:
fred flintstone:2168:301 Cobblestone Way:5551212:5552121:3
barney rubble:709918:3128 Granite Blvd:5553333:5553438:0

Q
;
. ,
:
while (<FILE>) {
chomp;
my @items = split /:/;
my($card_num, $count) = ($items[1], $items[5]);

301

... #
}

@items ; Q
.1 , split Q
:
my($name, $card_num, $addr, $home, $work, $count) = split /:/;

@items, Q
.

$dummy_1, ,
. ,
, Perl Q
undef. undef
, Q
:
my(undef, $card_num, undef, undef, undef, $count) = split /:/;

? , . Q
, : undef, Q
, $count. Q
.
, , Q
stat mtime, :
my(undef, undef, undef, undef, undef, undef, undef,
undef, undef, $mtime) = stat $some_file;

undef, mtime atime


ctime; .
: Perl
. (slice) .
mtime 9 , stat2,
:
my $mtime = (stat $some_file)[9];

( stat) Q
. Q
, :
my $mtime = stat($some_file)[9]; # !
1

.
, , Q
, .
, 9,
0.
, .

302

17. Perl

Q
. , Q
, .
: , ,
split. Q
1 5 :
my $card_num = (split /:/)[1];
my $count = (split /:/)[5];

, (Q
) Q , Q
, split .
; , Q
:
my($card_num, $count) = (split /:/)[1, 5];

1 5,
. Q
my, , .
, Q
.
Q
. Q
;
, 1 :1
my($first, $last) = (sort @names)[0, 1];

.
5 , 10 Q
:
my @names = qw{ zero one two three four five six seven eight nine };
my @numbers = ( @names )[ 9, 0, 2, 1, 0 ];
print "Bedrock @numbers\n"; # Bedrock nine zero two one zero


.
( ) .
, :
my @numbers = @names[ 9, 0, 2, 1, 0 ];
1

, Q
. Perl
,
( , Q
).

303

; Q

. ( 3) , @ @names
. Perl $ , Q
@ .
, Q
@. Perl
@names[ ... ], , Perl, Q
@ . Q
, ,
@ 1
( $). . . 17.1.

$names [ . . . ]

@names [ . . . ]

. 17.1.

($ @) Q
. $ Q
. @,
.
, @names[ 2, 5 ] , ($names[2],
$names[5]). ,
. , ,
.
,
,
:

, ,
.

304

17. Perl
my @names = qw{ zero one two three four five six seven eight nine };
print "Bedrock @names[ 9, 0, 2, 1, 0 ]\n";

@names ,
. @names[ 9,
0, 2, 1, 0 ], ,
.1 . , Q
, Q
.
@items, Q
:
my $new_home_phone = "5556099";
my $new_address = "99380 Red Rock West";
@items[2, 3] = ($new_address, $new_home_phone);

, Q
. Q
($items[2], $items[3]), .


Q
. Q
%score? Q
, . Q
( ):
my @three_scores = ($score{"barney"}, $score{"fred"}, $score{"dino"});
my @three_scores = @score{ qw/ barney fred dino/ };

, Q
@.2 Perl Q
@score{ ... }, , Perl,
@ .
, , @
(
$). . . 17.2.
,
($ @) . $
Q
1

Perl $",
. Q
. Perl
join $", @list, @list .
, ,
: . Q
? : .

305

$score { . . . }

@score { . . . }

. 17.2.

.1 @,
.
: ,
%? ; (
) , . Perl
$ , @ Q
, % .
, Q
Q
Perl. , Q
( Q
) :
my @players = qw/ barney fred dino /;
my @bowling_scores = (195, 205, 30);
@score{ @players } = @bowling_scores;

,
:
($score{"barney"}, $score{"fred"}, $score{"dino"}).

.
:
print "Tonight's players were: @players\n";
print "Their scores were: @score{@players}\n";

, ,
Perl. . $; manQ perlvar.

306

17. Perl

.
1. [30] ,
( ). ,
. Q
, ,
.
; . Q
. (, Q
), Q

.
, . ( Q
, samp
le_text , , ,
OReilly; . .)

, Q
.

2
1. :
#!/usr/bin/perl w
$pi = 3.141592654;
$circ = 2 * $pi * 12.5;
print "The circumference of a circle of radius 12.5 is $circ.\n";

#!;
Perl.
.
$pi
. Q
1 : 3.141592654
,
. 3.141592654, Q
3.14159, .
, 3.141952654 (
),
. $pi , ,
. ,

, Q
constant.

308

, .1
, $circ Q
. ,
.
( Q
):
The circumference of a circle of radius 12.5 is
78.53981635.bash2.01$[]

2. :
#!/usr/bin/perl w
$pi = 3.141592654;
print "What is the radius? ";
chomp($radius = <STDIN>);
$circ = 2 * $pi * $radius;
print "The circumference of a circle of radius $radius is $circ.\n";

, Q
, ,
12.5.
,
$radius. Q
chomp.
, 12.5\n Q
12.5. Q
:
The circumference of a circle of radius 12.5
is 78.53981635.

$radius, Q
. $radius is print
, . :
chomp , Q
.
3. :
#!/usr/bin/perl w
$pi = 3.141592654;
print "What is the radius? ";
chomp($radius = <STDIN>);
$circ = 2 * $pi * $radius;
if ($radius < 0) {
$circ = 0;

Q
. . 246, Indiana State Legislature, 1897, http://
www.cs.uwaterloo.ca/~alopezo/mathfaq/node45.html.

309

}
print "The circumference of a circle of radius $radius is $circ.\n";

.
,
. Q
,
; . ,
Perl.

.
4. :
print "Enter first number: ";
chomp($one = <STDIN>);
print "Enter second number: ";
chomp($two = <STDIN>);
$result = $one * $two;
print "The result is $result.\n";

: #! . Q
, , ,
.
, . Q
, Q
, , $two Q
2. , Q

, $first_response $second_response.
chomp $one $two,
,
.
,
The result of multiplying $one by $two is $result.\n,
Q
. : chomp,
.
5. :
print "Enter a string: ";
$str = <STDIN>;
print "Enter a number of times: ";
chomp($num = <STDIN>);
$result = $str x $num;
print "The result is:\n$result";

:
. Q
.

310

chomp, Q
, Q
. , fred
3, fred
, .
print $result
, ,
. , , Q
fred :
The result is: fred
fred
fred


, $result .
Perl
; , Q
. ,
! x Q
$str, Perl $strx, Q
.

3
1. :
print "Enter some lines, then press CtrlD:\n"; # or maybe CtrlZ
@lines = <STDIN>;
@reverse_lines = reverse @lines;
print @reverse_lines;

:
print "Enter some lines, then press CtrlD:\n";
print reverse <STDIN>;

Perl , ,
, Q
.
2. :
@names = qw/ fred betty barney dino wilma pebbles bammbamm /;
print "Enter some numbers from 1 to 7, one per line, then press CtrlD:\n";
chomp(@numbers = <STDIN>);
foreach (@numbers) {
print "$names[ $_  1 ]\n";
}

311

1, Q
1 7, 0 6.

@names:
@names = qw/ dummy_item fred betty barney dino wilma pebbles bammbamm /;

, 1
7, .
3. ,
:
chomp(@lines = <STDIN>);
@sorted = sort @lines;
print "@sorted\n";

:
print sort <STDIN>;

4
1. :
sub total {
my $sum; # private variable
foreach (@_) {
$sum += $_;
}
$sum;
}

$sum Q
. $sum, , Q
undef. foreach ( @_),
$_ . (,
@_ $_, Q
foreach .)
foreach ( $_) $sum.
, $sum undef, Q
.
(Perl +=), Perl ,
0. Perl Q
0 $sum.
$sum, undef,
.
$sum; . ,
$sum .
. ,
( Q

312

&max Q
). $sum undef; Q
. , ,
0,
undef. (, , Q
(3, 5, 2), undef.)
, Q
, . $sum Q
undef:
my $sum = 0;

,
.
2. :
# &total !
print "The numbers from 1 to 1000 add up to ", total(1..1000), ".\n";

1, Q
print .
500500 .
; 1000 Q
Perl.
3. :
sub average {
if (@_ == 0) { return }
my $count = @_;
my $sum = total(@_);
$sum/$count;
}

sub above_average {
my $average = average(@_);
my @list;
foreach my $element (@_) {
if ($element > $average) {
push @list, $element;
}
}
@list;
}

average Q
.
undef2; ,
1

, . Perl Q
.
, &average .

313

. , Q
&total.
$sum and $count, Q
.
, above_average,
. ( $element
$_?) Q
Q
.
4. .
undef; Q
, Fred. Q
$name $last_name
:
use 5.010;
greet( 'Fred' );
greet( 'Barney' );
sub greet {
state $last_person;
my $name = shift;
print "Hi $name! ";
if( defined $last_person ) {
print "$last_person is also here!\n";
}
else {
print "You are the first one here!\n";
}
$last_person = $name;
}

5. , Q
. Q
@names
:
use 5.010;
greet(
greet(
greet(
greet(

'Fred' );
'Barney' );
'Wilma' );
'Betty' );

sub greet {
state @names;
my $name = shift;

314

A
print "Hi $name! ";
if( @names ) {
print "I've seen: @names\n";
}
else {
print "You are the first one here!\n";
}
push @names, $name;
}

5
1. :
print reverse <>;

! ;
print , , reverse
. reverse Q
, , <>
. , <>
, . reverse Q
, print .
2. :
print "Enter some lines, then press CtrlD:\n"; # CtrlZ
chomp(my @lines = <STDIN>);
print "1234567890" x 7, "12345\n"; # 75
foreach (@lines) {
printf "%20s\n", $_;
}


chomp. .
,
. Q
,
"1234567890" /
, ,
.
foreach
%20s.
:
my $format = "%20s\n" x @lines;
printf $format, @lines;

315

, Q Q
19 .
, 1: chomp,
? Q
chomp %20s ( )2
Q . ?
, Perl , Q
. Q
hello , Perl Q
, Q
. 14 6
20 %20s.
, Perl
; Q
. ( , Q
, Q) .3
3. :
print "What column width would you like? ";
chomp(my $width = <STDIN>);
print "Enter some lines, then press CtrlD:\n"; # CtrlZ
chomp(my @lines = <STDIN>);
print "1234567890" x (($width+9)/10), "\n";

foreach (@lines) {
printf "%${width}s\n", $_;
}

,
. Q
, Q
( ,
). , Q
,
.
Q
. Q
, , ,
. , ,
. (: Q
50 51 , x Q
, .)
1
2
3

, .
.
.

316


"%${width}s\n", $width. Q
s;
$widths. ,
, Q
,
'%' . $width . "s\n".
$width ,
chomp . $width chomp,
"%30\ns\n".
.
, printf,
. printf C,
, Q
, C. Q
(*), Q
:
printf "%*s\n", $width, $_;

6
1. :
my %last_name = qw{
fred flintstone
barney rubble
wilma flintstone
};
print "Please enter a first name: ";
chomp(my $name = <STDIN>);
print "That's $name $last_name{$name}.\n";

qw// (
) .
, Q
Q
, .
(,
), . ,

:
my %last_name;
$last_name{"fred"} = "flintstone";
$last_name{"barney"} = "rubble";
$last_name{"wilma"} = "flintstone";

317

: Q
my (, Q use strict),
Q .
my ,
:
my $last_name{"fred"} = "flintstone"; # !

my Q
.
, , , Q
$name chomp.

, .
chomp . Q
"fred\n" Q
chomp, "fred\n", Q
. , chomp Q
; "fred \n" ( Q
), , fred.
,
, Q
.
2. :
my(@words, %count, $word);
chomp(@words = <STDIN>);
foreach $word (@words) {
$count{$word} += 1;
}

# ()

# $count{$word} = $count{$word} + 1;

foreach $word (keys %count) { # sort keys %count


print "$word was seen $count{$word} times.\n";
}

.
(, PasQ
cal), ,
,
. , Q
use strict;
Perl .
<STDIN> Q
, @words,
chomp. @words
( , Q
).

318

foreach . Q
, Q
$count{$word} 1,
$count{$word}.
, ( +=),
, Perl $word
.1 foreach
$count{$word} 1. , Q
fred $count{"fred"} 1. Q
, $count{"fred"} , Q
undef. ( Q
+= + ), Perl
undef 0. 1 $co
unt{"fred"}.
, foreach bar
ney. $count{"barney} 1, un
def 1.
, fred.
1 $count{"fred"}, 1,
2. $count{"fred"}; Q
, fred .
foreach ,
.
() , Q
, .
, foreach , Q
. Q
.
.
,
.
, ; Q
, , Q
.
3. :
my $longest = 0;
foreach my $key ( keys %ENV ) {
my $key_length = length( $key );
$longest = $key_length if $key_length > $longest;
1

, Perl,
Q
, .
, ++,
.

319

}
foreach my $key ( sort keys %ENV ) {
printf "%${longest}s %s\n", $key, $ENV{$key};
}

foreach Q
length.
$longest, .
printf Q
. , Q
3 5, $longest
.

7
1. :
while (<>) {
if (/fred/) {
print;
}
}

2.

3.

4.
5.

.
. Fred ;
,
. ( , Q
.) frederick Alfred , Q
fred,
. Q
, frederick Alfred Q
, .
:
/[fF]red/.
/(f|F)red/ /fred|Fred/,
.
:
/\./.
, . Q
: /[.]/.
:
/[AZ][az]+/.
:
/(\S)\1/.
\S , ,

320

\1
, .
6. :
while (<>) {
if (/wilma/) {
if (/fred/) {
print;
}
}
}

/fred/
/wilma/, fred ,
wilma; .

if, :1
while (<>) {
if (/wilma.*fred|fred.*wilma/) {
print;
}
}

,
wilma fred, fred wilma.
/wilma.*fred/ fred and
wilma flintstone, .
,
Q
. OR ( , |),
AND. , Q
.2 ,
, .

, AND (. 10),
/fred/ /wilma/ if. Q
,
.
AND.

, AND. ,
AND Perl Q
, Q
Perl.

321

8
1. , Q
. before<match>after,
, , .
2. :
/a\b/

(, ,
!) bar
ney, , .
3. :
#!/usr/bin/perl
while (<STDIN>) {
chomp;
if (/(\b\w*a\b)/) {
print "Matched: |$`<$&>$'|\n";
print "\$1 contains '$1'\n";
} else {
print "No match: |$_|\n";
}
}

( ),
$1.
1 \b Q
, ,
. ,
, ; .
4. ,
:
#!/usr/bin/perl
use 5.010;
while (<STDIN>) {
chomp;
if (/(?<word>\b\w*a\b)/) {
print "Matched: |$`<$&>$'|\n";
print "'word' contains '$+{word}'\n";
} else {

, Q
, Q
. Q
; Q
.

322

A
print "No match: |$_|\n";
}
}

5. :
m!
(\b\w*a\b)
(.{0,5})
!xs

# $1: , a
# $2:
# /x /s

( $2.
,
.)
wilma, ,
( ). , Q
/s,
.
6. :
while (<>) {
chomp;
if (/\s+$/) {
print "$_#\n";
}
}

#.

9
1. :
/($what){3}/

$what /(fred|barney){3}/.
/fred|barney{3}/, Q
/fred|barneyyy/. , Q
.
2. :
my $in = $ARGV[0];
unless (defined $in) {
die "Usage: $0 filename";
}
my $out = $in;
$out =~ s/(\.\w+)?$/.out/;
unless (open IN, "<$in") {
die "Can't open '$in': $!";
}

323


unless (open OUT, ">$out") {
die "Can't write '$out': $!";
}
while (<IN>) {
s/Fred/Larry/gi;
print OUT $_;
}

Q
; , Q
. $out,
( ) .out. (,
.out .)
IN OUT Q
. Q
/g /i, ,
fred Fred.
3. :
while (<IN>) {
chomp;
s/Fred/\n/gi;
s/Wilma/Fred/gi;
s/\n/Wilma/g;
print OUT "$_\n";
}

# FRED
# WILMA
#

, .

Q, . Q
chomp
(\n) .
, Q \0.
4. :
$^I = ".bak";
#
while (<>) {
if (/^#!/) {
# ?
$_ .= "## Copyright (C) 20XX by Yours Truly\n";
}
print;
}

, Q
. , ex01Q1,
ex01Q2 . . ex...,
:
./fix_my_copyright ex*

324

5. Q
, . Q
, ,
( 1
):
my %do_these;
foreach (@ARGV) {
$do_these{$_} = 1;
}

, Q
.
$ARGV, Q
:
while (<>) {
if (/^## Copyright/) {
delete $do_these{$ARGV};
}
}

, @ARGV
:
@ARGV = sort keys %do_these;
$^I = ".bak";
#
while (<>) {
if (/^#!/) {
# ?
$_ .= "## Copyright (c) 20XX by Yours Truly\n";
}
print;
}

10
1. :
my $secret = int(1 + rand 100);
#
# print "Don't tell anyone, but the secret number is $secret.\n";
while (1) {
print "Please enter a guess from 1 to 100: ";
chomp(my $guess = <STDIN>);
if ($guess =~ /quit|exit|^\s*$/i) {
print "Sorry you gave up. The number was $secret.\n";
last;
} elsif ($guess < $secret) {
print "Too small. Try again!\n";
} elsif ($guess == $secret) {
print "That was it!\n";
last;

325

} else {
print "Too large. Try again!\n";
}
}

1 100.
: rand ,
rand 100 0 ( ) 100.
, 99.999.1
1 1 100.999, int
, 1 100.
Q
. Q
while.
, Q
last.
. Q
? , ; Q
, quit? Q
(, , Q
).
, , Q
. , .
Q
redo.
; .
, , Q
while (
). ,
, .
2.
.
, , $Debug
. $Debug , Q
, 1 .
//, 1 , Q
$ENV{DEBUG} :
use 5.010;
my $Debug = $ENV{DEBUG} // 1;
my $secret = int(1 + rand 100);
print "Don't tell anyone, but the secret number is $secret.\n"
if $Debug;
1

;
, http://
www.cpan.org/doc/FMTEYEWTK/random.

326

Q
Perl 5.10, :
my $Debug = defined $ENV{DEBUG} ? $ENV{DEBUG} : 1;

3. ,
3 6.
. Q
ZERO EMPTY , ,
UNDEFINED .
printf //
(undefined) , $ENV{$key} Q
:
use 5.010;
$ENV{ZERO}
= 0;
$ENV{EMPTY}
= '';
$ENV{UNDEFINED} = undef;
my $longest = 0;
foreach my $key ( keys %ENV )
{
my $key_length = length( $key );
$longest = $key_length if $key_length > $longest;
}
foreach my $key ( sort keys %ENV )
{
printf "%${longest}s %s\n", $key, $ENV{$key} // "(undefined)";
}

// Q
, , ZERO EMPTY.
Perl 5.10,
:
printf "%${longest}s %s\n", $key,
$ENV{$key} ? $ENV{$key} : "(undefined)";

11
1. (
Intermediate Perl1 (OReilly)), Q
, . ,
, , . Q
, .

, Perl: . .
. .: Q, 2007.

327

:
#!/usr/bin/perl
use Module::CoreList;
my %modules = %{ $Module::CoreList::version{5.006} };
print join "\n", keys %modules;

12
1. :
foreach my $file (@ARGV) {
my $attribs = &attributes($file);
print "'$file' $attribs.\n";
}
sub attributes {
#
my $file = shift @_;
return "does not exist" unless e $file;
my @attrib;
push @attrib, "readable" if r $file;
push @attrib, "writable" if w $file;
push @attrib, "executable" if x $file;
return "exists" unless @attrib;
'is ' . join " and ", @attrib; #
}

.
, Q
, 'cerealkiller' Q
, 'sasquatch' .

. , , Q
, . Q
, .
, . ( Q
, Q
_ $file,
.)
, Q
. ,
? ,
, , , Q
. unless
, @attrib ( Q
),

328

. Q
, and is , Q
.
, Q
. ; , Q
, .
, Q
.
2. :
die "No file names supplied!\n" unless @ARGV;
my $oldest_name = shift @ARGV;
my $oldest_age = M $oldest_name;
foreach (@ARGV) {
my $age = M;
($oldest_name, $oldest_age) = ($_, $age)
if $age > $oldest_age;
}
printf "The oldest file was %s, and it was %.1f days old.\n",
$oldest_name, $oldest_age;

,
. Q
,
.

. , , Q
. Q
$oldest_age.
Q
M, ,
( $_).
Q
, .
$oldest_age,
.
, Q
.
, M,
$age. , Q
M ? , Q
_ Q
Q
, (,

). , : Q

329

, Q . Q
, .
M
Q
. , $oldest_age, Q
.
, .
!
, printf
, Q
. , Q
, .
3. :
use 5.010;
say "Looking for my files that are readable and writable";
die "No files specified!\n" unless @ARGV;
foreach my $file ( @ARGV ) {
say "$file is readable and writable" if o r w $file;
}

C
Perl 5.10, use, Q
Perl. @ARGV Q
, , Q
foreach.

: o , r ,
w . o r w
,
.
Perl, 5.10,
. say Q
print , Q
,
&&:
print "Looking for my files that are readable and writable\n";
die "No files specified!\n" unless @ARGV;
foreach my $file ( @ARGV ) {
print "$file is readable and writable\n"
if( w $file && r _ && o _ );
}

330

13
1. :
print "Which directory? (Default is your home directory) ";
chomp(my $dir = <STDIN>);
if ($dir =~ /^\s*$/) {
# A blank line
chdir or die "Can't chdir to your home directory: $!";
} else {
chdir $dir or die "Can't chdir to '$dir': $!";
}
my @files = <*>;
foreach (@files) {
print "$_\n";
}

Q
, chomp (
chomp , Q
; UNIX ,
chdir ).
, , Q
; . Q
, .
, <*> Q
, . Q
print.
2. :
print "Which directory? (Default is your home directory) ";
chomp(my $dir = <STDIN>);
if ($dir =~ /^\s*$/) {
#
chdir or die "Can't chdir to your home directory:
$!";
} else {
chdir $dir or die "Can't chdir to '$dir': $!";
}
my @files = <.* *>;
foreach (sort @files) {
print "$_\n";
}

## .*
##

: Q, Q
.*, ,
. Q, Q
, , ,

.

331

3. :
print "Which directory? (Default is your home directory) ";
chomp(my $dir = <STDIN>);
if ($dir =~ /^\s*$/) {
#
chdir or die "Can't chdir to your home directory:
$!";
} else {
chdir $dir or die "Can't chdir to '$dir': $!";
}
opendir DOT, "." or die "Can't opendir dot: $!";
foreach (sort readdir DOT) {
# next if /^\./; ##
print "$_\n";
}

, Q
, Q
. Q
, DOT.
DOT ( )? Q
(, /etc), .
,
(, fred). chdir fred,
opendir.
fred , .
. ( ,
UNIX ).
readdir . Q
. Q
,
; Q
foreach.
, :
chdir? readdir Q
, . ,
Q
.

. ,
,
.
4. :
unlink @ARGV;

Q
:

332

A
foreach (@ARGV) {
unlink $_ or warn "Can't unlink '$_': $!, continuing...\n";
}

$_ Q
unlink. Q
, , .
5. :
use File::Basename;
use File::Spec;
my($source, $dest) = @ARGV;
if (d $dest) {
my $basename = basename $source;
$dest = File::Spec>catfile($dest, $basename);
}
rename $source, $dest
or die "Can't rename '$source' to '$dest': $!\n";

Q
, Q
.
. $dest Q
, $source Q
($dest). $dest Q
, rename .
6. :
use File::Basename;
use File::Spec;
my($source, $dest) = @ARGV;
if (d $dest) {
my $basename = basename $source;
$dest = File::Spec>catfile($dest, $basename);
}
link $source, $dest
or die "Can't link '$source' to '$dest': $!\n";

, Q
. : rename Q
link.
, :
print "Would link '$source' to '$dest'.\n";

7. :
use File::Basename;
use File::Spec;

333

my $symlink = $ARGV[0] eq 's';


shift @ARGV if $symlink;
my($source, $dest) = @ARGV;
if (d $dest) {
my $basename = basename $source;
$dest = File::Spec>catfile($dest, $basename);
}
if ($symlink) {
symlink $source, $dest
or die "Can't make soft link from '$source' to '$dest': $!\n";
} else {
link $source, $dest
or die "Can't make hard link from '$source' to '$dest': $!\n";
}

( use) Q
. s, , Q
,
$symlink. s
.
. ,
$symlink (Q
). ;
, Q
.
8. :
foreach (<.* *>) {
my $dest = readlink $_;
print "$_ > $dest\n" if defined $dest;
}

,
, $_.
, readlink Q
, .
, .

14
1. :
my @numbers;
push @numbers, split while <>;
foreach (sort { $a <=> $b } @numbers) {
printf "%20g\n", $_;
}

334

, ?
. ,
, 1,
. Q Q
.
while, Q
:
while (<>) {
push @numbers, split;
}

, . while Q
( , ,
<>), split
, Q
. , ,
. Q
, while @numbers.
foreach Q
, %20g Q
. Q
%20s. ? Q
, Q
. ,
1.50 1.5, 04 4?
,
%20g Q
. ,
, .
2. :
# %last_name
#
my @keys = sort {
"\L$last_name{$a}" cmp "\L$last_name{$b}" #
or
"\L$a" cmp "\L$b"
#
} keys %last_name;
1

, ,
.
Q Q
, , .
Q
, Perl Mongers. Q
JAPHQ , Q
.

335


foreach (@keys) {
print "$last_name{$_}, $_\n";
}

# Rubble,BammBamm

:
, . QQ
Q ( Q
).
3. :
print "Please enter a string: ";
chomp(my $string = <STDIN>);
print "Please enter a substring: ";
chomp(my $sub = <STDIN>);
my @places;
for (my $pos = 1; ; ) {
# for
$pos = index($string, $sub, $pos + 1); #
last if $pos == 1;
push @places, $pos;
}
print "Locations of '$sub' in '$string' were: @places\n";

: Q
,
. for ,
;
, Q
. , ,
,
, .
$pos Q
for 1. ,
. Q
for ,
. (, Q
last.)
,
$pos + 1. , ,
$pos 1, 0
( ). Q
$pos. 1, , last
. 1,
@places, .
$pos + 1 , ,
.
.

336

for, Q
:
{
my $pos = 1;
while (1) {
... #
}
}

$pos.
, ,
. Q
,
, ,
$pos . ,
,
, Q
. ,
$substring_position.
,
( !), Q
( !):
for (my $pos = 1; 1 !=
($pos = index
+$string,
+$sub,
+$pos
+1
);
push @places, ((((+$pos))))) {
'for ($pos != 1; # ;$pos++) {
print "position $pos\n";#;';#' } pop @places;
}

for Q
. ,
Q
, Q
. , .
, t This is a test.? Q
10 13. 0 ; Q
, .

15
1. Q
10. Q
, given:

337


use 5.010;
my $Verbose = $ENV{VERBOSE} // 1;
my $secret = int(1 + rand 100);
print "Don't tell anyone, but the secret number is $secret.\n"
if $Verbose;
LOOP: {
print "Please enter a guess from 1 to 100: ";
chomp(my $guess = <STDIN>);
my $found_it = 0;
given( $guess ) {
when( ! /^\d+$/ )
{ say
when( $_ > $secret ) { say
when( $_ < $secret ) { say
default
{ say
}

"Not a number!" }
"Too high!" }
"Too low!"
}
"Just right!"; $found_it++ }

last LOOP if $found_it;


redo LOOP;
}

when , . Q
, ,
, Q
.
: last default. Q
,
Perl 5.10.0 (, Q
).
2. :
use 5.010;
for (1 .. 105) {
my $what = '';
given ($_) {
when (not $_ % 3) { $what .= ' fizz'; continue }
when (not $_ % 5) { $what .= ' buzz'; continue }
when (not $_ % 7) { $what .= ' sausage' }
}
say "$_$what";
}

3. :
use 5.010;
for( @ARGV )
{

338

A
say "Processing $_";
when(
when(
when(
when(
}

! e
r _
w _
x _

)
)
)
)

{
{
{
{

say
say
say
say

"\tFile does not exist!" }


"\tReadable!"; continue }
"\tWritable!"; continue }
"\tExecutable!"; continue }

given, when Q
for. , Q
( , ).
when , , Q
break Q
. when ,
, r.
_, Q
stat (, Q
). _
, . when
continue, when
.
4. , given Q
:
use 5.010;
say "Checking the number <$ARGV[0]>";
given( $ARGV[0] ) {
when( ! /^\d+$/ ) { say "Not a number!" }
my @divisors = divisors( $_ );
my @empty;
when( @divisors ~~ @empty ) { say "Number is prime" }
default { say "$_ is divisible by @divisors" }
}
sub divisors {
my $number = shift;
my @divisors = ();
foreach my $divisor ( 2 .. $number/2 ) {
push @divisors, $divisor unless $number % $divisor;
}
return @divisors;
}

, ;
. $ARGV[0] Q
,
.

339

given when,
. when ,
; Q
, .
, Q
, . when Q
break, given.
, divisors().
given, Q
(,
'Fred'), Perl . Q
, when
.
,
@divisors . , Q
Q
, Q
. ,
, , Q
. @empty,
. @divisors Q
Q
. , when,
break.
, , de
fault, .
, Q
, InterQ
mediate Perl1: @divisors Q
,
.
:
when( @divisors ~~ [] ) { ... }

5. , Q
:
use 5.010;
say "Checking the number <$ARGV[0]>";
my $favorite = 42;
given( $ARGV[0] ) {
when( ! /^\d+$/ ) { say "Not a number!" }

, Perl: . .
. .: Q, 2007.

340

A
my @divisors = divisors( $ARGV[0] );
when( @divisors ~~ 2 ) { # 2 is in @divisors
say "$_ is even";
continue;
}
when( !( @divisors ~~ 2 ) ) { # 2 isn't in @divisors
say "$_ is odd";
continue;
}
when( @divisors ~~ $favorite ) {
say "$_ is divisible by my favorite number";
continue;
}
when( $favorite ) { # $_ ~~ $favorite
say "$_ is my favorite number";
continue;
}
my @empty;
when( @divisors ~~ @empty ) { say "Number is prime" }
default { say "$_ is divisible by @divisors" }
}
sub divisors {
my $number = shift;
my @divisors = ();
foreach my $divisor ( 2 .. ($ARGV[0]/2 + 1) ) {
push @divisors, $divisor unless $number % $divisor;
}
return @divisors;
}


.
@divisors
. 2, Q
, .
, continue
when.
. , Q
, .

341

16
1. :
chdir "/" or die "Can't chdir to root directory: $!";
exec "ls", "l" or die "Can't exec ls: $!";

Q
. exec Q
.
,
.
2. :
open STDOUT, ">ls.out" or die
open STDERR, ">ls.err" or die
chdir "/" or die "Can't chdir
exec "ls", "l" or die "Can't

"Can't write to ls.out: $!";


"Can't write to ls.err: $!";
to root directory: $!";
exec ls: $!";

STDOUT STDERR
( ). ,
chdir, ,
, .
die? ,
ls.err , STDERR. Q
die chdir . Q
, STDERR
? STDERR.
STDIN,
STDOUT STDERR ,
.
3. :
if (`date` =~ /^S/) {
print "go play!\n";
} else {
print "get to work!\n";
}

(Saturday Sunday) Q
S, date
, :
date , S. Q
, ;
.
,
/^(Sat|Sun)/. , ;
, Q
.

342

17
1. :
my $filename = 'path/to/sample_text';
open FILE, $filename
or die "Can't open '$filename': $!";
chomp(my @strings = <FILE>);
while (1) {
print "Please enter a pattern: ";
chomp(my $pattern = <STDIN>);
last if $pattern =~ /^\s*$/;
my @matches = eval {
grep /$pattern/, @strings;
};
if ($@) {
print "Error: $@";
} else {
my $count = @matches;
print "There were $count matching strings:\n",
map "$_\n", @matches;
}
print "\n";
}

eval , Q
. grep Q
.
eval ,
.
, chomp : map
.

B
,
, .
, Perl,
, . Q
Perl,
, , Q
. , Q
. Q
, , Q
. Q : Perl
X, Y, .
, ( Q
): , Q
, Intermediate Perl1 (OReilly),
. Q
, Q
100 ( ).
MasterQ
ing Perl, . Q
Perl,
, Q
. , Q
, .


, Perl,
. ,
1

, Perl: . .
. .: Q, 2007.

344

.
perltoc () perlfaq (
). perldoc Q
Perl, Q
( perldoc). Q
http://perldoc.perl.org, Q
Perl.


, . MasterQ
ing Regular Expressions1 (Jeffrey Friedl) (OReilly)
, .2
,
Perl. Q
,
, Q
. , Q
Perl, . . manQ
perlre ( perlretut perlrequick
Perl). Q
.

3 .
, 10 Q
. $fred, @barney, %betty
&wilma , , Q
?
; Q
$fred, , , . Q
Perl Q
. .

, 3Q . . .
.: Q, 2008.
, OReilly. Q
.
, : Q

( Perl ). Q
( $fred
&wilma). .

345

Perl
Perl Q
: . ,
.
.
Perl, CPAN.
,
.

, Perl,
. ( )
, Q
. Perl , .

. , Q
, Q
, Q
. , Q
,
.
Q
.
Perl;
, C. , MD5
Q
.1 Q
, Perl, 2;
C.
Digest::MD5 C.
, , Perl
MD5.

1
2

, .
Digest::Perl::MD5 MD5 Q
Perl. , Q
280 , Digest::MD5 (, Q
). ,
C ; Q
,
. Perl , .

346


, .
, ?
inside, CPAN http://
www. cpan.org/authors/id/P/PH/PHOENIX/.
, ,
, Perl CPAN http://search.
cpan.org/. Q
manQ perlmodinstall.

use. ,
, ,
.


,
,
Perl ( C). Q
manQ perlmod perlmodlib. ,
, ,
.


1 Q
.2 , ,
Perl ( ). Q
CPAN.

CGI
Perl , Q
Q ( CGI).
CGI Perl. 11;
.

Q
; Q
.
, , Q
, Q
Perl.

347

Cwd
.
(, ., ,
Q
.) Cwd, Perl, cwd
:
use Cwd;
my $directory = cwd;

Fatal
"or die" open chdir,
, Fatal . , Q
, Q
,
"or die" .
Fatal (, Q
), Fatal
. Q
, ,
. :
use Fatal qw/ open chdir /;
chdir '/home/merlyn'; # "or die"

File::Basename
11. Q

:
use File::Basename;
for (@ARGV) {
my $basename = basename $_;
my $dirname = dirname $_;
print "That's file $basename in directory $dirname.\n";
}

File::Copy
,
File::Copy . ( Q
, .) Q
, Q
, :

348

B
use File::Copy;
copy("source", "destination")
or die "Can't copy 'source' to 'destination': $!";

File::Spec
( Q
, ), ,
File::Spec, Q
, . ,
catfile ,
(. 11), , Q
, ,
. curdir Q
(. UNIX).
File::Spec Q,
, . Q
( )
File::Spec >:
use File::Spec;
my $current_directory = File::Spec>curdir;
opendir DOT, $current_directory
or die "Can't open current directory '$current_directory': $!";

Image::Size

. (, ,
HTML, IMG .)
Image::Size, CPAN, Q
GIF, JFIF (JPEG) PNG, .
:
use Image::Size;
# fred.png
my($fred_height, $fred_width) = imgsize("fred.png");
die "Couldn't get the size of the image"
unless defined $fred_height;

Net::SMTP
, Q
SMTP (
), Net::SMTP.1
1

, , Perl . Q
, .

349

, CPAN, Q
, ,
. SMTP Q
, . ,
, Q
. :
use Net::SMTP;
my
my
my
my

$from = 'YOUR_ADDRESS_GOES_HERE';
# , fred@bedrock.edu
$site = 'YOUR_SITE_NAME_GOES_HERE';
# , bedrock.edu
$smtp_host = 'YOUR_SMTP_HOST_GOES_HERE'; # , mail mailhost
$to = 'president@whitehouse.gov';

my $smtp = Net::SMTP>new($smtp_host, Hello => $site);


$smtp>mail($from);
$smtp>to($to);
$smtp>data( );
$smtp>datasend("To: $to\n");
$smtp>datasend("Subject: A message from my Perl program.\n");
$smtp>datasend("\n");
$smtp>datasend("This is just to let you know,\n");
$smtp>datasend("I don't care what those other people say about you,\n");
$smtp>datasend("I still think you're doing a great job.\n");
$smtp>datasend("\n");
$smtp>datasend("Have you considered enacting a law naming Perl \n");
$smtp>datasend("the national programming language?\n");
$smtp>dataend( );
$smtp>quit;

# datasend!

POSIX
, POSIX (IEEE Std 1003.1),
POSIX. ,
C: (asin, cosh),
(floor, frexp), (isupper, isalpha),
/ (creat, open) (asctime,
clock). , ,
POSIX :
use POSIX;
print "Please enter a number: ";
chomp(my $str = <STDIN>);
$! = 0; #
my($num, $leftover) = POSIX::strtod($str);
if ($str eq '') {
print "That string was empty!\n";
} elsif ($leftover) {

350

B
my $remainder = substr $str, $leftover;
print "The string '$remainder' was left after the number $num.\n";
} elsif ($!) {
print "The conversion function complained: $!\n";
} else {
print "The seeminglyvalid number was $num.\n";
}

Sys::Hostname
Sys::Hostname hostname, Q
, .
( ,
, Q
; or die Q
.) :
use Sys::Hostname;
my $host = hostname;
print "This machine is known as '$host'.\n";

Text::Wrap
Text::Wrap wrap, Q
. Q
; Q
:
use Text::Wrap;
my $message = "This is some sample text which may be longer " .
"than the width of your output device, so it needs to " .
"be wrapped to fit properly as a paragraph. ";
$message x= 5;
print wrap("\t", "", "$message\n");

Time::Local
(, time) Q
, , , , , ,
Perl localtime
1 ( Q
, ).
Q
, timelocal
Time::Local. : 2008 $mon
$year 3 2008, ;

localtime Q
; . .

351

,
. :
use Time::Local;
my $time = timelocal($sec, $min, $hr, $day, $mon, $year);

(pragmas) ,
Perl Q
Perl . strict.
, Perl, manQQ
perlmodlib.
, , Q
use. Q
(my) , ,
.
. (
, .)
Q
. Q
.

constant
, ,

. ,
Q
. Perl constant Q
. , Q
, , Q
. :
use constant DEBUGGING => 0;
use constant ONE_YEAR => 365.2425 * 24 * 60 * 60;
if (DEBUGGING) {
# ,
# DEBUGGING
...
}

diagnostics
Perl ,
. ,
, manQ perldiag; Q
.

352

manQ, Q
diagnostics, Perl Q
. Q
, Q
,
perldiag (
). diagnostics
, .
. :
use diagnostics;

lib
,
,
. Q
,
Perl , ? lib. Q
Perl, .
( , Q
.)
, . :
use lib '/home/rootbeer/experimental';

: .
,
.
CGI ( , Q).

strict
use strict, Q
, .
Q
. , use strict
Perl, . Q
, strict.

vars
, Q
use strict, Q
vars.1

Perl 5.6, Q
our vars.

353

Perl, Q
:
use strict;
use vars qw/ $fred $barney /;
$fred = "This is a global variable, but that's all right.\n";

vars .

warnings
Perl 5.6
warnings.1
, Q
w, , Q
, Q
,
. , Q
: , Q
, . ,
Perl, warnings.


Perl . Q
. DBI
11.


Perl ,
.
Windows ( Q
), UNIX (
IPQ , ).


, (Q
) , Perl , Q
Q, Q
.

Perl 5.6, Q
warnings.

354


, , Q
: .. Q
,, wantarray goto (!), caller chr. manQ
perlop perlfunc.

tr///
tr/// , Q
.
, Q
. manQ perlop.


(here documents) Q
; . manQ perldata.

Perl Q
, .


( , ,
, ) Q
;
manQ perlfunc. (,
) ,
,
. ( Q
POSIX.)


Perl,
. Q
, Q
* sqrt Q
. . Math::Complex.


Q
. , Q
2000 10 000 .
. Math::BigInt Math::BigFloat.

355


Perl , Q
.

map grep
map grep (.
17). ; Q
manQ perl
func. map grep
.

splice
splice
. ( Q
, substr
.)
Perl. . manQ perlfunc.


vec ( ): Q
, 123, Q
456 789.
. vec
, , Q
2. . manQ perlfunc.

Perl Q
Q
. , , Q
Perl
. , , Q
. , Q
, , Q
. Q
, . ,
, , , , , 
, .
. manQ perlform.

356

IPC
, Q
, Perl, , Q
. Q
.

System V IPC
Perl System V IPC (InterproQ
cess Communication); , Q
. , Perl
, C1, Q
Perl . Q
, , Q
Perl . . manQ
perlfunc perlipc.

Perl TCP/IP. ,
Perl Q ,
Usenet, finger, FTP, Q
SMTP/POP/SOAP, Q
,
. , Q
; Q
. , Q Q
LWP Q .2
LWP ( , Q
Web)
Perl,
. Q
, ,
.

, Perl Q
, Q
.
LWP Q Q
, Q
. X11
Tk Gtk,
curses. Q
CPAN.

357

Perl , Q
, Perl, Q
, C. ,
, taintQ.
Perl ,
( , Q
).
, , Perl
. TaintQ
,
, . Q
manQ perlsec.

Perl Q
, ,
,
Perl . Perl (Q
, ?). ,

Perl ( , Q
) Q
. manQ perl
debug. .
B::Lint.
,
w.

CGI
Q Perl Q
CGI (Common Gateway Interface).
Q , Q
, Q Q
Q.
CGI, Perl, Q
HTML. Q
, Q
, Q
,

358

.1 CGI Q
, Q
.
, ,
, . Q

CGI.

, , Q
1 2% Q
, .2
, Q
. ,
.3

CGI , ,
.
, ,
, . Q
, ,
, .
URI, HTMLQQ
(HTMS entities), HTTP , SSL (Secure Sockets
Layer), SSI (ServerQSide Includes), ,
, HTML,
, , cookies, Q
, , , taintQ, Q
, Perl HTML ( Q
1

, , ,
CGI Q
. ,
. Q
CGI ( ) , , 50%.
,
. , ,
Q ,
.
, , Q
, .

359

), Apache mod_perl LWP.1


Q
Perl. CGI Programming with Perl2 Q
(Scott Guelich) . (OReilly), Network ProgramQ
ming with Perl (Lincoln Stein) (AddisonQWesley).


Perl
; Q
. . manQ perlrun.


Perl ( @ARGV and $0) Q
Perl.
. manQ perlvar.


Perl , Q
, continue BEGIN. . manQQ
perlsyn perlmod.

Perl C,
Pascal Ada.
; Perl Q
, Q
, ,
.
Q
. . manQ perlreftut perlref.
.


Perl.
3
1

,
?
. CGIQ Perl, 2Q . .
. .: Q, 2001 ( ).
, , , Q
, .

360

,
.1 . manQ perldsc perllol. , Q
(, . .) Q
.

)
, Perl , Q
. QQ

, , Q
.2 Q
Q , Perl Q
. ( Q
, .)
N , , Q
QQ
( , ).
N; , Q
. manQ perlobj
perlboot, Q
(Damian Conway) ObjectQOriented Perl
( Manning Press). Q
.


, Q
. Q
Q
.
(closures) Perl Lisp. Q
( )
. Q
.


(tied) ,
, Q
. , ,
1

. ,
, Perl .
Q .
, Q
.

361

,
, . .
manQ perltie.


overload Q
, ,
. , Q
( )
8 .


: Q
, Q
, . Q
.
Perl , Q
.1 Q
, Perl.

(embedding) Q
.
,
, C++.2 Q , Q

Perl ,
Perl. ,
Perl .
, Perl , Q
.
Q ,


, Q
.
, Perl Q
.
, . ,
Perl, Q
. X , Q
X. , X = Perl.

362

Perl. Q
, . Q
Q
.
? Q
Perl. .
.
,
.
Apache mod_perl,
Perl Q. Q
Perl, mod_perl;
, , .

Perl
sed awk,
Perl? , . Perl ,
. , Q
, , , .
s2p ( sed) a2p (
awk1). , , Q
, ,
, , ,
. Q
, Q
.
Perl , Q
, .
Perl C? , Q
: C ,
Perl. , Q
, .
manQ perlxs, Inline
SWIG.
Perl ?
.
Perl . , Q
;
. , Q
1

gawk, nawk , a2p


Perl. Q

Perl.

363

, system ,
Q
. , Q
cut, rm, sed, awk grep
Perl. .

find Perl
Q
. UNIX Q
find. ,
Perl.
find2perl Perl ,
find. ,
find2perl Perl . Q
,
. ( , Q
.)
find2perl eval,
find. Q
, Perl
.
, ,
$_ .
find2perl. ,
UNIX Q
/tmp.1 Q
:
$ find2perl /tmp atime +14 eval unlink >Perlprogram

/tmp ( Q
) , Q
14 . Q
Perl unlink, Q
$_ .
find2perl ( PerlQprogram)
, . Q
.

cron .

364



, Q
(
Perl, w), ,
. .
Getopt::Long GetOpt::Std.


Perl pod (PlainQOld
Documentation).
, HTML
. . manQ perlpod. Q
.

Perl
; . manQ perlopentut.


, . Q
, , Perl Q
(locales) .
Perl, Q
. , Q

? ? . manQ perllocale
( perllocal).
, Perl
, manQ perlunicode. Q
Perl ,
, , Q
.


Perl (threads).
( Q
), .

365

fork (, )
; . manQ perlfork perlthrtut.

(GUI)
Tk Q
, .
. Mastering Perl/Tk (Nancy Walsh) (SteQ
ve Lidie) (OReilly).


CPAN,
:
, Q
. CPAN Q
, Perl
, .
, .
, Perl
Perl .

, Perl , , . Q
, !


Q (),
, 146
/ ( )
//, , 202
, 140
, 150
Q ()
QQ (), 190
, 42
\ ( )
, 142
, 44, 140, 278
! ( )
!=, , 55
, 57
" " ()
, 156
, 43
# (), , 34
#!, , 35
$ ()
$!, , 116
$$, , 248
$&, , 163
$', , 163
$^I, , 180
$_, , 72, 270
$`, , 163
$1, $2, , 157
, 48
, 304
, 303
, 136
, 153, 165
% ()
printf, 107
, 128

, , 42, 297
, 305
%d, , 108
%ENV, , 136, 282
%f, , 108
%g, , 108
%s, , 108
& ()
&& ( ), 201
, 80
, 229
, 93
' ' ()
, 43
, 278
( ) ( )
, 142
(?:), 159
, 165
, 159
* ()
** ( ), 50
*? ( ),
178
, 141
, 42
+ ()
++ (), 190
+? ( ),
178
, 142
, 42
, (), 131
. ()
. .. , 236,
241
.*, , , 234
./, , 33
.., , 65

367


.= ( ),
50
/s
, 151

, 141
, 45
; ( )
, 35
, 86
< (), , 55, 273
<< ( ),
, 229
<= ( ), , 55
<=>, , 259
<>, , 100
print, 105
@ARGV, 102
, 181
= ( )
== (), , 55
=~ ( ), 155, 171
substr, 254
=> ( ), 131
? ( )
?: ( ), 200
??, ,
178
, 205
, 142
@ ( at)
, 70
, 303
, 67
, 136
, 305
@ARGV, , 102
[ ] ( )
, 71
, 303
, 146
^ ()

, 146
, 229
, 153, 165
_ ()
, 90
,
224
`` ( ), 38

, 285
, 283
{ } ( )
{ }?,
, 178
m//, , 151
, 304
, 56
, 80
, 164
, 127
, 52
| ( )
, 145, 165
, 286
, 229
|| ( ),
, 201
~ ()
~~, , 265
, 229
> ()
, 55, 273
, 112
Q> ( ), 214
>= ( ), , 55
>> ( ),
, 229

A
ACL (Access Control Lists), 220
ActiveState Perl, 209
and, , 205
Apache, Q, mod_perl, 362
ARGV, 110
ARGVOUT, 110
ASCII
, 32
, 73

B
b, 154
\B ( ), 155
basename, , 211
Bourne Shell, 279
Build, , 208

C
C Shell, 280

368
C, , 28
switch, , 269
, 200
C Perl, 362
, 205
cat, , 100
cd, , 232
CGI (Common Gateway Interface), 357
, 346
, 27
CGI.pm, , 214
chdir, , 232
chmod
, 33
, 248
chomp
, 58

, 78
chown, , 249
cmp, , 263
comp.lang.perl*, , 30
connect, ( DBI), 216
constant, , 351
continue, , 271
ControlQD,
Unix, 77
ControlQZ, WinQ
dows, 77
CPAN (Comprehensive Perl Archive NetQ
work), 28, 207
cpan, , 209
CPAN.pm, , 209
ctime, , 249
Cwd, , 347

D
\D,
, 148
\d,
, 146
DATA, 110
date, , 180, 277
DBI (Database Interface), , 216
defined, , 60, 249
delete, , 135
diagnostics, , 47, 352
die, , 115
dirname, , 211

E
each, , 132
echo, , 233
else
, 56
unless, , 185
, 185
elsif, , 189
emacs, 32
eval
, 342
, 294
exec, , 281
exists, , 135

F
Fatal, , 347
File, 210, 211, 213, 237, 248, 347, 348
find, (Unix), 363
find2perl, , 363
for, , 192
last, 195
foreach, 194
foreach
givenQ
when, 274
, 71
, 71
last, 195

G
/g,
m//, 175
s///, 170
getgrnam, , 249
getpwnam, , 249
givenQwhen, , 269
glob, , 234
unlink, 238
gmtime, , 228
grep
, 138
, 355
, 297

H
\h,
, 147

369


Haskell, Perl 6 (Pugs), 26
hostname, , 350
HTML, 215

next, , 196

oct, , 247

/i, , 151
Qi, , 182
if
, 55, 184
, 186
ifQelseifQelse, , 270
Image, 348
index, , 252
substr, 254
IPC (InterProcess Communications), 356

J
join, , 174

K
keys, , 131

L
\L, , 172
last, , 195
lib, , 352
link, , 242
localtime, , 180, 228, 350
lstat, , 228
LWP, , 356

M
m//, , 150
, 174
MakeMaker, , 208
map, , 298, 355
mkdir, , 246
mod_perl, (Apache), 362
Module, 208
my
, 89
, 219
, 270

N
Qn, , 182
Net, 348

Qp, , 182
Parrot (), 26
Perl
, 35
, 20
, 36
, 28
, 362
, 26
, 37
, 31
, 29
, 27
Perl 5 Porters, 26
Perl Mongers, 31
Perl Package Manager (PPM), 209
perldoc, 37, 208, 344
perlfaq, 344
pop, , 69
POSIX, , 349
print
, 33
, 50
, 104
printf
, 107
, 109
Pugs, 26
push, , 69

Q
qw (), , 65
qw, , 65

R
\R, ,
147
readdir, , 236
readline, , 236
readlink, , 246
redo, , 197
rename, , 239

370
reverse, , 72

, 75
, 260
rindex, , 253
rmdir, , 247
rmtree, , 248

S
s/// (), , 169
s///,
=~ ( ), 171
/g , 170
, 171
, 172
\S,
, 148
\s
, 151

, 147
say, , 33
say, , 120
shift, , 69
sort
, 100
, 73
, 75
splice, , 355
split, , 172
sprintf, , 256
stat, , 226
STDERR, 111
STDIN
, 57
, 77
undef, 60
STDOUT, 110
stty, , 77
sub, , 80
substr, , 253
switch/case, , 189
symlink, , 244
Sys, 350
System V IPC, 356
system, , 277

T
Text, 350
Time, 350


time, , 229, 249
timelocal, , 350
Tk, , 365
tr///, , 354

U
\U, , 172
undef, , 59
, 64
, 76
, 61
Unix
#!, , 35
, 241

, 32
unless, , 184
unlink
, 247
, 246
unshift, , 69
until, , 185
use, , 211
use strict, , 90, 352
use warnings, , 107
Usenet, , 30
utime, , 249

V
\v, ,
147
values, , 131
vars, , 352
vec, , 355
vi, 32

W
Qw, , 107, 114
Qw, , 182
\W, ,
148
\w, ,
147
warnings, , 114, 353
Web, Perl, 27
when,
given, 269
, 274
while, , 59, 188

371


while,
last, 195
Windows
Ctrl+Z, , 77

X
x ( ), , 45, 109
/x, , 152

(QQ), 190
(++), 190
, 87
, 360
, , 43

, 100
, 84
, 100
, 54
,
, 166

, 209
Q, 37
, , 227
, 357
CGI, , 358
, 193
, 345
, 230
, Perl, 30

, 199
Perl, 196
(=>), 131, 300
, 354
, 105

, 98
/
print, 50
say, 120
warn, 117

, 114


, 119
, 77
printf, 109
<>, 100
, 314
, 111

, 57

, 283
, 98
, 103
, 109

printf, 107
Q, 357
Q, 30
, 288
, 364
, 40
, 108
, , 249
, 37
, 354
, , 42
, 82
, 227
, 249
, 228

,
, 75
, 25
, 195

,
81
, 233
, 365
, 142
, 225
, 30

,
(CSV), 65
, 222
, sprintf, 255

372
, 236
( . .), 65, 94
, 361
, 30
, 343
, 364
perldoc, 37
, 208
, 233

, 228

, , 361
, 360
(,), (=>), 131

, 109
, 80
, 241
, 227

, 63
, 254
, 64

, 156

, 135
, , 51

Parrot, 26
perl, 22
, 36
Perl, 20
, 33
, 71

, 109
, 232
, 208
, 233
, 236
, 248



, 210
, 330
, 239
, 232
, 237
, 249
, 246
, 241
, 238
, 141
, 175
, 175
, 164
, 165
(Unix), 287

CPAN.pm, 209
, 181

, 139
, 279
, 136
, 232
, 37
(), , 38
, 34
qw, , 66
, 152
, 36
, 354
, 98
, 77
, 73

, 76
,
, 77

, 89

, 40
, 41
, 65
, 42
, 41
Perl, 28
, 56, 132
, 201

373


//, 202
and, 205
or, 205
, 205
, 201
, 364

(Q>), 214
, 62
printf, , 109
( ), 355
, ,
310
, 70, 104
, 69
, 121
, 96
, 63
, 64
, 266
, 302
, 67
, 354
, 140
, 279
, 165
, 199
, 214
, 186
, 94, 207, 345
CGI, 346
CGI.pm, 214
CPAN, 365
Cwd, 347
DBI (Database Interface), 216
Fatal, 347
File, 210, 213, 347, 348
Image, 348
Net, 348
POSIX, 349
Sys, 350
Text, 350
Time, 350
, 326
, 207
, 208
, 211
, 244

, 150

, 89
my, , 219
,
188
, 169

, 322
, 142
, 166
Q
, 360
Q , 213

, 150
, 256

chomp, 58
, 50
, 201
, 361
, 229
, 60
, 52
, 218
, 54
, 45
(?:), 200
, 42

#!, , 35
Perl, 28
, 210
, 136
, 232
, (%), 42
, 357
, 144
, 38
, 29
(eval), 294
, 31
(STDERR), 111
(die), 115

374

, 344
, 359
, 364
, 361
, 48
$_, 72
use strict, 90
, 359
, 49
, 89
, 188
, 35
, 360
, 48
, 136, 282
, 353
, 204
, (x), 45
, Perl, 29
, 80

substr, 253
, 253
, 252
, 229
Perl, 28
, 20
, 191
, 191
, 351
diagnostics, 47
strict, 95
warnings, 47, 114

Perl, 46

(printf format string), 107


, , 289
, 190
, 190
, (=~), 155, 171
substr, 254

, 52, 205
, 268

, 165
, 49
, 50


, 76
, 130
, 67
, 129

localtime, , 228
lstat, , 228
stat, , 226
, 225
, 327
, 229
, 223
, 219
, 364

\s, , 147
, 147
, /x, 152
, 170
Perl 5.10, 147
, 170
, 188
last, 195
, 94
, 277
system, 277
, 288
, 286
, 341
, 289
, 278
, 69
, 51, 154

(), 227
, 219
$mode, , 227
, 147
, 147
, 129
, 345

Perl, 359
, 33

, 49
, 55
, 139
join, , 174


m//, 174
s///, 169
split, , 172
, 139
, 167
, 344
, 160
, 156
, 141
, 175
, 151
, 159
(=~), 155
, 319
, 146
, 167
, 265
,
162
, 153
, 242

, 360
, 356
, , 289
, 244
, 246

\n, 36
, 148
, 117
, 103
chomp, 58
, , 166
, 146
, 166
, 146
, 353
, 39
, 94
, 51
, 307
, 48

, 52
, 49
, 39
, 74
, 75

375
, 77
, 241
, 356
, 258
, 258
, 261
, 262
, 159
, 62
, 212
, 65
,
, 310
grep, 297

, 86
, 88
, 30

, 129
map, 298
, 74
m//, 174
, 94
, 285
, 76
, 303
, 300
, 302
, 300
, 304
, 242, 359
, 227
, 244
, 246

(STDIN), 110
(STDOUT), 110
(STDERR), 111
, 95
, 42, 252
, 230
, 43
, 63

, 70
, 51
, 303
, 305
, 123
, 43

376
, 43
, 67
, 45
, 55
, 46
, 172
, 174
, 258
, 55
sprintf, 256

qw, , 66
, 70

, 70

, 136
, 172

, 195
, 359
, 242

, 32
, 222
, 32
, 33
, 81
(?:), 200
, 131

, 265

, 272
(~~), 265
, 337
, 267
, , 25
, 195
last, 195
next, 196
redo, 197
, 184
elsif, , 189
for, 192
givenQwhen, 269
unless, 184
until, 185


, 201
, 199
, 186
, 324
, 188
foreach for, 194
(?:), 200
, 195

, 109
, 364
, 114
, 111
, 286
, 119
print printf, 118

, 239
, 151
, 278
, 355

, 188
, 354
, 131

, 211

, 123
%ENV, 136
=> ( ), 131
, 135
, 96
, 128
, 123
, 123
, 316
, 125
, 129

, 261
, 262
, 304
, 134
, 131

, 41
, 40
, 38, 59, 71

, 39
, 46
, 63
, 40
, 40
, 41
, 54
printf, 108
, 41
, 354
, 42

, 139


Net, 348
, , 62
, 228

, 364

,
Perl, 362

, 154
, 153
, 165

377

 
Books.Ru
ISBN 9785932861547,
Perl, 5 
Book.Ru . 
,

. , 
 (piracy@symbol.ru), 
.