You are on page 1of 354

Hc

Perl


Randal L. Schwartz

Ngi dch: Ng Trung Vit






H Ni 5/1999







Learning
Perl


Randal L. Schwartz









OReilly & Associates, Inc., 1993



i


Mc lc


1 Gii thiu .................................................................. 1
Lch s Perl ................................................................. 1
Mc ch ca Perl ....................................................... 3
Tnh sn c .............................................................. 3
H tr ...................................................................... 5
Cc khi nim c bn .................................................. 6
Do qua Perl ................................................................ 9
Chng trnh Xin cho mi ngi .................... 10
Hi cu hi v nh kt qu ................................... 11
B sung chn la .................................................. 12
on t b mt ...................................................... 13
Nhiu t b mt ..................................................... 14
Cho mi ngi mt t b mt khc nhau .............. 16
Gii quyt dng thc ci vo thay i .................. 19
Lm cho cng bng vi mi ngi ....................... 21
Lm cho n m un hn mt cht ........................ 24
Chuyn danh sch t b mt vo tp ring bit ..... 28
m bo mt lng an ton gin d ...................... 33
Cnh bo ai khi mi vic i sai ........................ 34
Nhiu tp t b mt trong danh mc hin ti ........ 36
Nhng chng ta bit h l ai! ................................ 38
Lit k cc t b mt .............................................. 40



ii
Lm cho danh sch t c ng lu hn ........ 44
Duy tr c s d liu on ng cui cng ........... 45
Chng trnh cui cng ........................................ 48
Bi tp ....................................................................... 51
2 D liu v hng .................................................... 53
D liu v hng l g? ............................................ 53
S .......................................................................... 54
Tt c cc s c cng dng thc bn trong ...... 54
Hng k hiu ng ................................................. 54
Hng k hiu nguyn ............................................. 55
Xu ............................................................................ 56
Xu du nhy n ................................................. 56
Xu du nhy kp ................................................. 57
Ton t ...................................................................... 59
Ton t s ............................................................. 59
Ton t xu ........................................................... 61
Th t u tin v lut kt hp ca ton t ............ 63
Chuyn i gia s v xu .................................... 66
Cc ton t trn bin v hng ............................. 68
Ton t gn hai ngi ............................................. 69
T tng v t gim ................................................ 71
Ton t chop() ....................................................... 72
Xen ln v hng vo trong xu ........................... 73
<STDIN> xem nh mt v hng ....................... 75
a ra bng print() ............................................... 76
Gi tr undef ......................................................... 77
Bi tp ....................................................................... 78
3 D liu mng v danh sch ................................... 79



iii
Mng l g? ............................................................... 79
Biu din hng k hiu .......................................... 80
Bin ....................................................................... 81
Ton t .................................................................. 82
Php gn ................................................................ 82
Truy nhp phn t ................................................. 85
Cc ton t push() v pop() .................................. 88
Cc ton t shift() v unshift() .............................. 89
Ton t reverse() ................................................... 89
Ton t sort() ........................................................ 90
Ton t chop() ....................................................... 90
Hon cnh v hng v mng .............................. 91
<STDIN> nh mt mng ...................................... 92
Xen ln bin mng ................................................ 92
Bi tp ....................................................................... 94
4 Cu trc iu khin ................................................ 97
Khi cu lnh ............................................................ 97
Cu lnh if/unless .................................................. 98
Cu lnh while/until ............................................ 101
Cu lnh for ........................................................ 103
Cu lnh foreach ................................................. 104
Bi tp ..................................................................... 106
5 Mng kt hp........................................................ 109
Mng kt hp l g? ................................................ 109
Bin mng kt hp .............................................. 110
Biu din hng k hiu cho mng kt hp ........... 111
Cc ton t mng kt hp ....................................... 112



iv
Ton t keys() ..................................................... 112
Ton t values() .................................................. 113
Ton t each() ..................................................... 114
Ton t delete ..................................................... 114
Bi tp ..................................................................... 115
6 Vo / ra c bn ..................................................... 117
Vo t STDIN ......................................................... 117
a vo t ton t hnh thoi ............................... 119
a ra STDOUT ..................................................... 120
Dng print cho a ra thng thng ................... 120
Dng printf cho ci ra c dng thc .................... 121
Bi tp ..................................................................... 122
7 Biu thc chnh qui .............................................. 123
Khi nim v biu thc chnh qui ........................... 123
Cch dng n gin v biu thc chnh qui........ 124
Khun mu .............................................................. 126
Khun mu mt k t .......................................... 127
Khun mu nhm ................................................ 129
Du ngoc trn nh b nh................................. 132
Thay phin .......................................................... 134
Khun mu neo ................................................... 134
Th t u tin.......................................................... 136
Thm v ton t i snh ........................................ 137
Chn mt mc tiu khc (ton t =~) ................. 137
B qua ch hoa thng ....................................... 138
Dng mt nh bin khc .................................... 139



v
Dng xen ln bin ............................................... 140
Bin ch c c bit ........................................... 141
Thay th .................................................................. 142
Cc ton t split() v join() ..................................... 144
Ton t split() ..................................................... 144
Ton t join() ...................................................... 146
Bi tp ..................................................................... 146
8 Hm ....................................................................... 149
Hm h thng v hm ngi dng .......................... 149
Xc nh mt hm ngi dng ........................... 149
Gi mt hm ngi dng .................................... 151
Gi tr cho li ...................................................... 152
i ...................................................................... 153
Bin cc b trong hm ........................................ 156
Bi tp ..................................................................... 159
9 Cc cu trc iu khin khc .............................. 161
Ton t last ......................................................... 161
Ton t next ........................................................ 163
Ton t redo ........................................................ 164
Khi c nhn ....................................................... 165
B thay i biu thc .......................................... 167
&&, || v ?: xem nh cc cu trc iu khin ..... 169
Bi tp ..................................................................... 171
10 Tc hiu tp v kim th tp .......................... 173
Tc hiu tp l g?................................................. 173



vi
M v ng mt tc hiu tp ................................ 174
Mt cht tiu khin: die() ................................... 175
Dng tc hiu tp .................................................. 177
Kim tra tp -x .................................................... 178
Cc ton t stat() v lstat() .................................. 183
Dng _Filehandle ................................................ 184
Bi tp ..................................................................... 185
11 Dng thc ............................................................ 187
Dng thc l g? ...................................................... 187
nh ngha mt dng thc ................................... 188
Gi mt dng thc .............................................. 191
Ni thm v ni gi tp ...................................... 193
Trng vn bn ................................................... 194
Trng s ............................................................ 194
Trng nhiu dng.............................................. 196
Trng c lp y ........................................... 196
Dng thc u trang ............................................ 200
Thay i mc nh cho dng thc ........................... 201
Dng select() thay i tc hiu tp .............. 201
Thay i tn dng thc ....................................... 203
i tn dng thc u trang ................................ 204
i chiu di trang .............................................. 205
Thay i v tr trn trang ..................................... 206
Bi tp ..................................................................... 207
12 Truy nhp danh mc ......................................... 209
Chuyn vng quanh cy danh mc ......................... 209
Globbing ................................................................. 210



vii
Tc hiu danh mc ........................................... 213
M v ng tc hiu danh mc ........................ 214
c mt tc hiu danh mc .............................. 215
Bi tp ..................................................................... 216
13 Thao tc tp v danh mc ................................. 217
Loi b tp .............................................................. 217
i tn tp ............................................................... 219
To ra tn thay phin cho mt tp (mc ni) ...... 220
V mc ni cng v mm ................................... 220
To ra cc mc ni cng v mm bng Perl ....... 222
To ra v xo danh mc ...................................... 224
Thay i php s dng ........................................ 225
Thay i quyn s hu........................................ 226
Thay i nhn thi gian ...................................... 227
Bi tp ..................................................................... 229
14 Qun l tin trnh ................................................ 230
Dng system() v exec() ......................................... 230
Dng du nhy n ngc .................................. 235
Dng cc tin trnh nh tc hiu tp ................. 236
Dng fork ............................................................ 238
Tm tt v cc php ton tin trnh ..................... 241
Gi v nhn tn hiu ............................................ 243
Bi tp ..................................................................... 246
15 Bin i d liu khc ......................................... 249
Tm mt xu con ..................................................... 249
Trch v thay th mt xu con............................. 251



viii
Dng thc d liu bng sprintf() ......................... 254
Sp xp nng cao .................................................... 254
Chuyn t ................................................................ 260
Bi tp ..................................................................... 263
16 Truy nhp c s d liu h thng ..................... 265
Ly mt hiu v thng tin nhm ............................. 265
Gi v m d liu nh phn..................................... 270
Ly thng tin mng ................................................. 273
Ly cc thng tin khc ............................................ 275
Bi tp ..................................................................... 276
17 Thao tc c s d liu ngi dng .................... 277
C s d liu DBM v mng DBM ........................ 277
M v ng mng DBM ..................................... 278
Dng mng DBM ................................................ 280
C s d liu truy nhp ngu nhin chiu di c
nh ..................................................................... 281
C s d liu (vn bn) chiu di thay i ......... 284
Bi tp ..................................................................... 287
18 Chuyn i cc ngn ng khc sang Perl ......... 289
Chuyn chng trnh awk sang Perl ................... 289
Chuyn i chng trnh sed sang Perl .............. 291
Chuyn i chng trnh Shell sang Perl ........... 292
Bi tp ..................................................................... 293
Ph lc A Tr li cc bi tp .................................. 295



ix
Chng 2, D liu v hng .............................. 295
Chng 3, Mng v d liu danh sch ............... 297
Chng 4, Cu trc iu khin ........................... 299
Chng 5, Mng kt hp .................................... 302
Chng 6, Vo/ra c s ...................................... 305
Chng 7, Biu thc chnh qui ........................... 307
Chng 8, Hm ................................................... 311
Chng 9, Cc cu trc iu khin khc ............ 314
Chng 10, Tc hiu tp v kim th tp ........ 315
Chng 11, Dng thc ........................................ 317
Chng 12, Truy nhp danh mc ....................... 319
Chng 13, Thao tc tp v danh mc ............... 320
Chng 14, Qun l tin trnh ............................. 323
Chng 15, Bin i d liu khc ...................... 326
Chng 16, Truy nhp c s d liu h thng ... 329
Chng 17, Thao tc c s d liu ngi dng.. 330
Chng 18, Chuyn cc ngn ng khc sang Perl
............................................................................ 332
Ph lc B C s v ni mng .................................. 333
M hnh khe cm ................................................ 333
Mt khch mu ................................................... 335
B phc v mu .................................................. 335
Ph lc C Cc ch cn cha ni ti .................. 337
Trnh g li ......................................................... 337
Dng lnh ............................................................ 338
Cc ton t khc .................................................. 338
Nhiu, nhiu hm na ......................................... 338
Nhiu, nhiu bin nh ngha sn ........................ 338
Xu y ............................................................ 338
Tr v (t trnh con)............................................ 339



x
Ton t eval (v s///e) ......................................... 339
Thao tc bng k hiu bng *FRED .................... 340
Ton t goto ........................................................ 340
Ton t require .................................................... 341
Th vin .............................................................. 341
Tin vui v Perl 5.0 ............................................... 341








1

1


Gii thiu


Lch s Perl
Perl l cch vit tt cho Practical Extraction and
Report Language Ngn ng bo co v trch rt thc
hnh, mc du n cng cn c gi l Pathologically
Eclectic Rubbish Lister - B lit k rc in t bnh
hon. Chng ch g m bin minh xem cch gi no ng
hn, v c hai u c Larry Wall, ngi sng to v
kin trc s chnh, ngi ci t v bo tr ca Perl chp
nhn. ng y to ra Perl khi c gng sn xut ra mt
s bo co t mt cp bc cc tp kiu nh th ngi
dng mng Usenet h thng bo li, v lnh awk lm
x ht hi. Larry, mt ngi lp trnh li bing, quyt
nh thanh ton vn ny bng mt cng c vn nng
m ng c th dng t nht cng mt ni khc. Kt qu
l bn u tin ca Perl.
Sau khi chi vi bn u ny ca Perl mt cht,
thm cht liu y , Larry a n cho cng ng c
Trong chng ny:
Lch s Perl
Mc ch ca Perl
C sn
H tr
Cc khi nim c bn
Do qua v Perl

2

gi Usenet, thng vn c gi l the Net. Ngi
dng thuc ton ngi ph du ngho kh v h thng
trn ton th gii (qung chc nghn ngi) a li
cho anh y phn hi, hi cch lm th ny th kia, vic
ny vic khc, nhiu im m Larry cha bao gi mng
tng ra v vic gii quyt cho Perl nh b ca mnh c.
Nhng kt qu l Perl trng thnh, trng thnh v
trng thnh thm na, v cng cng t l nh li ca
UNIX. (vi bn l ngi mi, ton b li UNIX c
dng ch kht vo trong 32K! V by gi chng ta may
mn nu ta c th c c n di mt vi mega.) N
trng thnh trong cc tnh nng. N trng thnh
trong tnh kh chuyn. iu m c thi l mt ngn ng
t to by gi c ti liu s dng 80 trang, mt cun
sch ca Nutshell 400 trang, mt nhm tin Usenet vi 40
nghn thu bao, v by gi l on gii thiu nh nhng
ny.
Larry vn l ngi bo tr duy nht, lm vic trn
Perl ngoi gi khi kt thc cng vic thng ngy ca
mnh. V Perl th vn pht trin.
Mt cch i th lc m cun sch ny t ti im
dng ca n, Larry s a ra bn Perl mi nht, bn 5.0,
ha hn c mt s tnh nng thng hay c yu cu,
v c thit k li t bn trong tr ra. (Larry bo ti
rng khng cn my dng lnh t ln a ra trc, v s
y c ngy cng t i mi ngy.) Tuy nhin, cun sch
ny c th vi Perl bn 4.0 (ln a ra gn y
nht khi ti vit iu ny). Mi th y s lm vic
vi bn 5.0 v cc bn sau ca Perl. Thc ra, chng
trnh Perl 1.0 vn lm vic tt vi nhng bn gn y,
ngoi tr mt vi thay i l cn cho s tin b.

3

Mc ch ca Perl
Perl c thit k tr gip cho ngi dng UNIX
vi nhng nhim v thng dng m c th rt nng n
hay qu nhy cm vi tnh kh chuyn i vi trnh v,
v cng qu k l hay ngn ngi hay phc tp lp trnh
trong C hay mt ngn ng cng c UNIX no khc.
Mt khi bn tr nn quen thuc vi Perl, bn c th
thy mnh mt t thi gian ly c trch dn trnh v
(hay khai bo C) ng, v nhiu thi gian hn c tin
trn Usenet v i trt tuyt trn i; v Perl l mt cng
c ln ta nh chic n by. Cc cu trc cht ch ca
Perl cho php bn to ra (vi ti thiu vic lm m ) mt
s gii php c u th rt trm lng hay nhng cng c
tng qut. Cng vy, bn c th li nhng cng c ny
sang cng vic tip, v Perl l kh chuyn cao v li
c sn, cho nn bn s c nhiu thi gian hn c tin
Usenet v trt tuyt.
Ging nh mi ngn ng, Perl c th ch vit - tc
l c th vit ra chng trnh m khng th no c
c. Nhng vi ch ng n, bn c th trnh c
kt ti thng thng ny. Qu th, i khi Perl trng nh
ni ting vi nhng ci khng quen thuc, nhng vi
ngi lp trnh tho Perl, n ta nh nhng dng c
tng kim tra vi mt s mnh trong cuc i. Nu bn
tun theo nhng hng dn ca cun sch ny th
chng trnh ca bn s d c v d bo tr, v chng ta
c l s thng trong bt k cuc tranh lun Perl kh hiu
no.
Tnh sn c
Nu bn nhn c

4

Perl: not found
khi bn th gi Perl t lp v th ngi qun tr h thng
ca bn cng chng ln cn st. Nhng thm ch nu n
khng c trn h thng ca bn, th bn vn c th ly
c n khng mt tin (theo ngha n tra khng mt
tin).
Perl c phn phi theo giy php cng khai GNU,
ngha l th ny, bn c th phn pht chng trnh nh
phn Perl ch nu bn lm cho chng trnh gc c sn
cho mi ngi dng khng phi tr tin g c, v nu bn
sa i Perl, bn phi phn pht chng trnh gc ca
bn cho ni sa i ca bn na. V l bn cht ca
cho khng. Bn c th ly chng trnh gc ca Perl vi
gi ca mt bng trng hay vi mga byte qua ng
dy. V khng ai c th kho Perl v bn cho bn ch m
nh phn vi t tng c bit v cu hnh phn cng
c h tr.
Thc ra, n khng ch l cho khng, nhng n chy
cn gn hn trn gn nh mi th m c th gi l
UNIX hay ta UNIX v c trnh bin dch C. y l v
b trnh ny ti vi bn vit cu hnh b quyt c gi
l Cu hnh, ci s mc v chc vo cc danh mc h
thng tm nhng th n cn, v iu chnh vic a
vo cc tp v cc k hiu c xc nh tng ng,
chuyn cho bn vic kim chng pht hin ca n.
Bn cnh cc h thng UNIX hay ta UNIX, ngi
b nghin Perl em n sang Amiga, Atari ST, h
Macintosh, VMS, OS/2, thm ch MS/DOS - v c l
cn nhiu hn na vo lc bn c cun sch ny. v tr
chnh xc v s c sn ca nhng bn Perl ny th bin

5

ng, cho nn bn phi hi quanh (trn nhm tin Usenet
chng hn) c c thng tin mi nht. Nu bn hon
ton khng bit g, th mt bn c ca Perl c trn a
phn mm CD-ROM UNIX Power Tools, ca Jerry Peek,
Tim OReilly v Mike Loukides (OReilly & Associates/
Random House Co., 1993).

H tr
Perl l con ca Larry Wall, v vn ang c anh
y nng niu. Bo co li v yu cu nng cao ni chung
c sa cha trong cc ln a ra sau, nhng anh y
cng chng c ngha v no lm bt k ci g vi
chng c. Tuy th Larry thc s thch th nghe t tt c
chng ta, v cng lm vic thc s thy Perl c
dng trn qui m th gii. E-mail trc tip cho anh y
ni chung nhn c tr li (cho d y ch n thun
l my tr li email ca anh y), v i khi l s p ng
con ngi.
ch li hn vic vit th trc tip cho Larry l nhm
h tr Perl trc tuyn ton th gii, lin lc thng qua
nhm tin Usenet comp.lang.perl. Nu bn c th gi
email trn Internet, nhng cha vo Usenet, th bn c
th tham gia nhm ny bng cch gi mt yu cu ti
perl-users-request@virgina.edu, yu cu s ti mt
ngi c th ni bn vi ca khu email hai chiu trong
nhm, v cho bn nhng hng dn v cch lm vic.
Khi bn tham gia mt nhm tin, bn s thy i loi
c khong 30 n 60 th mi ngy (vo lc bn vit
ny c son tho) trn mi ch t cu hi ca
ngi mi bt u cho ti vn chuyn chng trnh

6

phc tp v vn giao din, v thm ch c mt hay hai
chng trnh kh ln.
Nhm tin gn nh c nhng chuyn gia Perl iu
phi. Phn ln thi gian, cu hi ca bn c tr li
trong vng vi pht khi tin ca bn ti u ni Usenet
chnh. th mc h tr t nh sn xut phn mm
mnh a chung v vic cho khng ny! Bn thn Larry
cng c v nhm khi thi gian cho php, v i khi
xen cc bi vit c thm quyn vo chm dt vic ci
nhau hay lm sng t mt vn . Sau rt, khng c
Usenet, c l khng th c ch d dng cng b Perl
cho c th gii.
Bn cnh nhm tin, bn cng nn c tp ch Perl, i
cng vic phn phi Perl. Mt ngun c thm quyn
khc l cun sch Programming Perl ca Larry Wall v
Randal L. Schwatrz (OReilly & Associates, 1990).
Programming Perl c xem nh Sch con lc v
ba ca n v con vt ny (ht nh cun sch ny c l s
c bit ti vi tn sch lc khng bu). Sch con
lc cha thng tin tham chiu y v Perl di
dng ng gn gng. Sch con lc cng bao gm mt
bng tra tham chiu bt ra ti tnh m chnh l ngun a
chung ca c nhn ti v thng tin Perl.

Cc khi nim c bn
Mt bn vit v khng g khc hn l mt dy cc
lnh v nhi vo trong mt tp vn bn. Tp ny c
lm cho chy bng cch bt mt bit thc hin (qua
chmod +x filename) v ri g tn ca tp vo li nhc

7

ca v. Bingo, mt chng trnh v ln. Chng hn, mt
bn vit chy ch lnh date theo sau bi ch lnh who
c th c to ra v thc hin nh th ny:
$ echo date > somecript
$ echo who > somecript
$ cat somescript
date
who
$ chmod _x somescript
$ somescript
[output of date followed by who]
$
Tng t nh th, mt chng trnh Perl l mt b
cc cu lnh v nh ngha Perl c nm vo trong mt
tp. Ri bn bt bit thc hin v g tn ca tp ny ti li
nhc ca v. Tuy nhin, tp ny phi ch ra rng y l
mt chng trnh Perl v khng phi l chng trnh v,
nn chng ta cn mt bc ph.
#! /usr/bin/perl
lm dng u tin ca tp ny. Nhng nu Perl ca
bn b kt vo mt ni khng chun, hay h iu hnh
ta UNIX ca bn khng hiu dng #!, th bn c thm
vic phi lm. Hi ngi ci t Perl v iu ny. Cc th
d trong sch ny gi s rng bn dng c ch thng
thng ny.
Perl l mt ngn ng phi nh dng kiu nh C -
khong trng gia cc hiu bi (nhng phn t ca
chng trnh, nh print hay +) l tu chn, tr phi hai
hiu bi i vi nhau c th b lm ln thnh mt hiu bi
khc, trong trng hp th khong trng thuc loi
no l bt buc. (Khong trng bao gm du cch,

8

du tab, dng mi, v u dng hay ko giy.) C mt
vi cu trc i hi mt loi khong trng no ch
no , nhng chng s c tr ra khi ta ni ti chng.
Bn c th gi thit rng loi v khi lng khong trng
gia cc hiu bi l tu trong cc trng hp khc.
Mc du gn nh tt c cc chng trnh Perl c
th c vit tt c trn mt dng, mt cch in hnh
chng trnh Perl cng hay c vit tt l nh chng
trnh C, vi nhng phn cu lnh lng nhau c vit tt
vo hn so vi phn bao quanh. Bn s thy y nhng
th d ch ra phong cch vit tt l in hnh trong ton
b cun sch ny.
Cng ging nh bn vit v v, chng trnh Perl
bao gm tt c cc cu lnh perl v tp c ly t hp
chung nh mt trnh ln cn thc hin. Khng c khi
nim v trnh chnh main nh trong C.
Ch thch ca Perl ging nh ch thch ca lp v
(hin i). Bt k ci g nm gia mt du thng (#) ti
cui dng l mt ch thch. Khng c khi nim v
ch thch trn nhiu dng nh C.
Khng ging hu ht cc lp v (nhng ging nh
awk v sed), b thng dch Perl phn tch v bin dch
hon ton chng trnh trc khi thc hin n. iu ny
c ngha l bn khng bao gi nhn c li c php t
chng trnh mt khi chng trnh bt u chy, v
cng c ngha l khong trng v ch thch bin mt v
s khng lm chm chng trnh. Thc ra, giai on bin
dch ny bo m vic thc hin nhanh chng ca cc
thao tc Perl mt khi n c bt u, v n cung cp
ng c ph loi b C nh mt ngn ng tin ch h

9

thng n thun da trn nn tng l C c bin dch.
Vic bin dch ny khng mt thi gian - s l phi
hiu qu nu mt chng trnh Perl cc ln li ch thc
hin mt nhim v nh b chng vnh (trong s nhiu
nhim v tim nng) v ri ra, v thi gian chy cho
chng trnh s nh xu nu so vi thi gian dch.
Cho nn Perl ging nh mt b bin dch v thng
dch. N l bin dch v chng trnh c c v phn
tch hon ton trc khi cu lnh u tin c thc
hin. N l b thng dch v khng c m ch ngi u
trt y khng gian a. Theo mt cch no , n l
tt nht cho c hai loi ny. Phi th thc, vic n i m
ch dch gia nhng li gi th hay, v l trong
danh sch mong c ca Larry cho Perl tng lai.

Do qua Perl
Chng ta bt u cuc hnh trnh ca mnh qua Perl
bng vic i do mt cht. Vic i do ny s gii thiu
mt s cc tnh nng khc nhau bng cch b sung vo
mt ng dng nh. Gii thch y l cc k ngn gn -
mi vng ch c tho lun chi tit hn rt nhiu
v sau trong cun sch ny. Nhng cuc i do nh ny
s cho bn kinh nghim nhanh chng v ngn ng, v
bn c th quyt nh liu bn c thc s mun kt thc
cun sch ny hay c thm cc tin Usenet hay chy i
chi trt tuyt.


10

Chng trnh Xin cho mi ngi
Ta hy nhn vo mt chng trnh nh m thc t c
lm iu g . y l chng trnh Xin cho mi
ngi:
#!/usr/bin/perl
print Xin cho mi ngi\n;
Dng u tin l cu thn ch ni rng y l
chng trnh Perl. N cng l li ch thch cho Perl -
nh rng li ch thch l bt k ci g nm sau du thng
cho ti cui dng, ging nh hu ht cc lp v hin i
hay awk.
Dng th hai l ton b phn thc hin c ca
chng trnh ny. Ti y chng ta thy cu lnh print.
T kho print bt u chng trnh, v n c mt i,
mt xu vn bn kiu C. Bn trong xu ny, t hp k t
\n biu th cho k t dng mi; ht nh trong C. Cu lnh
print c kt thc bi du chm phy (;). Ging nh C,
tt c cc cu lnh n gin kt thc bng chm
phy
*
.
Khi bn gi chng trnh ny, phn li s gi b
thng dch Perl, phn tch cu ton b chng trnh (hai
dng, k c dng ch thch u tin) v ri thc hin
dng dch. Thao tc u tin v duy nht l thc hin
ton t print, iu ny gi i ca n ra li ra. Sau khi
chng trnh hon tt, tin trnh Perl ra, cho li mt
m ra thnh cng cho lp v.


*
Du chm phy c th b i khi cu lnh ny l cu lnh cui ca
mt khi hay tp hay eval.

11

Hi cu hi v nh kt qu
Thm mt cht phc tp hn. T Xin cho mi ngi
l mt ng chm lnh nht v cng rn. Lm cho
chng trnh gi bn theo tn bn. lm vic ny, cn
mt ch gi tn, mt cch hi tn, v mt cch nhn cu
tr li.
Mt loi t ch gi gi tr (ta nh mt tn) l bin
v hng. Vi chng trnh ny, ta s dng bin v
hng $name gi tn bn. Chng ta s i chi tit hn
trong Chng 2, D liu v hng, v nhng g m bin
ny c th gi, v nhng g bn c th lm vi chng.
Hin ti, gi s rng bn c th gi mt s hay xu (dy
cc k t) trong bin v hng.
Chng trnh ny cn hi v tn. lm iu ,
cn mt cch nhc v mt cch nhn ci vo. Chng
trnh trc ch ra cho ta cch nhc - dng ton t print.
V cch nhn mt dng t thit b cui l vi ton t
<STDIN>, m (nh ta s dng n y) ly mt dng
ci vo. Gn ci vo ny cho bin $name. iu ny cho
chng trnh:
print Tn bn l g? ;
$name = <STDIN> ;
Gi tr ca $name ti im ny c mt du dng mi
kt thc (Randal c trong Randal\n). vt b iu ,
chng ta dng ton t chop(), ton t ly mt bin v
hng lm i duy nht v b i k t cui t gi tr xu
ca bin:
chop($name);
By gi tt c nhng g cn lm l ni Xin cho, tip

12

l gi tr ca bin $name, m c th thc hin theo
kiu v bng cch nhng bin ny vo bn trong xu c
ngoc kp:
print Xin cho, $name!\n;
Ging nh lp v, nu mun mt du la thay v
tham chiu bin v hng, th c th t trc du la
vi mt du s cho ngc.
Gn tt c li, ta c:
#!/usr/bin/perl
print Tn bn l g? ;
$name = <STDIN> ;
chop($name);
print Xin cho, $name!\n;

B sung chn la
By gi ta mun c mt li cho c bit cho
Randal, nhng mun li cho thng thng cho mi
ngi khc. lm iu ny, cn so snh tn c
a vo vi xu Randal, v nu hai xu l mt, th lm
iu g c bit. B sung thm lnh r nhnh if-then-
else v php so snh vo chng trnh:
#!/usr/bin/perl
print Tn bn l g? ;
$name = <STDIN> ;
chop($name);
if ($name eq Randal) {
print Xin cho Randal! Tt qu anh li y!\n;
} else {
print Xin cho, $name!\n; # cho mng thng
thng
}

13

Ton t eq so snh hai xu. Nu chng bng nhau
(tng k t mt, v c cng chiu di), th kt qu l
ng. (Khng c ton t ny trong C, v awk phi dng
cng ton t cho xu v s v to ra vic on c rn
luyn.)
Cu lnh if chn xem khi cu lnh no (gia cc
du ngoc nhn snh ng) l c thc hin - nu biu
thc l ng, l khi th nht, nu khng th l
khi th hai.

on t b mt
No, v chng ta c mt tn nn ta cho mt
ngi chy chng trnh on mt t b mt. Vi mi
ngi ngoi tr Randal, chng ta s cho chng trnh
c hi lp li on cho n khi no ngi ny on
c ng. Trc ht xem chng trnh ny v ri xem
gii thch:
#! /usr/bin/perl
$secretword = llama; # t b mt
print Tn bn l g? ;
$name = <STDIN> ;
chop($name);
if ($name eq Randal) {
print Xin cho, Randal! May qu anh y!\n;
} else {
print Xin cho, $name!\n; # cho thng thng
print T b mt l g? ;
$guess = <STDIN>;
chop($guess);
while ($guess ne $secrectword) {
print Sai ri, th li i. T b mt l g?;
$guess = <STDIN>;

14

chop($guess);
}
}
Trc ht, nh ngha t b mt bng vic t n vo
trong bin v hng khc, $secretword. Sau khi n
cho, mt ngi (khng phi Randal) s c yu cu
(vi mt cu lnh print khc) on ch. Li on ri
c em ra so snh vi t b mt bng vic dng ton
t ne, m s cho li ng nu cc xu ny khng bng
nhau (y l ton t logic ngc vi ton t eq). Kt qu
ca vic so snh s kim sot cho trnh while, chu trnh
ny thc hin khi thn cho ti khi vic so snh vn cn
ng.
Tt nhin, chng trnh ny khng phi l an ton
lm, v bt k ai mt vi vic on cng c th n
thun ngt chng trnh v quay tr v li nhc, hay
thm ch cn nhn qua chng trnh gc xc nh ra
t. Nhng, chng ta hin ti cha nh vit mt h thng
an ton, ch xem nh mt th d cho trang hin ti ca
cun sch ny.

Nhiu t b mt
Ta hy xem cch thc mnh c th sa i on
chng trnh ny cho php c nhiu t b mt. Bng
vic dng iu thy, chng ta c th so snh li on
lp i lp li theo mt chui cu tr li r c ct gi
trong cc bin v hng tch bit. Tuy nhin, mt danh
sch nh vy s kh m thay i hay c vo t mt tp
hay my tnh trn c s ngy lm vic thng l.
Mt gii php tt hn l ct gi tt c cc cu tr li

15

c th vo trong mt cu trc d liu gi l danh sch
hay mng. Mi phn t ca mng l mt bin v
hng tch bit m c th c t gi tr hay truy nhp
c lp. Ton b mng cng c th c trao cho mt
gi tr trong mt c t nhp. Ta c th gn mt gi tr
cho ton b mng c tn @words sao cho n cha ba mt
hiu tt c th c:
@words = (camel, llama, oyster);
Tn bin mng bt u vi @, cho nn chng l
khc bit vi cc tn bin v hng.
Mt khi mng c gn th ta c th truy nhp
vo tng phn t bng vic dng mt tham chiu ch s.
Cho nn $words[0] l camel, $words[1] l llama, $words[2]
l oyster. Ch s cng c th l mt biu thc, cho nn
nu ta t $i l 2 th $words[$i] l oyster. (Tham chiu ch
s bt u vi $ thay v @ v chng tham chiu ti mt
phn t ring ca mng thay v ton b mng.) Quay tr
li vi th d trc y ca ta:
#! /usr/bin/perl
$words = (camel, llama, oyster); # t b mt
print Tn bn l g? ;
$name = <STDIN> ;
chop($name);
if ($name eq Randal) {
print Xin cho, Randal! May qu anh y!\n;
} else {
print Xin cho, $name!\n; # cho thng thng
print T b mt l g? ;
$guess = <STDIN>;
chop($guess);
$i = 0; # th t ny trc ht
$correct = c th; # t on c ng hay khng?
while ($correct eq $guess) { # c kim tra n khi bit

16

if ($words[$i] eq $guess) { # ng khng
$correct = c; # c
} elsif ($i < 2) { # cn phi xt thm t na?
$i = $i + 1; # nhn vo t tip ln sau
} else # ht ri, th l hng
print Sai ri, th li i. T b mt l g?;
$guess = <STDIN>;
chop($guess);
$i = 0; # bt u kim tra t u ln na
}
} # kt thc ca while not correct
} # kt thc ca not Randal
Bn s rng chng ta ang dng bin v hng
$correct ch ra rng chng ta vn ang tm ra mt hiu
ng, hay rng chng ta khng tm thy.
Chng trnh ny cng ch ra khi elsif ca cu lnh
if-then-else. Khng c lnh no tng ng nh th
trong C hay awk - l vic vit tt ca khi else cng
vi mt iu kin if mi, nhng khng lng bn trong
cp du ngoc nhn khc. y chnh l ci rt ging Perl
so snh mt tp cc iu kin trong mt dy chuyn
phn tng if-elsif-elsif-elsif-else.


Cho mi ngi mt t b mt khc nhau
Trong chng trnh trc, bt k ngi no ti cng
c th on bt k t no trong ba t ny v c th
thnh cng. Nu ta mun t b mt l khc nhau cho mi
ngi, th ta cn mt bng snh gia ngi v t:


17


Ngi T b mt
Fred
Barney
Betty
Wilma
camel
llama
oyster
oyster

Ch rng c Betty v Wilma c cng t b mt.
iu ny l c.
Cch d nht ct gi mt bng nh th trong Perl
l bng mt mng kt hp. Mi phn t ca mng ny
gi mt gi tr v hng tch bit (ht nh kiu mng
khc), nhng cc mng li c tham chiu ti theo
kho, m c th l bt k gi tr v hng no (bt k xu
hay s, k c s khng nguyn v gi tr m). to ra
mt mng kt hp c gi l %words (ch % ch
khng phi l @) vi kho v gi tr c cho trong
bng trn, ta gn mt gi tr cho %words (nh ta lm
nhiu trc y vi mng khc):
%words = (fred, camel, barney, llama,
betty, oyster, wilma, oyster) ;
Mi cp gi tr trong danh sch biu th cho mt
kho v gi tr tng ng ca n trong mng kt hp.
Ch rng ta b php gn ny ra hai dng m khng
c bt k loi k t ni dng no, v khong trng ni
chung l v ngha trong chng trnh Perl.
tm ra t b mt cho Betty, ta cn dng Betty nh

18

kho trong mt tham chiu vo mng kt hp %words,
qua mt biu thc no nh %words{betty}. Gi tr ca
tham chiu ny l oyster, tng t nh iu ta lm
trc y vi mng khc. Cng nh trc y, kho c
th l bt k biu thc no, cho nn t $person vi betty
v tnh $words{$person} cng cho oyster.
Gn tt c nhng iu ny li ta c chng trnh
nh th ny:
#! /usr/bin/perl
%words = (fred, camel, barney, llama,
betty, oyster, wilma, oyster) ;
print Tn bn l g? ;
$name = <STDIN> ;
chop($name);
if ($name eq Randal) {
print Xin cho, Randal! May qu anh y!\n;
} else {
print Xin cho, $name!\n; # cho thng thng
$secretword = $words{$name}; # ly t b mt
print T b mt l g? ;
$guess = <STDIN>;
chop($guess);
while ($correct ne $secretwords) {
print Sai ri, th li i. T b mt l g?;
$guess = <STDIN>;
chop($guess);
} # kt thc ca while
} # kt thc ca not Randal
ch nhn vo t b mt. Nu khng tm thy t
ny th gi tr ca $secretword s l mt xu rng
*
, m ta
c th kim tra liu ta c mun xc nh mt t b mt

*
c, y chnh l gi tr undef, nhng n trng nh mt xu
rng cho ton t eq

19

mc nh cho ai khc khng. y l cch xem n:
[... phn cn li ca chng trnh b xo...]
$secretword = $words{$name}; # ly t b mt
if ($secretword eq ) { # y, khng thy
$secretword = cu knh; # chc chn, sao khng
l vt?
}
print T b mt l g? ;
[... phn cn li ca chng trnh b xo...]


Gii quyt dng thc ci vo thay i
Nu ti a vo Randal L. Schwartz hay randal thay v
Randal th ti s b ng cc li vi phn ngi dng cn
li, v vic so snh eq th li so snh ng s bng nhau.
Ta hy xem mt cch gii quyt cho iu .
Gi s ti mun tm bt k xu no bt u vi
Randal, thay v ch l mt xu bng Randal. Ti c th
lm iu ny trong sed hay awk hoc grep vi mt biu
thc chnh qui: mt khun mu s xc nh ra mt tp
hp cc xu snh ng. Ging nh trong sed hay grep,
biu thc chnh qui trong Perl snh bt k xu no bt
u vi Randal l ^Randal. snh xu ny vi xu trong
$name, chng ta dng ton t snh nh sau:
if ($name =~ /^Randal/) {
## c, snh ng
} else {
## khng, snh sai
}
Ch rng biu thc chnh qui c nh bin bi
du s cho. Bn trong cc du s cho, du cch v

20

khong trng l c ngha, ht nh chng bn trong xu.
iu ny gn nh th, nhng n li khng gii quyt
vic la ra randal hay loi b Randall. chp nhn
randal, chng ta thm tu chn b qua hoa thng, mt
ch i nh c thm vo sau du s cho ng. loi
b Randall, ta thm mt nh du c bit nh bin t
(tng t vi vi v mt s bn ca grep) di dng ca
\b trong biu thc chnh qui. iu ny m bo rng k
t i sau l u tin trong biu thc chnh qui khng phi
l mt k t khc. iu ny lm thay i biu thc chnh
qui thnh /^randal\b/i, m c ngha l randal ti u xu,
khng c k t hay ch s no theo sau, v chp nhn c
hai kiu ch hoa thng.
Khi gn tt c li vi phn cn li ca chng trnh
th n s ging nh th ny:
#! /usr/bin/perl
%words = (fred, camel, barney, llama,
betty, oyster, wilma, oyster) ;
print Tn bn l g? ;
$name = <STDIN> ;
chop($name);
if ($name =~ /^randal\b/i ) {
print Xin cho, Randal! May qu anh y!\n;
} else {
print Xin cho, $name!\n; # cho thng thng
$secretword = $words{$name}; # ly t b mt
if ($secretword eq ) { # y, khng thy
$secretword = cu knh; # chc chn, sao
khng l vt?
}
print T b mt l g? ;
$guess = <STDIN>;
chop($guess);
while ($correct ne $secretwords) {

21

print Sai ri, th li i. T b mt l g?;
$guess = <STDIN>;
chop($guess);
} # kt thc ca while
} # kt thc ca not Randal
Nh bn c th thy, chng trnh ny khc xa vi
chng trnh n gin Xin cho, mi ngi, nhng n vn
cn rt nh b v lm vic c, v n qu lm c t
cht vi ci ngn xu vy. y chnh l cch thc ca
Perl.
Perl a ra tnh nng v cc biu thc chnh qui c
trong mi trnh tin ch UNIX chun (v thm ch trong
mt s khng chun). Khng ch c th, nhng cch thc
Perl gii quyt cho vic i snh xu l cch nhanh nht
trn hnh tinh ny, cho nn bn khng b mt hiu nng.
(Mt chng trnh ging nh grep c vit trong Perl
thng nh bi chng trnh grep c cc nh cung
cp vit trong C vi hu ht cc ci vo. iu ny c
ngha l thm ch grep khng thc hin vic ca n tht
tt.)

Lm cho cng bng vi mi ngi
Vy by gi ti c th a vo Randal hay randal hay
Randal L. Schwartz, nhng vi nhng ngi khc th sao?
Barney vn phi ni ng barney (thm ch khng c
c barney vi mt du cch theo sau).
cng bng cho Barey, chng ta cn nm c t
u ca bt k ci g c a vo, v ri chuyn n
thnh ch thng trc khi ta tra tn trong bng. Ta lm
iu ny bng hai ton t: ton t substitute, tm ra mt

22

biu thc chnh qui v thay th n bng mt xu, v ton
t translate, t xu ny thnh ch thng.
Trc ht, ton t thay th: chng ta mun ly ni
dung ca $name, tm k t u tin khng l t, v loi i
mi th t y cho n cui xu. /\W.*/ l mt biu thc
chnh qui m ta ang tm kim - \W vit tt cho k t
khng phi l t (mt ci g khng phi l ch, ch s
hay gch thp) v .* c ngha l bt k k t no t y
ti cui dng. By gi, loi nhng k t ny i, ta cn
ly bt k b phn no ca xu snh ng vi biu thc
chnh qui ny v thay n vi ci khng c g:
$name =~ s/\W.*//;
Chng ta ang dng cng ton t =~ m ta dng
trc , nhng by gi bn v phi ta c ton t thay
th: ch s c theo sau bi mt biu thc chnh qui v
xu c nh bin bi du s cho. (Xu trong th d
ny l xu rng gia du s cho th hai v th ba.)
Ton t ny trng ging v hnh ng rt ging nh
php thay th ca cc trnh son tho khc nhau.
By gi c c bt k ci g cn li tr thnh
ch thng th ta phi dch xu ny dng ton t tr. N
trng rt ging ch lnh tr ca UNIX, nhn mt danh
sch cc k t tm v mt danh sch cc k t thay
th chng. Vi th d ca ta, t ni dung ca $name
thnh ch thng, ta dng:
$name =~ tr/A-Z/a-z/;
Cc du s cho phn tch cc danh sch k t cn
tm v cn thay th. Du gch ngang gia A v Z thay
th cho tt c cc k t nm gia, cho nn chng ta c hai
danh sch, mi danh sch c 26 k t. Khi ton t tr tm

23

thy mt k t t mt xu trong danh sch th nht th k
t s c thay th bng k t tng ng trong danh
sch th hai. Cho nn tt c cc ch hoa A tr thnh ch
thng a, v c nh th
*
.
Gn tt c li vi mi th khc s cho kt qu trong:
#! /usr/bin/perl
%words = (fred, camel, barney, llama,
betty, oyster, wilma, oyster) ;
print Tn bn l g? ;
$name = <STDIN> ;
chop($name);
$original_name = $name; # ct gi cho mng
$name =~ s/\W.*//; # b mi th sau t u
$name =~ tr/A-Z/a-z/; # mi th thnh ch thng
if ($name eq randal ) {
print Xin cho, Randal! May qu anh y!\n;
} else {
print Xin cho, $original_name!\n; # cho thng
thng
$secretword = $words{$name}; # ly t b mt
if ($secretword eq ) { # y, khng thy
$secretword = cu knh; # chc chn, sao
khng l vt?
}
print T b mt l g? ;
$guess = <STDIN>;
chop($guess);
while ($correct ne $secretwords) {
print Sai ri, th li i. T b mt l g?;
$guess = <STDIN>;
chop($guess);
} # kt thc ca while

*
Cc chuyn gia s lu rng ti cng xy dng mt ci g
ta nh s/(\S*).*/\L$1/ lm tt c iu ny trong mt c t kch,
nhng cc chuyn gia c l s khng c mc ny.

24

} # kt thc ca not Randal
n cch thc biu thc chnh qui snh ng
vi tn ti Randal li tr thnh vic so snh n gin.
Sau rt, c Randal L. Schwartz v Randal tr thnh
randal sau khi vic thay th v dch. V mi ngi khc
cng c c s cng bng, v Fred v Fred Flinstone c
hai tr thnh fred, Barney Rubble v Barney, the little
guy s tr thnh barney, vn vn.
Vi ch vi cu lnh, chng ta to ra mt chng
trnh thn thin ngi dng hn nhiu. Bn s thy rng
vic din t thao tc xu phc tp vi vi nt l mt
trong nhiu im mnh ca Perl.
Tuy nhin, chm vo tn cho ta c th so snh n
v tra cu n trong bng th s ph hu mt tn va a
vo. Cho nn, trc khi chm vo tn, cn phi ct gi
n vo trong @original_name. (Ging nh cc k hiu C,
bin Perl bao gm cc ch, ch s v du gch thp v
c th c chiu di gn nh khng gii hn.) Vy c th
lm tham chiu ti $original_name v sau.
Perl c nhiu cch gim st v cht ct xu. bn
s thy phn ln chng trong Chng 7, Biu thc chnh
qui v Chng 15, Vic chuyn i d liu khc.

Lm cho n m un hn mt cht
Bi v chng ta thm qu nhiu m nn phi
duyt qua nhiu dng chi tit trc khi ta c th thu
c ton b lung chng trnh. iu cn l tch bch
logic mc cao (hi tn, chu trnh da trn t b mt a
vo) vi cc chi tit (so snh mt t b mt vi t

25

bit). Chng ta c th lm iu ny cho r rng, hoc c
th bi v mt ngi ang vit phn cao cp cn ngi
khc th vit (hay vit) phn chi tit.
Perl cung cp cc chng trnh con c tham bin v
gi tr cho li. Mt chng trnh con c xc nh mt
khi no trong chng trnh, v ri c th c dng
lp i lp li bng vic gi t bn trong bt k biu thc
no.
Vi chng trnh nh nhng tng trng nhanh ca
chng ta, to ra mt chng trnh con tn l &good_word
(tt c cc tn chng trnh con bt u vi mt du
v &) m nhn mt tn sch v mt t on, ri cho
li true nu t l ng, v cho li false nu khng
ng. Vic xc nh chng trnh con ta nh th
ny:
sub good_word {
local($somename, $someguess) = @_; # tn tham
bin
$somename =~ s/\W.*//; # b mi th sau t u
$somename =~ tr/A-Z/a-z/; # mi th thnh ch
thng
if ($somename eq randal) { # khng nn on
1; #gi tr cho li l true
} elsif (($words{$somename} || cu knh) eq
$someguess) {
1; # gi tr cho li l true
} else {
0; # cho li gi tr false
}
}
Trc ht, vic nh ngha ra mt chng trnh con
bao gm mt t dnh ring sub i theo sau l tn chng
trnh con (khng c du v &) tip na l mt khi m

26

lnh (c nh bin bi du ngoc nhn). nh ngha
ny c th vo bt k u trong tp chng trnh,
nhng phn ln mi ngi thch chng vo cui.
Dng u tin trong nh ngha c bit ny l mt
php gn lm vic sao cc gi tr ca hai tham bin ca
chng trnh ny vo hai bin cc b c tn $somename
v $someguess. (local() xc nh hai bin l cc b cho
chng trnh con ny, v cc tham bin ban u trong
mt mng cc b c bit gi l @_.)
Hai dng tip lm sch tn, cng ging nh bn
trc ca chng trnh.
Cu lnh if-elsif-else quyt nh xem t c on
($someguess) l c ng cho tn ($somename) hay
khng. Randal khng nn lm n thnh chng trnh con
ny, nhng ngay c nu n c, th d t no c on
cng OK c.
Biu thc cui cng c tnh trong chng trnh
con l cho li gi tr. Chng ta s thy cch cho li gi tr
c dng sau khi ti kt thc vic m t nh ngha v
chng trnh con. Php kim tra cho phn elsif trng c
phc tp hn mt cht - chia n ra:
($words{$somename} || cu knh) eq $someguess
Vt th nht bn trong du ngoc l mng kt hp
quen thuc ca ta, cho mt gi tr no t %words da
trn kho $somename. Ton t ng gia gi tr v
xu cu knh l ton t || (php hoc logic) nh c
dng trong C v awk v cc v khc. Nu vic tra cu t
mng kt hp c mt gi tr (ngha l kho $somename l
trong mng), th gi tr ca biu thc l gi tr . Nu
kho khng tm c, th xu cu knh s c dng

27

thay. y chnh l mt vt kiu Perl thng lm - xc
nh mt biu thc no , v ri a ra mt gi tr mc
nh bng cch dng || nu biu thc ny c th tr thnh
sai.
Trong mi trng hp, d l mt gi tr t mng
kt hp, hay gi tr mc nh cu knh, chng ta so
snh n vi bt k ci g c on. Nu vic so snh l
ng th cho li 1, nu khng cho li 0.
By gi tch hp tt c nhng iu ny vi phn cn
li ca chng trnh:
#! /usr/bin/perl
%words = (fred, camel, barney, llama,
betty, oyster, wilma, oyster) ;
print Tn bn l g? ;
$name = <STDIN> ;
chop($name);
if ($name =~ /^randal\b/i ) { # tr li cch khc
print Xin cho, Randal! May qu anh y!\n;
} else {
print Xin cho, $original_name!\n; # cho thng
thng
print T b mt l g? ;
$guess = <STDIN>;
chop($guess);
while ( ! &good_word($name, $guess)) {
print Sai ri, th li i. T b mt l g?;
$guess = <STDIN>;
chop($guess);
}
}
[ ... thm vo nh ngha ca &good_word y ...]
Ch rng chng ta quay tr li vi biu thc
chnh qui kim tra Randal, v by gi khng cn ko
mt phn tn th nht v chuyn n thnh ch thng,

28

chng no cn lin quan ti chng trnh chnh.
Khc bit ln l chu trnh while c cha &good_word.
Ti y, chng ta thy mt li gi ti chng trnh con,
truyn cho n hai i, $name v $guess. Bn trong
chng trnh con ny, gi tr ca $somename c t t
tham bin th nht, trong trng hp ny l $name.
Ging th, $someguess c t t tham bin th hai,
$guess.
Gi tr do chng trnh con cho li (hoc 1 hoc 0,
nh li nh ngha nu trc y) l m vi ton t
tin t ! (php ph nh logic). Nh trong C, ton t ny
cho li ng nu biu thc i sau l sai, v ngc li.
Kt qu ca php ph nh ny s kim sot chu trnh
while. Bn c th c iu ny l trong khi khng phi
l t ng.... Nhiu chng trnh Perl vit tt c rt
ging ting Anh, a li cho bn mt cht t do vi Perl
hay ting Anh. (Nhng bn chc chn khng ot gii
Pulitzer theo cch .)
Ch rng chng trnh con ny gi thit rng gi
tr ca mng %words c chng trnh chnh t. iu
ny khng c bit l hay, nhng chng c g so snh
c vi static ca C i vi chng trnh con - ni
chung, tt c cc bin nu khng ni khc i m c
to ra vi ton t local() th l ton cc i vi ton b
chng trnh. Thc ra, y ch l vn nh, v ngi ta
th c c tnh sng to v cch t tn bin di lu.

Chuyn danh sch t b mt vo tp ring bit
Gi s ta mun dng chung danh sch t b mt cho

29

ba chng trnh. Nu ct gi danh sch t nh lm th
s cn phi thay i tt c ba chng trnh ny khi Betty
quyt nh rng t b mt ca c s l swine thay v
oyster. iu ny c th thnh phin phc, c bit khi
xem xt ti vic Betty li thng xuyn thch thay i
nh.
Cho nn, t danh sch t vo mt tp, v ri c
tp ny thu c danh sch t vo trong chng trnh.
lm iu ny, cn to ra mt knh vo/ra c gi l
tc hiu tp. Chng trnh Perl ca bn s t ng ly
ba tc hiu tp gi l STDIN, STDOUT v STDERR,
tng ng vi ba knh vo ra chun cho chng trnh
UNIX. Chng ta cng dng tc hiu STDIN c
d liu t ngi chy chng trnh. By gi, y ch l
vic ly mt tc hiu khc gn vi mt tp do ta to
ra.
Sau y l mt on m nh lm iu :
sub init_words {
open (WORDSLIST, wordslist);
while ($name = <WORDSLIST>) {
chop ($name);
$word = <WORDSLIST>;
chop($word);
$words{$name} = $word;
}
close (WORDSLIST);
}
Ti t n vo mt chng trnh con cho ti c
th gi phn chnh ca chng trnh khng b ln xn.
iu ny cng c ngha l vo thi im sau (hng dn:
mt vi ln n li cuc i do ny), ti c th thay i
ni ct gi danh sch t, hay thm ch nh dng ca

30

danh sch.
nh dng c chn bt k cho danh sch t l mt
khon mc trn mt dng, vi tn v t, lun phin. Cho
nn, vi c s d liu hin ti ca chng ta, chng ta c
ci ta nh th ny:
fred
camel
barney
llama
betty
oyster
wilma
oyster
Ton t open() to ra mt tc hiu tp c tn
WORDSLIST bng cch lin kt n vi mt tp mang
tn wordslist trong danh mc hin ti. Lu rng tc
hiu tp khng c k t l l pha trc n nh ba kiu
bin vn c. Cng vy, tc hiu tp ni chung l ch
hoa - mc du chng khng nht thit phi l nh th -
bi nhng l do s nu chi tit v sau.
Chu trnh while c cc dng t tp wordslist (qua
tc hiu tp WORDSLIST) mi ln mt dng. Mi
dng c ct gi trong bin $name. Khi t n cui
tp th gi tr cho li bi ton t <WORDSLIST> l xu
rng
*
, m s sai cho cho trnh while, v kt thc n.
l cch chng ta i ra cui.
Mt khc, trng hp thng thng l ch chng
ta c mt dng (k c du dng mi) vo trong

*
V mt k thut th y li l undef, nhng cng gn cho tho
lun ny

31

$name. Trc ht, ta b du dng mi bng vic dng
ton t chop(). Ri, ta phi c dng tip ly t b
mt, gi n trong bin $word. N na cng phi b du
dng mi i.
Dng cui cng ca chu trnh while t $word vo
trong %words vi kho $name, cho nn phn cn li ca
chng trnh c th truy nhp vo n v sau.
Mt khi tp c c xong th c th b tc
hiu tp bng ton t close(). (Tc hiu tp du sao
cng c t ng ng li khi chng trnh thot ra,
nhng ti ang nh lm cho gn.)
nh ngha chng trnh con ny c th i sau hay
trc chng trnh con khc. V chng ta gi ti chng
trnh con thay v t %words vo ch bt u ca chng
trnh, cho nn mt cch bao qut tt c nhng iu
ny c th ging th ny:
#! /usr/bin/perl
&init_words;
print Tn bn l g? ;
$name = <STDIN> ;
chop($name);
if ($name =~ /^randal\b/i ) { # tr li cch khc
print Xin cho, Randal! May qu anh y!\n;
} else {
print Xin cho, $original_name!\n; # cho thng
thng
print T b mt l g? ;
$guess = <STDIN>;
chop($guess);
while ( ! &good_word($name, $guess)) {
print Sai ri, th li i. T b mt l g?;
$guess = <STDIN>;
chop($guess);

32

}
}
## chng trnh con t y xung
sub init_words {
open (WORDSLIST, wordslist);
while ($name = <WORDSLIST>) {
chop ($name);
$word = <WORDSLIST>;
chop($word);
$words{$name} = $word;
}
close (WORDSLIST);
}
sub good_word {
local($somename, $someguess) = @_; # tn tham
bin
$somename =~ s/\W.*//; # b mi th sau t u
$somename =~ tr/A-Z/a-z/; # mi th thnh ch
thng
if ($somename eq randal) { # khng nn on
1; #gi tr cho li l true
} elsif (($words{$somename} || cu knh) eq
$someguess) {
1; # gi tr cho li l true
} else {
0; # cho li gi tr false
}
}
By gi n bt u trng ging mt chng trnh
trng thnh hon ton. Ch n dng thc hin c
u tin l li gi ti &init_words. Khng c tham bin
no c truyn c, cho nn chng ta c t do b i
du ngoc trn. Cng vy, gi tr cho li khng c
dng trong tnh ton thm, th cng l tt v ta khng
cho li iu g ng . (Gi tr ca close() thng
thng l ng.)

33

Ton t open() cng c dng m cc tp a
ra, hay m chng trnh nh tp ( c biu din ngn
gn). Tuy th, vic vt ht v open() s c nu v sau
trong cun sch ny, trong Chng 10, Tc hiu tp v
kim tra tp.

m bo mt lng an ton gin d
Danh sch cc t b mt phi thay i t nht mt
ln mi tun! ng Trng ban danh sch t b mt ku
ln. Thi c, chng ta khng th buc danh sch ny
khc i, nhng chng ta c th t nht cng a ra mt
cnh bo nu danh sch t b mt cn cha c thay
i trong hn mt tun.
Cch tt nht lm iu ny l trong chng trnh
con &init_words - chng ta nhn vo tp . Ton t
Perl -M cho li tui tnh theo ngy t mt tp hay tc
hiu tp c thay i t ln trc, cho nn ta ch cn
xem liu gi tr ny c ln hn by hay khng i vi
tc hiu tp WORDSLIST:
sub init_words {
open (WORDSLIST, wordslist);
if (-M WORDSLIST > 7) { # tun th theo ng li
quan liu
die Rt tic, danh sch t c hn by ngy
ri.;
}
while ($name = <WORDSLIST>) {
chop ($name);
$word = <WORDSLIST>;
chop($word);
$words{$name} = $word;
}

34

close (WORDSLIST);
}
Gi tr ca -M WORDSLIST c so snh vi by,
v nu ln hn, th th ta vi phm vo ng li ri. Ti
y, ta thy mt ton t mi, ton t die, m cho in ra
mt thng bo trn thit b cui
*
, v b chng trnh
trong mt c b nho ri xung.
Phn cn li ca chng trnh vn khng i, cho
nn trong mi quan tm ti vic tit kim cy ci, ti s
khng lp li n y.
Bn cnh vic ly tui ca tp, ta cng c th tm ra
ngi ch ca n, kch c, thi gian truy nhp, v mi
th khc m UNIX duy tr v tp. Nhiu iu hn c
trnh by trong Chng 10.

Cnh bo ai khi mi vic i sai
Xem c th lm cho h thng b sa ly th no khi
gi mt mu th in t mi ln cho mt ai on t
b mt ca h khng ng. Cn sa i mi chng trnh
con &good_word (nh c tnh m un) v c tt c thng
tin ngay y.
Th s c gi cho bn nu bn g a ch th ca
ring mnh vo ch m chng trnh ni a ch bn
y. y l iu phi lm - ngay trc khi tr 0 v t
chng trnh con, to ra mt tc hiu tp m thc ti l
mt tin trnh (mail), ging nh:
sub good_word {

*
Thc ti l STDERR, nhng y thng thng l mn hnh

35

local($somename, $someguess) = @_; # tn tham
bin
$somename =~ s/\W.*//; # b mi th sau t u
$somename =~ tr/A-Z/a-z/; # mi th thnh ch
thng
if ($somename eq randal) { # khng nn on
1; #gi tr cho li l true
} elsif (($words{$somename} || cu knh) eq
$someguess) {
1; # gi tr cho li l true
} else {
open(MAIL, |mail a_ch_bn__y);
print MAIL tin xu: $somename on
$someguess\n;
0; # cho li gi tr false
}
}
Cu lnh mi th nht y l open(), c mt k
hiu ng ng (|) trong tn tp. y l mt ch dn c
bit rng ang m mt ch lnh thay v mt tp. V
ng ng l ti ch bt u ca ch lnh nn ang m
mt ch lnh c th ghi ln n. (Nu bn t ng
ng ti cui thay v u th bn c th c ci ra ca ch
lnh.)
Cu lnh tip, print, ch ra rng mt tc hiu tp
gia t kho print v gi tr c in ra chn tc hiu tp
lm ci ra, thay v STDOUT
*
. iu ny c ngha l
thng bo s kt thc nh ci vo cho ch lnh mail.
Cui cng, ng tc hiu tp, m s bt u
mail gi d liu ca n theo cch ca n.

*
V mt k thut th tc hiu tp ny hin c chn. iu s
c ni nhiu ti v sau.

36

cho ng, chng ta c th gi cu tr li ng
cng nh cu tr li sai, nhng ri ai c qua vai ti
(hay np trong h thng th) trong khi ti ang c th
m c th ly qu nhiu thng tin c ch.
Perl c th cng gi c cc lnh vi vic kim sot
chnh xc trn danh sch i, m cc tc hiu tp, hay
thm ch li ra c bn sao ca chng trnh hin ti, v
thc hin hai (hay nhiu) bn sao song song. Backquotes
(ging nh backquotes ca v) cho mt cch d dng
nm c ci ra ca mt ch lnh nh d liu. Tt c
nhng iu ny s c m t trong Chng 14, Qun l
tin trnh, cho nn bn nh c.

Nhiu tp t b mt trong danh mc hin ti
Thay i nh ngha ca tn tp t b mt mt cht.
Thay v tp c t tn l wordslist, th tm bt k ci g
trong danh mc hin ti m c tn cng l .secret. Vi
lp v, ni:
echo *.secret
thu c mt lit k ngn gn cho tt c cc tn ny.
Nh lt na bn s thy, Perl dng mt c php tn
chm tng t.
ly li nh ngha &init_words :
sub init_words {
while ($filename = <*.secret>) {
open (WORDSLIST, $filename);
if (-M WORDSLIST > 7) {
while ($name = <WORDSLIST>) {
chop ($name);
$word = <WORDSLIST>;

37

chop($word);
$words{$name} = $word;
}
}
close (WORDSLIST);
}
}
Trc ht, ti bao mt chu trnh while mi quanh
phn ln chng trnh con ca bn c. iu mi y l
ton t <*.secret>. iu ny c gi l nm tn tp, bi
l do lch s. N lm vic rt ging <STDIN>, ch mi
ln c truy nhp ti, n cho li gi tr tip: tn tp k
tip snh vi mu ca v, trong trng hp ny l
*.secret. Khi khng c tn tp thm na c cho li th
nm tn tp cho xu rng
*
.
Cho nn nu danh mc hin ti c cha fred.secret
v barney.secret, th $filename l barney.secret bc u
qua chu trnh while (tn ti theo trt t sp ca bng ch).
bc th hai, $filename l fred.secret. V khng c tnh
hung th ba v nm cho li xu rng khi ln th ba
c gi ti, lm cho chu trnh while thnh sai, gy ra
vic ra khi chng trnh con.
Bn trong chu trnh while, chng ta m tp v kim
chng rng n gn y (t hn by ngy t ln sa i
trc). Vi nhng tp gn, chng ta duyt qua nh
trc.
Ch rng nu khng c tp no snh vi *.secret v
li t hn by ngy th chng trnh con s ra m khng
t bt k t b mt no vo mng %words. iu c
ngha l mi ngi s phi dng t cu knh. Th cng

*
Li undef ln na

38

c. (Vi m tht, ti s thm mt kim tra no v
s cc trong %words trc khi cho li, v die nu n
khng tt. Xem ton t keys() khi ly mng kt hp trong
Chng 5, Mng kt hp.)

Nhng chng ta bit h l ai!
c ri, chng ta hi tn ngi dng khi thc ra
c th ly tn ca ngi dng hin ti t h thng, bng
vic dng mt vi dng nh:
@password = getpwuid($<); # ly d liu mt hiu
$name = $password[6]; # ly trng GCOS
$name =~ s/,.*//; # vt i mi th sau du phy u tin
Dng u tin dng s hiu ngi dng ID ca
UNIX (thng c gi l UID), t ng hin din trong
bin Perl $<. Ton t getpwuid() (c t tn ging nh
trnh th vin chun) ly s hiu UID v cho li thng
tin t tp mt hiu (hay c th mt s c s d liu khc)
nh mt danh sch. Chng nh du thng tin ny trong
mng @password.
Khon mc th by ca mng @password (ch s 6)
l trng GCOS, m thng l mt xu c cha danh
sch cc gi tr cc nhau bi du phy. Gi tr u tin
ca xu thng l tn y ca ngi.
Mt khi hai cu lnh u ny hon tt th chng
c ton b trng GCOS trong $name. Tn y ch l
phn th nht ca xu trc du phy u tin, cho nn
cu lnh th ba vt i mi th sau du phy th nht.
Gn tt c nhng iu vi phn cn li ca
chng trnh (nh c sa bi hai thay i chng

39

trnh con khc)
#! /usr/bin/perl
&init_words;
@password = getpwuid($<); # ly d liu mt hiu
$name = $password[6]; # ly trng GCOS
$name =~ s/,.*//; # vt i mi th sau du phy u tin
if ($name =~ /^randal\b/i ) { # tr li cch khc
print Xin cho, Randal! May qu anh y!\n;
} else {
print Xin cho, $name!\n; # cho thng thng
print T b mt l g? ;
$guess = <STDIN>;
chop($guess);
while ( ! &good_word($name, $guess)) {
print Sai ri, th li i. T b mt l g?;
$guess = <STDIN>;
chop($guess);
}
}

sub init_words {
while ($filename = <*.secret>) {
open (WORDSLIST, $filename);
if (-M WORDSLIST > 7) {
while ($name = <WORDSLIST>) {
chop ($name);
$word = <WORDSLIST>;
chop($word);
$words{$name} = $word;
}
}
close (WORDSLIST);
}
}
sub good_word {
local($somename, $someguess) = @_; # tn tham
bin

40

$somename =~ s/\W.*//; # b mi th sau t u
$somename =~ tr/A-Z/a-z/; # mi th thnh ch
thng
if ($somename eq randal) { # khng nn on
1; #gi tr cho li l true
} elsif (($words{$somename} || cu knh) eq
$someguess) {
1; # gi tr cho li l true
} else {
open(MAIL, |mail a_ch_bn__y);
print MAIL tin xu: $somename on
$someguess\n;
0; # cho li gi tr false
}
}
Ch rng khng cn cn hi ngi dng v tn
ngi y na - chng ta bit n!
Perl cung cp nhiu trnh truy nhp c s d liu h
thng li ra nhng gi tr t c s d liu mt hiu,
nhm, my ch, mng, dch v v giao thc. C vic tra
cu ring (nh c trnh by trn) v vic duyt s
ln cng c Perl h tr.

Lit k cc t b mt
Ri ng ph trch danh sch t b mt li mun c
mt bo co v tt c nhng t b mt hin ang dng,
v chng c n u. Nu gt sang bn chng trnh t
b mt mt lc, s c thi gian vit mt chng trnh
bo co cho ng ph trch.
Trc ht, ly ra tt c cc t b mt, bng vic n
cp mt on m trong chng trnh con &init_words:
while ($filename = <*.secret>) {

41

open (WORDSLIST, $filename);
if (-M WORDSLIST > 7) {
while ($name = <WORDSLIST>) {
chop ($name);
$word = <WORDSLIST>;
chop($word);
### cht liu mi s a vo y
}
}
close (WORDSLIST);
}
Ti im c nh du cht liu mi s a vo
y, cn bit ba iu: tn ca tp (trong $filename), tn
mt ai (trong $name), v rng t b mt ca mt ngi
(trong $Word). Sau y l ch dng cng c sinh bo
co ca Perl. nh ngha mt dng thc u trong
chng trnh (thng thng gn cui, ging nh chng
trnh con):
format STDOUT =
@<<<<<<<<<<<<<<< @<<<<<<<<<<
@<<<<<<<<<<<<<<
$filename, $name, $word
.
nh ngha dng thc ny bt u vi format
STDOUT =, v kt thc vi mt du chm. Hai dng
gia l chnh dng thc. Dng u ca dng thc ny l
dng nh ngha trng, xc nh s lng, chiu di v
kiu ca trng. Vi dng thc ny, chng c ba trng.
Dng i sau dng nh ngha trng bao gi cng l
dng gi tr trng. Dng gi tr cho mt danh sch cc
biu thc m s c tnh khi dng thc ny c dng,
v kt qu ca nhng biu thc s c gn vo trong
cc trng c xc nh trn dng trc .

42

Gi dng thc ny vi ton t write, nh th ny:
#!/usr/bin/perl
while ($filename = <*.secret>) {
open (WORDSLIST, $filename);
if (-M WORDSLIST < 7) {
while ($name = <WORDSLIST>) {
chop($name);
$word = <WORDSLIST>
chop($word);
write; # gi dng thc STDOUT ti STDOUT
}
}
close (WORDSLIST)
}
format STDOUT =
@<<<<<<<<<<<<<<< @<<<<<<<<<<
@<<<<<<<<<<<<<<
$filename, $name, $word
.
Khi dng thc ny c gi ti, Perl s tnh cc biu
thc trng v sinh ra mt dng m n gi ra tc hiu
tp STDOUT. V write l c gi mt ln mi khi i
qua chu trnh nn s thu c mt lot cc dng vi vn
bn theo ct, mi dng cho mt t b mt.
Hm. Chng cn cha c nhn cho cc ct. M iu
th cng d thi, ch cn thm vo dng thc trn u
trang, nh:
format STDOUT_TOP =
Page @<<
$%

Tn tp Tn T
========== ======== ==========
.

43

Dng thc ny mang tn STDOUT_TOP, v s
c dng u tin ngay khi gi ti dng thc STDOUT,
ri li sau 60 ln a ra STDOUT th n li c sinh ra.
Cc tiu ct y thng hng vi cc ct trong dng
thc STDOUT, cho nn mi th khp vo nhau.
Dng u tin trong dng thc ny ch ra mt vn
bn hng no (Page) cng vi vic nh ngha trng
ba k t. Dng sau l dng gi tr trng, y vi mt
biu thc. Biu thc ny l bin $%, gi s trang c in
ra - mt gi tr rt c ch trong dng thc u trang.
Dng th ba ca dng thc ny trng. V dng
ny khng cha bt k trng no nn dng sau n
khng phi l dng gi tr trng. Dng trng ny c
sao trc tip ln ci ra, to ra mt dng trng gia s
trang v tiu ct di.
Hai dng cui ca dng thc ny cng khng cha
trng no, cho nn chng c sao trc tip ra ci ra.
Do vy dng thc ny sinh ra bn dng, mt trong c
mt phn b thay i qua mi trang.
Ch cn thm nh ngha ny vo chng trnh trc
l n lm vic. Perl n dng thc u trang t
ng.
Perl cng c cc trng c nh tm hay cn l
phi, v h tr cho min on c rt kn. S c nhiu
vn v iu ny hn khi i vo cc dng thc trong
Chng 11, Dng thc.


44

Lm cho danh sch t c ng lu hn
Khi c qua cc tp *.secret trong danh mc hin ti,
c th tm thy cc tp qu c. Cho ti nay, ta thng
nhy qua nhng tp ny. Nay i thm mt bc na - s
i tn chng thnh *.secret.old cho ls ca danh mc s
nhanh chng cho nhng tp no qu c, n thun theo
tn.
Sau y l cch thc th hin cho chng trnh con
&init_words vi sa i ny:
sub init_words {
while ($filename = <*.secret>) {
open (WORDSLIST, $filename);
if (-M WORDSLIST > 7) {
while ($name = <WORDSLIST>) {
chop ($name);
$word = <WORDSLIST>;
chop($word);
$words{$name} = $word;
}
} else { # i tn tp n ng hn
rename($filename, $filename.old);
}
close (WORDSLIST);
}
}
Ch n phn else mi ca vic kim tra tui. Nu
tp c hn by ngy, n s c i tn bng ton t
rename(). Ton t ny ly hai tham bin, i tp c tn
trong tham bin th nht thnh tn trong tham bin th
hai.
Perl c mt phm vi y cc ton t thao tc tp -
gn nh bt k ci g bn c th thc hin cho mt tp

45

trong chng trnh C, bn cng c th lm t Perl.

Duy tr c s d liu on ng cui cng
Cn gi li du vt khi no vic on ng gn nht
c thc hin cho mi ngi dng. Mt cu trc d
liu dng nh mi thong nhn th c v c l mng
kt hp. Chng hn, cu lnh:
$last_good{$name} = time ;
gn thi gian UNIX hin ti (mt s nguyn ln
qung 700 triu, ch ra s giy) cho mt phn t
ca %last_good c tn vi kho . Qua thi gian, iu
ny s dng nh cho mt c s d liu ch ra thi im
gn nht m t b mt c on ng cho tng
ngi dng gi ti chng trnh ny.
Nhng, mng li khng tn ti gia nhng ln gi
chng trnh. Mi ln chng trnh ny c gi th mt
mng mi li c hnh thnh, cho nn nhiu nht th to
ra c mng mt phn t v ri lp tc li qun mt n
khi chng trnh ra.
Ton t dbmopen() nh x mt mng kt hp vo
mt tp a (thc t l mt cp tp a) c xem nh
mt DBM. N c dng nh th ny:
dbmopen(%last_good, lastdb, 066);
$last_good($name) = time;
dbmclose(%last_good);
Cu lnh u tin thc hin vic nh x ny, dng
cc tn tp a ca lastdb.dir v lastdb.pag (cc tn ny l
tn thng thng cho DBM c gi l lastdb). Cc php
v tp UNIX c dng cho hai tp ny nu cc tp

46

phi c to ra (khi chng ln u tin c gp ti) l
0666. Mt ny c ngha l bt k ai cng c th c hay
ghi ln tp. (Cc bit php tp c m t trong manpage
chmod(2).)
Cu lnh th hai ch ra rng chng dng mng kt
hp c nh x ny ht nh mng kt hp thng
thng. Tuy nhin, vic to ra hay cp nht mt phn t
ca mng s t ng cp nht tp a to nn DBM. V,
khi mng c truy nhp ti ln cui th gi tr bn trong
mng s ti trc tip t hnh nh a. iu ny cho mng
kt hp cuc sng tri bn ngoi li gi hin thi ca
chng trnh - mt s bn lu ca ring n.
Cu lnh th ba ngt mng kt hp ra khi DBM,
ging ht thao tc ng tp close().
Bn c th chn thm ba cu lnh ny vo ngay u
cc nh ngha chng trnh con.
Mc du cc cu lnh c chn thm ny duy tr c
s d liu l tt (v thm ch cn to ra n trong ln
u), chng vn khng c cch no xem xt thng tin
trong . lm iu , c th to ra mt chng trnh
nh tch bit trng i th nh th ny:
#!/usr/bin/perl
dbmopen(%last_good, lastdb, 0666);
foreach $name (sort keys(%last_good) {
$when = $last_good{$name};
$hours = (time - $when) / 3600; # tnh gi qua
write;
}
format STDOUT =
User @<<<<<<<<<<: ln on ng cui cng l @<<<
gi qua.
$name, $hour

47

.
Chng c vi ton t mi y: chu trnh foreach,
sp xp mt danh sch, v ly kho ca mng.
Trc ht, ton t keys() ly mt tn mng kt hp
nh mt i v cho li mt danh sch tt c cc kho ca
mng theo mt th t khng xc nh no . (iu
ny ht nh ton t keys trong awk.) Vi mng %words
c xc nh trc y, kt qu l mt ci g ta nh
fred, barney, betty, wilma, theo mt th t khng xc nh.
Vi mng %last_good, kt qu s l mt danh sch ca
tt c ngi dng on thnh cng t b mt ca ring
mnh.
Ton t sort sp xp theo th t bng ch (ht nh
vic truyn mt tp vn bn qua ch lnh sort). iu ny
bo m rng danh sch c x l bi cu lnh foreach
bao gi cng theo th t bng ch.
Thn ca chu trnh foreach np vo hai bin c
dng trong dng thc STDOUT, v ri gi ti dng thc
. Ch rng chng on ra tui ca mt phn t bng
cch tr thi gian UNIX ct gi (trong mng) t thi
gian hin ti (nh kt qu ca time) v ri chia cho 3600
( chuyn t giy sang gi).
Perl cng cung cp nhng cch thc d dng to
ra v duy tr cc c s d liu hng vn bn (nh tp
mt hiu) v c s d liu bn ghi chiu di c nh (nh
c s d liu ng nhp ln cui do chng trnh login
duy tr). Nhng c s d liu ny s c m t trong
Chng 17, Thao tc c s d liu ngi dng.


48

Chng trnh cui cng
Sau y l chng trnh m cuc i do ny a
ti di dng cui cng bn c th chi vi chng.
Trc ht l chng trnh ni li cho:
#! /usr/bin/perl
&init_words;
@password = getpwuid($<); # ly d liu mt hiu
$name = $password[6]; # ly trng GCOS
$name =~ s/,.*//; # vt i mi th sau du phy u tin
if ($name =~ /^randal\b/i ) { # tr li cch khc
print Xin cho, Randal! May qu anh y!\n;
} else {
print Xin cho, $name!\n; # cho thng thng
print T b mt l g? ;
$guess = <STDIN>;
chop($guess);
while ( ! &good_word($name, $guess)) {
print Sai ri, th li i. T b mt l g?;
$guess = <STDIN>;
chop($guess);
}
}

dbmopen(%last_good, lastdb, 066);
$last_good($name) = time;
dbmclose(%last_good);
sub init_words {
while ($filename = <*.secret>) {
open (WORDSLIST, $filename);
if (-M WORDSLIST > 7) {
while ($name = <WORDSLIST>) {
chop ($name);
$word = <WORDSLIST>;
chop($word);
$words{$name} = $word;

49

}
}
close (WORDSLIST);
}
}
sub good_word {
local($somename, $someguess) = @_; # tn tham
bin
$somename =~ s/\W.*//; # b mi th sau t u
$somename =~ tr/A-Z/a-z/; # mi th thnh ch
thng
if ($somename eq randal) { # khng nn on
1; #gi tr cho li l true
} elsif (($words{$somename} || cu knh) eq
$someguess) {
1; # gi tr cho li l true
} else {
open(MAIL, |mail a_ch_bn__y);
print MAIL tin xu: $somename on
$someguess\n;
0; # cho li gi tr false
}
}
Tip , c b in t b mt:
#! /usr/bin/perl
while ($filename = <*.secret>) {
open (WORDSLIST, $filename);
if (-M WORDSLIST > 7) {
while ($name = <WORDSLIST>) {
chop ($name);
$word = <WORDSLIST>;
chop($word);
write; # gi dng thc STDOUT cho
STDOUT
}
}
close(WORDSLIST);

50

}
format STDOUT =
@<<<<<<<<<<<<<<< @<<<<<<<<<<
@<<<<<<<<<<<<<<
$filename, $name, $word
.
format STDOUT_TOP =
Page @<<
$%

Tn tp Tn T
========== ======== ==========
.
V cui cng, l chng trnh hin th t c
dng ln cui cng:
#!/usr/bin/perl
dbmopen(%last_good, lastdb, 0666);
foreach $name (sort keys(%last_good) {
$when = $last_good{$name};
$hours = (time - $when) / 3600; # tnh gi qua
write;
}
format STDOUT =
User @<<<<<<<<<<: ln on ng cui cng l @<<<
gi qua.
$name, $hour
.
Cng vi danh sch t b mt (cc tp c tn
something.secret trong danh mc hin ti) v c s d
liu lastdb.dir v lastdb.pag, bn c tt c nhng g
mnh cn.


51

Bi tp
Thng thng, mi chng s kt thc vi mt s
bi tp, li gii cho chng s c trong Ph lc A, Tr li
bi tp. Vi chuyn i do ny, li gii c cho
trn.
1. G chng trnh th d trn vo my ri cho n chy.
(Bn cn to ra danh sch t b mt na.) Hi thy
Perl ca bn nu bn cn tr gip.



52



53

2


D liu
v hng


D liu v hng l g?
V hng l loi d liu n gin nht m Perl thao
tc. Mt v hng th hoc l mt s (ging 4 hay
3.25e20) hay mt xu cc k t (ging Xin cho hay
Gettysburg Address). Mc du bn c th ngh v s v
xu nh nhng vt rt khc nhau, Perl dng chng gn
nh i ln cho nhau, cho nn ti s m t chng vi
nhau.
Mt gi tr v hng c th c tc ng bi cc
ton t (ging nh php cng hay ghp tip), ni chung
cho li mt kt qu v hng. Mt gi tr v hng c
th c ct gi vo trong mt bin v hng. Cc v
hng c th c c t tp v thit b, v c ghi ra.
Trong chng ny:

D liu v hng l g?
S
Xu
Ton t
Bin v hng
Ton t trn bin v
hng
<STDIN> xem nh gi
tr v hng
In ra vi print()
Gi tr undef


54


S
Mc du v hng hoc l mt s hay mt xu, iu
cng c ch l nhn vo cc s v xu tch bit nhau
trong mt chc. Ta s xt s trc ri n xu...

Tt c cc s c cng dng thc bn trong
Nh bn s thy trong vi on tip y, bn c th
xc nh c s nguyn (ton b s, ging nh 14 hay
342) v s du phy ng (s thc vi du chm thp
phn, nh 3.14, hay 1.35 ln 10
25
). Nhng bn trong,
Perl ch tnh vi cc gi tr du phy ng chnh xc
gp i. iu ny c ngha l khng c gi tr nguyn
bn trong Perl - mt hng nguyn trong chng trnh
c x l nh gi tr du phy ng tng ng. Bn
c l khng (hay quan tm nhiu) n vic chuyn
i, nhng bn nn dng tm kim php ton nguyn
(xem nh ngc vi cc php ton du phy ng), v
khng c to no.

Hng k hiu ng
Hng k hiu l mt cch biu din mt gi tr
trong vn bn chng trnh Perl - bn cng c th gi
iu ny l mt hng trong chng trnh mnh, nhng ti
s dng thut ng hng k hiu. Hng k hiu l cch
thc biu din d liu trong m chng trnh gc ca
chng trnh bn nh ci vo cho trnh bin dch Perl.
(D liu c c t hay ghi ln cc tp c x l

55

tng t, nhng khng ng nht.)
Perl chp nhn tp hp y cc hng k hiu du
phy ng c sn cho ngi lp trnh C. S c hay
khng c du chm thp phn c php (k c tin
t cng hay tr tu chn), cng nh phn ch s m ph
thm (k php lu tha) vi cch vit E. Chng hn:
1.25 # mt phn t
7.25e45 # 7.25 ln 10 m 45 (mt s ln)
-6.5e24 # m 6.5 ln 10 m 24 (mt s m ln)
-12e-24 # m 12 ln 10 m -24 (mt s m rt nh)
-1.2E-23 # mt cch khc ni iu .

Hng k hiu nguyn
Cc hng k hiu nguyn cng l trc tip, nh
trong:
12
15
-2004
3485
Bn ng bt u mt s bng 0, v Perl h tr cho
hng k hiu h tm v h mi su (ht nh kiu C). S
h tm bt u bng s 0 ng u, cn s h mi su
bt u bng 0x hay 0X
*
. Cc ch s h mi su A n
F (trong c hai kiu ch hoa thng) biu th cho cc
gi tr s qui c t 10 n 15. Chng hn:
0377 # 377 h tm, ging nh 255 thp phn

*
Ch bo s khng ng u ch c tc dng vi cc hng k hiu
- khng c tc dng cho vic chuyn i t ng xu sang s. bn
c th chuyn i mt xu d liu ging nh mt gi tr h tm v
h mi su thnh mt s vi oct() hay hex().

56

-0xff # FF h mi su m, ht nh -255 thp phn

Xu
Xu l cc dy k t (nh Xin cho). Mi k t l
mt gi tr 8-bit trong ton b tp 256 k t (khng c g
c bit v k t NUL nh trong C).
Xu ngn nht c th c th khng c k t no.
Xu di nht chim trn b nh ca bn (mc du bn s
chng th no lm g nhiu vi n c). iu ny ph hp
vi nguyn l khng c gii hn sn m Perl cho php
mi c hi. Cc xu in hnh l cc dy in c gm
cc ch v s v du ngt trong phm vi ASCII 32 ti
ASCII 126. Tuy nhin, kh nng c bt k k t no t
0 ti 255 trong mt xu c ngha l bn c th to ra,
qut qua, v thao tc d liu nh phn th nh cc xu -
mt ci g m phn ln cc trnh tin ch UNIX khc
s gp kh khn ln. (Chng hn, bn c th v vu li
UNIX bng vic c n vo trong xu Perl, tin hnh
thay i, v ghi kt qu li.)
Ging nh s, xu c biu din hng k hiu (cch
thc bn biu din xu trong chng trnh Perl). Cc xu
hng k hiu c theo hai hng v: xu du nhy n v
xu du nhy kp.

Xu du nhy n
Xu du nhy n l mt dy cc k t c bao
trong du nhy n. Du nhy n khng phi l mt
phn ca bn thn xu - chng ch c Perl xc nh

57

ch bt u v kt thc ca xu. Bt k k t no nm
gia cc du nhy (k c du dng mi, nu xu vn cn
tip tc sang dng sau) u l hp php bn trong xu.
Hai ngoi l: ly c mt du nhy n trong mt
xu c nhy n, t trc n mt du s cho ngc.
V ly c du s cho ngc trong mt xu c
nhy n, t trc du s cho ngc mt du s cho
ngc na. Di dng hnh nh:
hello # nm k t: h, e, l, l, o
dont\t # nm k t: d, o, n, nhy n, t
# xu khng (khng k t)
silly\\me # silly, theo sau l mt s cho ngc, sau l
me
hello\n # hello theo sau l s cho ngc v n
hello
there # hello, dng mi, there (ton b 11 k t)
Ch rng \n bn trong mt xu c nhy n th
khng c hiu l dng mi, nhng l hai k t s cho
ngc v n. (Ch khi s cho ngc i theo sau bi mt
s cho ngc khc hay mt du nhy n th mi mang
ngha c bit.)

Xu du nhy kp
Xu du nhy kp hnh ng ht nh xu trong C.
Mt ln na, n li l dy cc k t, mc du ln ny
c bao bi du ngoc kp. Nhng by gi du s cho
ngc ly ton b sc mnh ca n xc nh cc k t
iu khin no , hay thm ch bt k k t no qua cc
biu din h tm hay h mi su. y l mt s xu du
nhy kp:
hello world\n # hello world, v dng mi

58

new \177 # new, du cch v k t xo (177 h tm)
coke\tsprite # coke, du tab, v sprite
Du s cho c th ng trc nhiu k t khc nhau
hm nhng iu khc nhau (v in hnh n c
gi l li thot s cho). Danh sch y ca cc li
thot xu nhy kp c cho trong Bng 2-1.
Bng 2-1 Li thot s cho ngc xu nhy kp
Kt cu ngha
\n dng mi
\r quay li
\t tab
\f ko giy
\b Xo li
\v tab chiu ng
\a Chung
\e li thot
\007 bt k gi tr ASCII h tm (
y, 007 = chung)
\x7f gi tr ASCII h mi su (
y, 7f = xo)
\cC bt k k t iu khin no (
y, control C)
\\ s cho ngc
\ du nhy kp
\l ch tip l ch thng
\L tt c cc ch i sau cho ti \E
l ch thng
\u Ch tip l ch hoa
\U tt c cc ch i sau cho ti \E
l ch hoa
\E Kt thc \L hay \U

59


Mt tnh nng khc ca xu nhy kp l ch chng
cho php chen ln cc bin, ngha l mt s tn bin no
bn trong xu c thay th bi gi tr hin ti ca
chng khi xu c dng. Chng khng c gii
thiu mt cch chnh thc l cc bin trng nh th no
(ngoi tr trong cuc i do), cho nn ti s quay li vn
ny sau.

Ton t
Mt ton t to ra mt gi tr mi (kt qu) t mt
hay nhiu gi tr khc (cc ton hng). Chng hn, + l
mt ton t v n nhn hai s (ton hng, nh 5 v 6), v
to ra mt gi tr mi (11, kt qu).
Cc ton t v biu thc ca Perl ni chung l
siu tp ca cc ton t c trong hu ht cc ngn ng
lp trnh ta ALGOL/Pascal, nh C. Mt ton t bao gi
cng trng i cc ton hng s hay xu (hay c th l t
hp ca c hai). Nu bn cung cp mt ton hng xu
ch ang cn ti mt s, hay ngc li, th Perl s t
ng chuyn ton hng bng vic dng cc qui tc
kh trc gic, m s c nu chi tit trong mc
Chuyn i gia s v xu, di y.

Ton t s
Perl cung cp cc ton t cng, tr, nhn, chia in
hnh thng thng, vn vn. Chng hn:
2 + 3 # 2 cng 3, hay 5

60

5.1 - 2.4 # 5.1 tr i 2.4, hay 2.7
3 * 12 # 3 ln 12 = 36
14 / 2 # 14 chia cho 2, hay 7
10.2 / 0.3 # 10.2 chia cho 0.3, hay 34
10 / 3 # bao gi l php chia du phy ng, nn
3.333...
Bn cnh , Perl cung cp ton t lu tha kiu
FORTRAN, m nhiu ngi tng mong mi cho
Pascal v C. Ton t ny c biu din bng hai du
sao, nh 2**3, chnh l hai lu tha ba, hay tm. (Nu
kt qu khng th khp trong s du phy ng chnh
xc gp i, nh mt s m m li lu tha theo s
khng nguyn, hay mt s ln ly lu tha theo s ln,
th bn s nhn c li nh mnh.)
Perl cng h tr cho ton t ly ng d modulus,
nh trong C. Gi tr ca biu thc 10 % 3 l s d khi
ly mi chia cho ba, chnh l mt. C hai gi tr
trc ht c a v gi tr nguyn, cho nn 10.5 % 3.2
c tnh l 10 % 3.
Cc ton t so snh logic l ht nh cc ton t c
trong C (< <= == >= > !=), v vic so snh hai gi tr v
mt s s cho li mt gi tr ng hay sai. Chng hn,
3>2 cho li ng v ba ln hn hai, trong khi 5 != 5 cho
li sai v khng ng l nm li khng bng nm. Cc
nh ngha v ng v sai c ni ti v sau, nhng vi
hin ti, ngh v gi tr cho li ging nh chng trong
C - mt l ng, cn khng l sai. (Cc ton t ny s
c thm li trong Bng 2-2.)


61

Ton t xu
Cc gi tr xu c th c ghp vi ton t chm
(.). (Qu th, l du chm n.) iu ny khng lm
thay i xu, cng nh 2+3 khng lm thay i 2 hay 3.
Xu kt qu (di hn) vy l c sn cho tnh ton thm
hay c ct gi trong mt bin.
hello . world # ht nh helloworld
hello wordl . \n # ht nh hello world\n
fred . . barney # ht nh fred barney
Ch rng vic ghp ni phi c gi tng minh
ti ton t ., khng ging awk m bn n thun phi
nh du hai gi tr gn ln nhau.
Mt tp cc ton t cho xu khc l ton t so snh
xu. Cc ton t ny ta FORTRAN, nh lt thay cho
b hn, vn vn. Cc ton t so snh cc gi tr ASCII
ca cc k t ca xu theo cch thng thng. Tp y
cc ton t so snh (cho c s v xu) c nu trong
Bng 2-2.
Bng 2-2. Cc ton t so snh s v xu
Php so snh S Xu
Bng == eq
Khng bng != ne
B hn < lt
Ln hn > gt
B hn hay bng <= le
Ln hn hay bng >= ge


62

Bn c th t hi ti sao c cc ton t phn tch
cho s v xu vy, nu s v xu c t ng chuyn
i ln cho nhau. Xt hai gi tr 7 v 30. Nu c so
snh nh s th 7 hin nhin b hn 30, nhng nu c
so snh theo xu, th xu 30 s ng trc xu 7 (v
gi tr ASCII ca 3 th b hn gi tr ASCII ca 7), v do
l b hn. Cho nn, khng ging awk, Perl i hi
bn xc nh ng kiu so snh, liu l s hay xu.
Ch rng cc php so snh s v xu v i th
ngc vi nhng iu xy ra cho ch lnh test ca
UNIX, m thng dng k hiu -eq so snh s cn =
so snh xu.
Vn cn mt ton t xu khc l ton t lp li xu,
bao gm mt k t ch thng n gin x. Ton t ny
ly ton hng tri ca n (mt xu), v thc hin nhiu
vic ghp bn sao ca xu theo s ln do ton hng
bn phi ch ra (mt s). Chng hn:
fred x 3 # l fredfredfred
barney x (4+1) # l barney x 5 hay
# barneybarneybarneybarneybarney
(3+2) x 4 # l 5 x 4, hay thc s 5 x 4, l
5555
Th d cui cng ng xem xt chm ri. Cc du
ngoc trn (3+2) buc cho phn ny ca biu thc cn
phi c tnh trc, cho nm. (Cc du ngoc y
lm vic ging nh trong C, hay trong ton hc chun.)
Nhng ton t lp li xu cn mt xu cho ton hng bn
tri, cho nn s 5 c chuyn thnh xu 5 (dng cc
qui tc s c m t chi tit v sau), thnh xu mt k
t. Xu mi ny ri c sao ln bn ln, cho xu bn k
t 5555. Ch rng nu o ngc trt t cc ton hng,

63

th s lm nm bn sao ca xu 4, cho 44444. iu ny
ch ra rng vic lp li xu l khng giao hon.
S m bn sao (ton hng bn phi) trc ht s b
cht ct i cho gi tr nguyn (4.8 tr thnh 4) trc
khi c s dng. S m bn sao b hn mt s gy ra
kt qu l xu rng (chiu di khng).

Th t u tin v lut kt hp ca ton t
Th t u tin ca ton t xc nh ra cch gii
quyt trng hp khng r rng khi no dng ton t
no trn ba ton hng. Chng hn, trong biu thc
2+3*4, s thc hin php cng trc hay php nhn
trc? Nu lm php cng trc th s c 5*4, hay 20.
Nhng nu lm php nhn trc (nh vn c dy
trong gi ton) th c 2+12, hay 14. May mn l Perl
chn nh ngha ton hc thng thng, thc hin nhn
trc. Bi iu ny, ni nhn c s u tin cao hn
cng.
Bn c th ph ro trt t u tin bng vic dng
du ngoc. Bt k ci g trong du ngoc c tnh ht
trc khi ton t bn ngoi du ngoc c p dng (ht
nh bn hc trong gi ton). Cho nn nu ti thc s
mun cng trc khi nhn, th ti c th vit (2+3)*4,
cho 20. Cng vy, nu ti mun biu th rng php nhn
c thc hin trc php cng, ti c th trang im
thm nhng chng lm g, mt cp du ngoc trong
2+(3*4).
Trong khi u tin l trc gic cho php cng v
nhn th ta bt u lao vo vn thng hay phi

64

ng u vi, chng hn, phn bit th no i vi
php ghp xu v nng ln lu tha. Cch ng n
gii quyt iu ny l tra cu s s th t u tin ton
t ca Perl, c nu trong Bng 2-3. (Ch rng mt
s cc ton t cn cha c m t, v thc ra, thm ch
khng th xut hin bt k u trong cun sch ny,
nhng ch c lm iu lm bn hong s v vic c
chng.) Vi nhng ton t cng c trong C, th nhng
ton t c cng s th t u tin nh chng c trong
C (m ti c th chng bao gi nh c).
Bng 2-3: Lut kt hp v s u tin ca cc ton t
(thp nht n cao nht)

Lut
kt hp
Ton t
khng ton t danh sch
tri , (phy)
phi += v cc ton t khc (ton t gn)
phi ? : (ton t if/then/else ba ngi)
khng .. (ton t phm vi, cu t danh sch)
tri || (hoc logic)
tri && (v logic)
tri | ^ (hoc bit, hoc bit loi tr)
tri & (v bit)
khng == != <=> eq ne cmp (ton t bng)

65

Lut
kt hp
Ton t
khng < <= > >= lt le gt ge (ton t khng
bng)
khng Ton t mt ngi c tn
khng -r v (cc ton t kim tra tp)
*
khc
tri << >> (dch chuyn bit)
tri + - . (cng, tr, ghp xu)
tri * / % x (nhn, chia, ly d, lp xu)
tri =~ !~ (snh, khng snh)
phi ** (lu tha)
phi ! ~ - (ph nh logic, ph nh bit, ph
nh s)
khng ++ -- (t tng, t gim)

Trong s ny, bt k ton t cho no c s
u tin ln hn cc ton t c lit k trn n, v c s
u tin thp hn cc ton t c lit k di n. (iu
ny ngc li iu c l bn ang trng i, nhng n
ht nh trong sch con lc , v chng ti cng dng
ngc n xung na.) Cc ton t ti cng mc u
tin c gii quyt theo lut kt hp.
Ging nh vi s u tin, lut kt hp gii quyt trt

*
Perl 5.0 t hp cc ton t kim tra tp v ton t mt ngi c tn
vo cng mc s u tin

66

t ca cc php ton khi hai ton t c cng mc u tin
cng tc ng trn ba ton hng:
2 ** 3 ** 4 # 2 ** (3 ** 4), hay 2 ** 81, hay xp x 2.41e24
72 / 12 / 3 # (72 / 12) / 3, hay 6 / 3, hay 2
30 / 6 * 3 # (30/6)*3, hay 15
Trong trng hp th nht, ton t ** c lut kt
hp phi, cho nn cc du ngoc c p dng t bn
phi. So snh vi n, cc ton t * v / c lut kt hp
tri, cho tp cc du ngoc bn tri.

Chuyn i gia s v xu
Nu mt gi tr xu c dng nh mt ton hng
cho mt ton t s (chng hn, +), th Perl s t ng
chuyn xu thnh gi tr s tng ng, dng nh n
c a vo nh mt gi tr du phy ng
*
. Nhng
cht liu phi s ng ui v khong trng ng u
b b qua mt cch yn lng v l php, cho nn
123.45fred (vi du cch ng trc) chuyn thnh
123.45 vi li cnh bo
*
. Ti mt cc im ca iu
ny, mt ci g khng phi l s to no chuyn thnh
khng m khng c bo trc (nh xu fred c dng
nh s).
Ging vy, nu mt gi tr s c cho khi ang cn
ti mt gi tr xu (cho php ghp xu chng hn), th
gi tr s s c m rng thnh bt k xu no s c
in ra cho s . Chng hn, nu bn mun ghp ni X v

*
Cc gi tr h tm v h mi su khng c h tr trong chuyn
i t ng ny. dng hex() v oct() din gii cc gi tr h mi
su v tm.
*
Tr phi bn bt tu chn -w trn dng lnh

67

theo sau l kt qu ca 4 nhn vi 5 th bn c th lm
n gin l:
X.(4*5) # ht nh X.20, hay X20
(Nh rng cc du ngoc ny buc 4*5 phi c
tnh trc khi xem xt ton t ghp ni xu.)
Ni cch khc, bn khng thc s phi lo lng g v
liu bn c mt s hay mt xu (phn ln thi gian). Perl
thc hin mi chuyn i cho bn.
Bin v hng
Mt bin l mt tn gi cho mt ch cha gi c
mt hay nhiu gi tr. Tn ca bin l khng i trong
ton b chng trnh, nhng gi tr hay cc gi tr c
cha trong bin v c bn th li thay i i thay i
li trong sut thc hin chng trnh.
Mt bin v hng gi mt gi tr v hng ring
(biu th cho mt s, hay mt xu, hay c hai). Cc tn
bin v hng bt u vi du la v tip theo sau l
mt ch, ri th c th l nhiu ch, s hay du gch
thp. Ch hoa v ch thng l phn bit: bin $A l
khc bin $a. V tt c cc ch, s v gch thp c
ngha, cho nn:
$a_very_long_variable_that_ends_in_1
l khc vi
$a_very_long_variable_that_ends_in_2
Ni chung nn chn tn bin mang ngha no c
lin quan ti gi tr ca bin . Chng hn, $xyz123 c
l khng mang tnh m t nhiu lm nhng $line_length
th li c ngha.

68


Cc ton t trn bin v hng
Php ton thng dng nht trn bin v hng l
php gn, chnh l cch t mt gi tr cho mt bin.
Ton t gn ca Perl l du bng (ging nh C hay
FORTRAN), tn bin bn v tri v cho gi tr ca
biu thc bn v phi, kiu nh:
$a = 17; # cho $a gi tr 17
$b = $a + 3; # cho $b gi tr hin ti ca $a cng vi 3
(20)
$b = $b * 2; # cho $b gi tr ca $b c nhn vi 2 (40)
Ch rng dng cui dng bin $b hai ln: khi ly
c gi tr ca n ( v phi du =), v khi xc nh
xem phi t biu thc tnh c vo u ( v tri ca
du =). iu ny l hp l, an ton v thc ra, kh thng
dng. Thc ra, n thng dng n mc chng s thy
trong vi pht y l c th vit iu ny bng vic dng
cch vit tt qui c.
Bn c th ch rng cc bin v hng bao gi
cng c tham chiu bng du $ ng trc. Trong lp
v, bn dng $ ly mt gi tr, nhng $ ng mt
mnh gn mt gi tr mi. Trong awk hay C, bn
cho $ ring hon ton. Nu bn phi vit i vit li cc
bin rt nhiu th bn s thy mnh ngu nhin b g sai.
Thng hay b vy. (Gii php ca ti l chm dt vic
vit chng trnh v, awk v C, nhng iu li c th
khng c tc dng cho bn.)
Vic gn v hng c th c dng nh mt gi tr
cng nh mt php ton, nh trong C. Ni cch khc, $a
= 3 c mt gi tr, cng nh $a+3 c mt gi tr. Gi tr

69

chnh l s c gn, cho nn gi tr ca $a = 3 l 3. Mc
du iu ny dng nh c v k l lc thong nhn, vic
dng mt php gn nh mt gi tr li c ch nu bn
mun gn mt gi tr trung gian trong mt biu thc cho
mt bin, hay nu bn mun n gin sao cng mt gi
tr cho mt hay nhiu bin. Chng hn:
$b = 4 + ($a = 3); # gn 3 cho $a, ri cng kt qu
vi 4 t vo $b, c 7
$d = ($c = 5); # sao 5 vo $c, v ri sao vo $d
$d = $c = 5; # cng iu y nhng khng c du ngoc
Th d cui lm vic tt v php gn c tnh kt hp
bn phi.

Ton t gn hai ngi
Cc biu thc nh $a = $a + 5 (trong cng mt
bin li xut hin c hai v ca php gn) thng xut
hin n mc Perl (ging nh C) c cch vit tt cho
php ton lm thay i bin - ton t gn hai ngi. Gn
nh tt c cc ton t hai ngi tnh mt gi tr c dng
php gn hai ngi tng ng vi du bng c b sung
thm phn t. Chng hn, hai dng sau y l tng
ng:
$a = $a + 5 ; # khng c ton t gn hai ngi
$a += 5 ; # c ton t gn hai ngi
V tng t nh th:
$b = $b * 3;
$b *= 3;
Trong tng trng hp, ton t ny lm cho gi tr
hin ti ca bin c thay i theo mt cch no ,

70

thay v n gin ghi ln gi tr ny bng kt qu ca
mt biu thc mi no .
Ton t gn thng dng khc l ton t ghp ni
xu:
$str = $str . ; # thm ducch vo $str
$str .= ; # cng iu y vi ton t gn
Gn nh tt c cc ton t hai ngi hp l theo
cch ny. Chng hn, ton t nng ln lu tha ca s
c vit l **=. Cho nn, $a **= 3 c ngha l nng mt
s trong $a ln lu tha ba, ri t kt qu tr li $a.
Ging nh ton t gn n, cc ton t ny cng c
mt gi tr : gi tr mi ca bin. Chng hn:
$a = 3;
$b = ($a += 4); # $a v $b c hai by gi l 7
Nhng khng may l trt t tnh ton ca cc ton
hng ca ton t hai ngi li khng c xc nh, cho
nn mt s biu thc khng th no c xc nh hon
ton:
$a = 3;
$b = ($a += 2) * ($a -= 2); # Chng trnh ti: $b c th
l 15 hay 3
Nu ton hng bn phi ca php nhn c tnh
u tin th kt qu s l 3 ln 1, hay 3. Tuy nhin, nu
ton hng bn tri c tnh trc ton hng bn phi,
th n l 5 ln 3, hay 15. Bn ch c lm iu ny, chng
no bn cn cha vo Cuc tranh lun Perl ri rm.


71

T tng v t gim
Dng cng d dng thm mt vo $a bng
vic ni $a += 1. Perl cn i xa hn v thm ch li cn
lm ngn hn cho iu ny na. Ton t ++ (c gi l
ton t t tng) cng thm mt vo ton hng ca n, v
cho li gi tr c tng, ging nh:
$a += 1 ; # c ton t gn
++$a; # vi t tng tin t
$d = 17;
$e = ++$d; # $e v $d by gi l 18
Ti y, ton t ++ c dng nh ton t tin t -
tc l, ton t xut hin bn tri ton hng ca n.
Php t tng cng c th c dng trong dng hu t
(nm bn phi ton hng ca n). Trong trng hp
ny, kt qu ca biu thc ny l gi tr ca bin trc
khi bin c tng ln. Chng hn,
$c = 17;
$d = $c++; # $d l 17, nhng $c by gi l 18
V gi tr ca ton hng thay i nn ton hng ny
phi l mt bin v hng, khng phi l biu thc. Bn
khng th ni ++16 c c 17, m cng khng th
ni ++($a+$b) l cch no c c gi tr ln hn
tng ca $a v $b mt n v.
Ton t t gim (--) cng tng t nh ton t t
tng, nhng tr i mt thay v cng vi mt. Ging nh
ton t t tng, ton t t gim cng c dng tin t v
hu t. Chng hn:
$x = 12;
--$x ; # $x by gi l 11
$y = $x-- ; # $y l 11, cn $x by gi l 10

72

Khng ging C, cc ton t t tng v t gim lm
vic trn s du phy ng. Cho nn vic tng mt bin
vi gi tr 4.2 s cho 5.2 nh d kin.

Ton t chop()
Mt ton t c ch khc l chop(). Ton t tin t ny
nhn mt i bn trong cc du ngoc ca n - tn ca
mt bin v hng - v b i k t cui cng t gi tr
xu ca bin . Chng hn:
$x = Xin cho mi ngi;
chop($x); # $x by gi l Xin cho mi ngi
Lu rng gi tr ca i b thay i y, do
cn phi c mt bin v hng, thay v ch n gin l
gi tr v hng. S l v ngha, chng hn, vit
chop(suey) bin n thnh sue, v khng c ch no
ct gi gi tr ny. Bn cnh , bn c th ch vit
sue cng .
Ton t ny trng ging nh mt li gi hm, v
qu thc cho li mt gi tr (m bn s trng i nu bn
quen thuc vi li gi hm t cc ngn ng). Gi tr
c cho li chnh l k t b loi b (ch i trong
ngi trn). iu ny c ngha l on m sau y c
l sai:
$x = chop($x); # SAI: thay th $x bng k t cui cng
ca n
chop($x); # ng: nh trn, loi b k t cui
Nu chop() c cho mt xu rng, th n chng lm
g c, v chng cho li g, m cng khng a ra li hay
than vn g. Phn ln cc php ton trong Perl c

73

nhng iu kin nhy cm - ni cch khc, bn c th
dng chng ngay st cnh (v vt ra ngoi) m thng
khng c li phn nn no. Mt s ngi bin minh rng
y l mt trong nhng nhc im nn tng ca Perl,
trong khi s cn li trong chng ta th vn vit ra nhng
chng trnh tc ci m chng phi lo lng g v phn
rm bn. Bn quyt nh xem mnh s theo vo pha no.

Xen ln v hng vo trong xu
Khi mt hng k t xu l c t trong nhy kp
th n l ch cho vic xen ln bin (bn cnh vic
c kim tra cho li thot s cho ngc). iu ny c
ngha l xu ny c duyt qua tm cc tn bin
*
v
hng c th - c ngha l du la i theo sau mt ch,
s hay du gch thp. Khi tm thy mt tham chiu bin
th n c thay th bng gi tr hin ti (hay bt k xu
rng no nu bin v hng cn cha c gn gi tr
no). Chng hn:
$a = fred;
$b = some text $a; # $b by gi l some text fred
$c = no such variable $what; # $c l no such variable
ngn cn vic thay th mt bin bng gi tr ca
n, bn phi hoc lm thay i phn ca xu cho
n xut hin trong ngoc n, hoc t trc du la
mt du s cho ngc, m s tt ngha c bit ca
du la:
$fred = hi;
$barney = a test of .$fred; # hng k hiu: a test of

*
V c bin mng na, nhng chng ta vn cn cha bit n chng
chng no cha ti Chng 3, bin mng

74

$fred
$barney2 = a test of \$fred; # cng nh vy
Tn bin s l tn bin di nht c th m to nn
ngha ti phn ca xu. iu ny c th l vn nu
bn mun t sau ngay gi tr c thay th vi mt vn
bn hng m bt u bng mt ch, s hay du gch
thp. V Perl duyt qua cc tn bin nn n s xt nhng
k t l cc k t tn ph, m khng phi l iu bn
mun. Perl cung cp mt nh bin cho tn bin theo cc
h thng tng t nh lp v. n thun bao tn ca
bin trong mt cp du ngoc nhn. Hay c th kt
thc phn ca xu v bt u mt phn khc ca xu
bng ton t ghp ni:
$fred = pay; $fredday = wrong!;
$barney = Its $fredday; # khng phi payday, m l
Its wrong!
$barney = Its ${fred}day; # by gi, $barney l Its
payday!
$barney2 = Its $fred; # cch khc lm vic
$barney3 = Its . $fred . day; v mt cch khc
Ton t s cho ngc chuyn hoa thng c th
c dng lm thay i ch hoa thng c em
theo cng vic xen ln bin. Chng hn:
$bigfred = \ufred; # $bigfred l FRED
$fred = fred; $bigfred = \Ufred; # cng iu
$capfred = \u$fred; # $capfred l Fred
$barney = \LBARNEY; # $barney by gi l barney
$capbarney = \u\LBARNEY; #capbarney by gi l
Barney
$bigbarney = BARNEY; $capbarney = \u\L$bigbarney;
th
Nh bn c th thy, cc ton t dch chuyn hoa
thng c ghi nh bn trong xu chng no chng

75

cn cha c dng ti, cho nn ngay k t u tin ca
BARNEY khng tun theo \u, n vn cn l ch hoa v \u.
Thut ng xen ln bin thng c dng ln vi
xen ln nhy kp, v cc xu c nhy kp l ch cho
vic xen ln bin.

<STDIN>xem nh mt v hng
Ti im ny, nu bn l mt ngi chuyn nghip
lp trnh th bn c th t hi lm sao ly c mt gi
tr vo trong chng trnh Perl. Sau y l cch n gin
nht. Mi ln bn dng <STDIN> ch ang trng i
mt gi tr v hng, th Perl s c ton b dng vn
bn tip t li vo chun (cho ti du dng mi u
tin), v dng xu nh gi tr cho <STDIN>. u vo
chun c th mang nhiu ngha, nhng chng no bn
cn cha lm iu g k l, th n vn cn mang ngha
l thit b cui ca ngi dng, ngi gi chng
trnh ca bn (c th l bn). Nu khng c g ch i
c c (trng hp in hnh, chng no bn cn cha
g xong ton b dng), th chng trnh Perl s dng v
i cho bn a vo mt s k t theo sau bng mt du
dng mi (xung dng).
Gi tr xu ca <STDIN> v in hnh c mt du
dng mi cui ca n. Thng thng nht l bn mun
g b ci du dng mi i (c s khc bit ln gia
hello v hello\n). y l ch m anh bn chng ta, ton t
chop(), ti gip. Mt dy ci vo in hnh a ti mt
ci g ta nh th ny:
$a = <STDIN>; # nhn vn bn
chop($a); # g b du dng mi kh chu

76

Cch vit tt thng dng cho hai dng ny l:
chop($a = <STDIN>) ;
Php gn bn trong cc du ngoc trn tip tc l
mt tham chiu ti $a, thm ch sau khi n c trao
cho mt gi tr vi ton t <STDIN>. Vy, ton t chop()
lm vic trn $a. (iu ny l ng ni chung i vi
ton t gn - mt biu thc gn c th c dng bt k
khi no mt bin l cn ti, v nhng hnh ng tham
chiu ti bin bn tri ca du bng.)

a ra bng print()
Vy thu c mi th vi <STDIN>. lm sao a ra
mi th y? Bng ton t print() y. Ton t tin t ny
nhn mt gi tr v hng bn trong cc du ngoc ca
n v a ra m khng cn bt k trang im no ln li
ra chun. Mt ln na, chng no bn cn cha lm iu
g k l, th li ra ny vn c l thit b cui ca bn.
Chng hn:
print (Xin cho mi ngi\n); # ni cho mi ngi, tip
l du dng mi
print Xin cho mi ngi\n; # cng cng iu
Lu rng th d th hai ch ra dng ca print()
khng c du ngoc. Thc ra, nhiu ton t trng nh
cc hm cng c dng c php lm vic khng cn du
ngoc. D c dng hay khng, du ngoc cng gn nh
l vn v kiu cch v s nhanh nhu trong cch g,
mc du c vi trng hp bn s cn cc du ngoc
loi b bt mp m.
Chng ta s thy rng bn thc s c th cho print

77

mt danh sch cc gi tr, trong mc Dng print a
ra thng thng Chng 6, C s v vo/ra, nhng
chng ta vn cn cha ni v danh sch, cho nn chng
ta s hon n v sau.

Gi tr undef
iu g s xy ra nu bn dng mt bin v hng
trc khi bn cho n mt gi tr? Chng c g nghim
trng c, v chng c g dt khot s gy nh mnh c.
Cc bin c gi tr undef trc khi chng c gn ln
u tin. Gi tr ny trng nh s khng khi c dng
nh mt s, hay xu rng chiu di khng nu c
dng nh mt xu.
Nhiu ton t cho li undef khi cc i vt ra ngoi
phm vi v thnh v ngha. Nu bn khng lm iu g
c bit th bn s nhn c khng hay xu khng m
khng c hu qu g ln. Trong thc hnh, iu ny gn
nh khng gy ra vn g.
Mt ton t m chng ta thy c cho li undef
trong hon cnh no l ton t <STDIN>. Thng
thng ton t ny cho li mt xu ca dng tip va
c c, tuy nhin (nh khi bn g control-D ti thit
b cui, hay khi mt tp khng cn d liu na), th ton
t ny cho li undef nh mt gi tr. Chng s thy trong
chng 6 cch kim tra iu ny v chn hnh ng c
bit khi khng cn d liu no c sn c na.


78


Bi tp
Xem Ph lc A v li gii.
1. Vit chng trnh tnh chu vi ng trn vi bn
knh 12.5. Chu vi bng 2 ln bn knh, hay khong
2 ln 3.141592654.
2. Sa chng trnh t bi tp trc nhc vic nhn
bn knh t ngi chy chng trnh.
3. Vit mt chng trnh nhc v c vo hai s, ri in
ra kt qu ca vic nhn hai s .
4. Vit mt chng trnh c mt xu v mt s ri in
ra xu s ln c ch ra bi s cc dng tch bit.
(Hng dn: dng ton t x.)



79

3


D liu mng
v danh sch


Mng l g?
Mng l mt danh sch c th t cc d liu v
hng. Mi phn t ca mng l mt bin v hng
tch bit vi mt gi tr v hng c lp. Cc gi tr
ny l c sp th t - tc l chng c mt trnh t c
bit t phn t thp nht n cao nht.
Mng c th c bt k s phn t no. Mng nh
nht khng c phn t no, trong khi mng ln nht th
c th lp kn ton b b nh c sn. Mt ln na, iu
ny li c gi hp vi trit l ca Perl v khng c
gii hn khng cn thit no.


Trong chng ny:
Mng l g?
Biu din hng
k hiu
Bin
Ton t
Ng cnh v
hng v mng
<STDIN>xem
nh mng
Bin
Xen ln mng



80

Biu din hng k hiu
Mt hng k hiu mng (cch thc bn biu din gi
tr ca mt mng bn trong chng trnh mnh) l mt
danh sch cc gi tr tch nhau bng du phy v c
bao trong du ngoc trn. Nhng gi tr ny to nn cc
phn t ca danh sch. Chng hn:
(1,2,3) # mng gm ba gi tr 1, 2 v 3
(fred, 4.5) # hai gi tr, fred v 4.5
Cc phn t ca mng khng nht thit l hng -
chng c th l biu thc m s c tnh mi li mi
ln hng c s dng. Chng hn:
($a, 17) # hai gi tr: gi tr hin ti ca $a, v 17
($b+$c,$d+$e) # hai gi tr
Mng rng (mng khng c phn t no) c biu
din bng mt cp du ngoc rng:
() # mng rng (khng phn t)
Mt phn t ca mng c th bao gm ton t cu
t mng, c ch ra bi hai gi tr v hng tch nhau
bi hai du chm lin tip. Ton t ny to ra mt danh
sch cc gi tr bt u ti gi tr v hng bn tri ko
cho ti gi tr v hng bn phi, mi ln tng ln mt.
Chng hn:
(1..5) # ging nh (1, 2, ,3 ,4, 5)
(1.2..5.2) # ging nh (1.2, 2.2, 3.2, 4.2, 5.2)
(2..6,10,12) # ging nh (2,3,4,5,6,10,12)
($a..$b) # phm vi c xc nh bi gi tr hin ti
ca $a v $b
Nu gi tr v hng bn phi b hn v hng bn
tri th s to ra danh sch rng - bn khng th m
ngc trt t ca cc gi tr. Nu gi tr cui cng khng

81

phi l ton b s bc trn gi tr ban u th danh sch
s dng ch ngay trc gi tr tip m s vt ra ngoi
phm vi:
(1.3..6.1) # ging nh (1.3, 2.3, 3.3, 4.3, 5.3)
Mt cch dng ca hng k hiu mng l nh i
ca ton t print() c gii thiu trc y. Cc phn
t ca danh sch ny c in ra m khng c bt k
khong trng xen thm vo:
print (Cu tr li l , $a, \n) ; # ba phn t mng hng
k hiu
Cu lnh ny in ra Cu tr li l, theo sau bi mt
du cch, gi tr ca $a, v du dng mi. Chuyn sang
cch dng khc cho hng k hiu mng.

Bin
Mt bin mng gi mt gi tr mng ring (khng
hay nhiu gi tr v hng). Cc tn bin mng l tng
t vi cc tn bin v hng, ch khc k t khi u, l
mt du a cng @ ch khng phi l du la $. Chng
hn:
@fred # bin mng @fred
@A_Very_Long_Array_Variable_Name
@A_Very_Long_Array_Variable_Name_that_is_different
Lu rng bin mng @fred l khng c quan h g
theo bt k cch no vi bin v hng $fred. Perl duy tr
khng gian tn tch bit cho cc kiu i tng khc
nhau.
Gi tr ca mt bin mng m cha c gn l (),
danh sch rng.

82

Mt biu thc c th tham chiu ti cc bin mng
nh mt tng th, hoc n c th xem xt v thay i
tng phn t ca mng .

Ton t
Cc ton t mng hnh ng trn cc mng nh mt
tng th. Mt s ton t mng c th cho li mt gi tr
mng, m c th hoc c dng nh mt gi tr cho
ton t mng khc, hoc c gn vo mt bin mng
khc.

Php gn
C l ton t mng quan trng nht l ton t gn
mng, cho mng mt gi tr. N l du bng, ging nh
ton t gn v hng. Perl xc nh liu php gn c l
php gn v hng hay php gn mng bng vic
xem liu php gn l cho bin v hng hay mng
*
.
Chng hn:
@fred = (1,2,3); # mng fred nhn ba phn t hng k
hiu
@barney = @fred; # by gi c sao sang @barney
Nu mt gi tr v hng c gn vo trong mt
bin mng th gi tr v hng tr thnh phn t duy
nht ca mng:
@huh = 1; # 1 c t cho danh sch (1) mt cch t
ng

*
iu ny p dng cho lvalue v hng hay mng cng nh cc
bin n

83

Tn bin mng c th xut hin trong danh sch
hng k hiu mng. Khi gi tr ca danh sch c tnh
th Perl thay th tn bin mng bng gi tr hin ti ca
mng , ging vy:
@fred = (mt, hai);
@barney = (4,5,@fred, 6, 7); @barney tr thnh
(4,5,mt,hai,6,7)
@barney = (8, @barney); # t 8 vo trc @barney
@barney = (@barney, cui); # v cui l cui
# @barney by gi l (8,4,5,mt,hai,6,7,cui)
Lu rng cc phn t mng c thm vo
cng mc nh phn cn li ca hng k hiu - mt danh
sch khng th cha mt danh sch khc nh mt phn
t
*
.
Nu mt mng hng k hiu ch cha cc tham chiu
bin (khng phi l biu thc) th mng hng k hiu y
cng c th c x l nh mt bin. Ni cch khc, mt
mng hng k hiu nh th c th c dng v bn
tri ca php gn. Mi bin v hng trong mng k hiu
nhn mt gi tr tng ng t danh sch v phi ca
php gn. Chng hn:
($a, $b, $c) = (1, 2, 3); # t 1 cho $a, 2 cho $b, 3 cho $c
($a, $b) = ($b, $a); # tro i $a v $b
($d, @fred) = ($a, $b, $c); # t $a cho $d, v ($b,$c)
cho @fred
($e,@fred) = @fred; # loi b phn t th nht ca
@fred l $e
# iu ny lm cho @fred = ($c) v $e = $b

*
Perl 5.0 cho php mt tham chiu danh sch l mt phn t danh
sch, nhng y vn khng phi l danh sch nh mt phn t danh
sch

84

Nu s phn t c gn khng snh ng vi s
cc bin gi cc gi tr th mi gi tr vt qu ( v
phi ca du bng) im lng b loi b, v bt k bin
vt qu no ( v tri ca du bng) c cho gi tr
undef.
Mt bin mng xut hin trong danh sch mng
hng k hiu phi cui, v bin mng l tham lam,
v n tiu th tt c cc gi tr cn li. (Ny, bn c th
t cc bin khc sau n, nhng chng s ch nhn gi tr
undef m thi.)
Nu mt bin mng c gn cho mt bin v
hng th s c gn l chiu di ca mng, nh trong:
@fred = (4, 5, 6); # khi u @fred
$a = @fred; # $a nhn phn t u tin ca @fred
Chiu di cng c cho li nu mt tn bin mng
c dng trong hu ht mi ch m mt gi tr v
hng ang c cn ti. (Trong mc di y c tn
Hon cnh v hng mng, chng ta s thy rng iu
ny qu l c gi nh vy vi vic dng tn mng
trong hon cnh v hng.) Chng hn, ly gi tr b
hn chiu di mng mt n v, bn c th dng @fred-1,
v ton t tr v hng cn cc v hng cho c hai ton
hng ca n. Ch iu sau:
$a = @fred; # $a nhn chiu di ca @fred
($a) = @fred; # $a nhn phn t u tin ca @fred
Php gn u tin l php gn v hng, v do vy
@fred c i x nh mt v hng, cho li chiu di
ca n. Php gn th hai l php gn mng (cho d ch
mt gi tr l cn ti), v do vy cho phn t u tin ca
@fred, im lng b i tt c phn cn li.

85

Gi tr ca php gn mng l chnh bn thn gi tr
mng, v c th c xp tng nh bn c th lm vi
cc php gn v hng. Chng hn:
@fred = (@barney = (2,3,4)); # @fred v @barney nhn
(2,3,4)
@fred = @barney = (2,3,4); # cng iu y

Truy nhp phn t
Cho ti nay, chng ta vn x l mng nh mt tng
th, thm vo v b bt cc gi tr bng vic thc hin
gn mng. Nhiu chng trnh c ch c xy dng
dng mng m thm ch chng truy nhp vo phn t
mng no. Tuy nhin, Perl cung cp ton t ch s truyn
thng tham chiu ti mt phn t mng theo ch s.
Vi ton t ch s mng, cc phn t mng c
nh s bng vic dng s nguyn tun t, bt u t
khng
*
v tng ln mt cho mi phn t. Phn t u
tin ca mng @fred m c truy nhp ti l $fred[0].
Ch rng @ trn tn mng tr thnh $ trn tham chiu
phn t. l v vic tham chiu ti mt phn t ca
mng xc nh ra mt bin v hng (mt phn ca
mng), m c th hoc c gn cho, hoc c gi tr hin
ti ca n c dng trong mt biu thc, kiu nh:
@fred = (7,8,9);

*
Cng c th thay i gi tr ch s ca phn t utin thnh mt
s no khc (nh mt) bng vic t gi tr cho bin $[. Tuy
nhin, lm nh vy c nh hng ton cc, m c th gy ln ln
ngi s bo tr chng trnh ca bn, v c th lm tan v chng
trnh bn nhn c t ngi khc. Do vy, chng ti khuyn bn
nn coi y l mt tnh nng khng nn dng.

86

$b = $fred[0]; # t 7 vo $b (phn t u tin ca
@fred)
$fred[0] = 5; # by gi @fred = (5,8,9)
Cng c th truy nhp ti cc phn t khc d tng
t, nh trong:
$c = $fred[1]; $ t 8 cho $c
$fred[2]++; # tng phn t th ba ca @fred
$fred[1] += 4; # cng 4 vo phn t th hai
($fred[0], $fred[1]) = ($fred[1], $fred[0]); # tro i hai
phn t u
Vic truy nhp vo mt danh sch cc phn t t
cng mng (nh trong th d cui) c gi l lt ct, v
thng xut hin n mc c mt cch biu din c bit
cho n:
@fred[0,1] # ht nh ($fred[0], $fred[1])
@fred[0,1] = @fred[1,0] # tro i hai phn t u
@fred[0,1,2] = @fred[1,1,1] # lm cho c 3 phn t ging
phn t th hai
@fred[1,2] = (9,10); # i hai gi tr cui thnh 9 v 10
Ch rng lt ct ny dng tin t @ ch khng l
$. iu ny l v bn ang to ra mt bin mng bng
vic chn mt phn ca mng ch khng phi l bin v
hng ch truy nhp vo mt phn t.
Lt ct cng lm vic trn danh sch hng k hiu,
hay bt k ton t no cho li mt gi tr danh sch:
@who = (fred,barney,betty,wilma)[2,3] ;
# ging nh @x = (fred,barney,betty,wilma); @who
= @x[2,3]
Cc gi tr ch s trong nhng th d ny l cc s

87

nguyn hng k hiu, nhng ch s cng c th l bt k
biu thc no cho li mt s, m ri c dng chn
phn t thch hp:
@fred = (7,8,9);
$a = 2;
$b = $fred[$a]; # ging $fred[2], hay gi tr 9
$c = $fred[$a-1]; # $c nhn $fred[1], hay 8
($c) = (7,8,9) [$a-1]; # cng iu nhng dng lt ct
Vy chng trnh Perl c th c vic truy nhp
mng tng t nh cc ngn ng lp trnh truyn thng.
tng ny v vic dng mt biu thc cho ch s
cng c tc dng cho cc lt ct. Tuy nhin nh rng ch
s cho lt ct l mt danh sch cc gi tr, cho nn biu
thc ny l mt biu thc mng, thay v l mt biu thc
v hng.
@fred = (7,8,9); # nh trong th d trc
@barney = (2,1,0);
@backfred = @fred[@barney];
# ging nh @fred[2,1,0], hay ($fred[2],$fred[1],$fred[0]),
# hay (9,8,7)
Nu bn truy nhp vo mt phn t mng bn ngoi
hai u ca mng hin ti (tc l mt ch s b hn
khng hay ln hn ch s ca phn t cui cng), th gi
tr undef s c cho li m khng c li cnh bo.
Chng hn:
@fred = (1,2,3);
$barney = $fred[7]; # $barney by gi l undef
Vic gn mt gi tr bn ngoi u ca mng hin ti
s t ng m rng mng (cho mt gi tr undef cho tt
c cc gi tr trung gian, nu c). Chng hn:
@fred = (1,2,3);

88

$fred[3] = hi; # @fred by gi l (1,2,3,hi)
$fred[6] = ho; # @fred by gi l (1,2,3,hi,undef,ho)
Php gn cho mt phn t mng c ch s b hn
khng l li nh mnh, v n c th lm pht sinh kiu
cch lp trnh rt xu.
Bn c th dng $#fred ly gi tr ch s ca phn
t cui ca @fred. (iu ny ging nh tham chiu v
C). Bn thm ch cn c th gn vo trong gi tr ny
lm thay i chiu di hin nhin ca @fred, lm cho n
to ln hay co li, nhng iu ni chung l khng cn
thit, v mng thng to ln hay co li mt cch t ng.

Cc ton t push() v pop()
Mt cch dng thng dng ca mng l nh mt
chng thng tin, ni nhng gi tr mi c thm vo v
ly i t pha bn phi ca danh sch. Nhng php ton
ny thng xut hin n mc chng c cc hm c
bit ca ring chng:
push(@mylist,$newvalue); # ging @mylist = (@mylist,
$newvalue)
$oldvalue = pop(@mylist); # ly ra phn t cui ca
@mylist
Ton t pop() cho li undef nu i ca n l danh
sch rng, thay v lm iu g khc kiu Perl nh
phn nn hay sinh ra thng bo li.
Ton t push() cng chp nhn mt danh sch cc
gi tr cn c y vo danh sch. Cc gi tr c y
vo cui ca danh sch. Chng hn:
@mylist = (1,2,3);

89

push(@mylist,4,5,6); # @mylist = (1,2,3,4,5,6)
Ch rng i th nht phi l mt tn bin mng
*
-
y vo v ly ra s khng c ngha vi danh sch hng
k hiu.

Cc ton t shift() v unshift()
Cc ton t push() v pop() lm mi iu bn
phi ca danh sch (phn vi ch s cao nht). Tng
t th, cc ton t unshift() v shift() thc hin nhng hnh
ng tng ng v bn tri ca mt danh sch (phn
vi ch s thp nht). Sau y l vi th d:
unshift(@fred,$a); # nh @fred = ($a,@fred);
unshift(@fred,$a,$b,$c); # nh @fred = ($a, $b, $c,
@fred);
$x = shift(@fred); # nh ($x,@fred) = @fred;
# vi mt s gi tr thc
@fred = (5,6,7);
unshift(@fred,2,3,4); # @fred by gi l (2,3,4,5,6,7)
$x = shift(@fred); # $x nhn 2, $fred nhn by gi l
(3,4,5,6,7)
Nh vi pop(), shift() cho li undef nu bin mng l
rng.

Ton t reverse()
Ton t reverse() o ngc trt t cc phn t ca
i ca n, cho li danh sch kt qu. Chng hn:
@a = (7,8,9);

*
Trong thc t, bn c th b @ mc du ti nghe ni rng Perl 5.0
li i hi n.

90

@b = reverse(@a); # t $b gi tr (9,8,7)
$b = reverse(7,8,9); # cng vic y
Ch rng danh sch i l khng b thay i - ton
t reverse() ch lm vic trn bn sao. Nu bn mun o
ngc mt mng ti ch, th bn cn gn n ngc tr
li cho cng bin:
@b = reverse(@b); # th @b l o ngc ca chnh
n

Ton t sort()
Ton t sort() ly i ca n v sp xp chng dng
nh chng tt c l cc xu theo trt t ASCII tng
dn. N cho li danh sch sp xp, khng lm thay
i danh sch gc. Chng hn:
@x = sort(small, medium, large);
# @x nhn large, medium, small
@y = (1,2,4,8,16,32,64);
@y = sort(@y); # @y nhn 1, 16, 2, 32, 4, 64, 8
Ch rng cc s sp xp khng xut hin theo th
t s, nhng theo gi tr xu ca tng s (1, 16, 2, 32,
vn vn). Trong mc Sp xp nng cao, Chng 15,
Vic bin i d liu khc, bn s hc cch sp xp theo
s, hoc theo th t gim, hay theo k t th ba ca tng
xu, hay bt k phng php no khc m bn chn.

Ton t chop()
Ton t chop() lm vic trn bin mng cng nh
bin v hng. Mi phn t ca mng c k t cui b
b i. iu ny c th l thun tin khi bn c mt danh

91

sch cc dng nh cc phn t mng tch bch, v bn
mun b i du dng mi trong tt c cc dng ngay lp
tc. Chng hn:
@stuff = (hello\n, world\n, happy day);
chop(@stuff); # @stuff by gi l (hello, world, happy
day)

Hon cnh v hng v mng
Nh bn c th thy, tng ton t c thit k
hot ng trn mt s t hp xc nh cc v hng
hay mng, v cho li mt v hng hay mng. Nu mt
ton t trng i mt ton hng l v hng th ni rng
ton hng l c tnh trong hon cnh v hng.
Tng t, nu mt ton hng ang trng i mt gi tr
mng th ni rng ton hng l c tnh trong hon
cnh mng.
Thng thng, iu ny l kh thng thng. Nhng
i khi bn nhn c mt thao tc hon ton khc tu
theo liu bn ang trong hon cnh v hng hay mng.
Chng hn, @fred cho li ni dung ca mng @fred trong
hon cnh mng, nhng cho li chiu di ca mng
trong hon cnh v hng. Nhng s tinh vi ny s c
nhc ti khi cc ton t c m t.
Nu bn mun buc mt biu thc phi c tnh
trong hon cnh v hng th bn c th ghp ni mt
xu khng vo cho n
*
. Chng hn:

*
Bn cng c th dng ton t scalar() nhng chng ta s khng
ni v iu y.

92

@a = (x,y,z);
print (Ti thy , @a, phn t\n); # sai, s in l xyz
cho @a
print (Ti thy ,.@a, phn tt\n); # ng, in 3 cho
@a
Ti y, chng ni xu khng vo @a, lm
ny sinh xu 3, m ri tr thnh mt phn ca danh
sch cho print.
Mt gi tr v hng c dng bn trong mt hon
cnh mng th s c coi nh mng mt phn t.

<STDIN> nh mt mng
Mt ton t thy trc y cng cho gi tr khc
trong hon cnh mng l <STDIN>. Nh m t trc
y, <STDIN> cho dng tip ca ci vo trong hon cnh
v hng. By gi, trong hon cnh mng, ton t ny
cho li tt c phn dng cn li cho ti cui tp. Mi
dng c cho li nh mt phn t tch bch ca
danh sch. Chng hn:
@a = <STDIN>; # c ci vo chun trong hon cnh
mng
Nu mt ngi chy chng trnh ny g vo ba
dng, ri nhn Control-D ( ch ra cui tp), th mng
kt thc vi ba phn t. Mi phn t s l mt xu m
kt thc bng mt du dng mi, tng ng vi ba dng
c kt thc l du dng mi g vo.

Xen ln bin mng
Ging nh cc v hng, cc gi tr mng c th

93

c xen ln trong xu c nhy kp. Mt phn t
ring ca mt mng s c thay th bi gi tr ca n,
ging nh:
@fred = (hello, dolly);
$y = 2;
$x = This is $fred[1]s place; # This is dollys place
$x = This is $fred[$y-1]s place; # cng cu y
Ch rng biu thc ch s c tnh nh mt biu
thc thng thng, dng nh n bn ngoi xu. N
khng phi l bin c xen ln trc ht. Ni cch
khc, nu $y cha xu 2*4 th vn ni v phn t 1, ch
khng phi l 7, v 2*4 xem nh mt s (gi tr ca $y
c dng trong biu thc s) ch l 2 r.
Nu bn mun t sau mt tham chiu bin v
hng n du ngoc vung tri th bn cn nh bin
cho du ngoc vung cho n khng c coi nh mt
phn ca mt tham chiu mng, nh sau:
@fred = (hello, dolly); # t gi tr cho @fred kim
th
$fred = right;
# chng ang nh ni this is right[1]...
$x = this is $fred[1]; # sai, cho this is dolly
$x = this is ${fred}[1] ; # ng (c bo v bi du
ngoc nhn)
$x = this is $fred..[1]; # ng (xu khc)
$x = this is $fred\[1]; # ng (s cho ngc che du
n)
Tng t, mt danh sch cc gi tr t mt bin
mng cng c th c xen ln. Vic xen ln n gin
nht l ton b mng, c ch ra bng vic cho tn
mng (k c k t @ ng u ca n). Trong trng
hp ny, cc phn t c xen ln theo trnh t vi mt

94

du cch gia chng, nh trong:
@fred = (a, bb, ccc, 1, 2, 3);
$all = Now for @fred here!;
# $all cho Now for a bb ccc 1 2 3 here!
Bn cng c th chn ra mt phn ca mng vi lt
ct:
@fred = (a, bb, ccc, 1,2,3);
$all = Now for @fred[2,3] here!;
# $all cho Now for ccc 1 here!
$all = Now for @fred[@fred[4,5]] here!; # cng th
Mt ln na, bn c th dng bt k c ch nhy kp
no c m t trc y nu bn mun t sau mt
tham chiu tn mng bng mt hng k hiu du ngoc
nhn tri thay v mt biu thc ch s.

Bi tp
Xem Ph lc A v li gii
1. Vit mt chng trnh c mt danh sch cc xu v
in ra danh sch theo th t o ngc.
2. Vit mt chng trnh c mt s ri mt danh sch
cc xu (tt c trn cc dng tch bit), ri in mt
trong cc dng t danh sch nh c la chn
bi con s .
3. Vit mt chng trnh c mt danh sch cc xu ri
cn ra v in xu ngu nhin trong danh sch .
Chn mt phn t ngu nhin ca @somearray , t
srand;

95

ti u chng trnh ca bn (iu ny s khi u
b sinh s ngu nhin), v ri dng
rand (@somearray)
khi bn cn mt gi tr ngu nhin gia 0 v mt s
b hn chiu di ca @somearray.


96



97


4

Cu trc
iu khin


Khi cu lnh
Khi cu lnh l mt dy cc cu lnh, c bao
trong cp du ngoc nhn. N trng ta nh th ny:
{
cu lnh th nht;
cu lnh th hai;
cu lnh th ba;
...
cu lnh cui;
}
Perl thc hin tng cu lnh theo trnh t, t u n
cui. (V sau, ti s ch cho bn cch thay i trnh t
thc hin ny bn trong khi, nhng hin ti th th l
.)
V mt c php, mt khi cc cu lnh c chp
Trong chng ny:

Khi cu lnh
Cu lnh if /
unless
Cu lnh while /
until
Cu lnh for
Cu lnh
foreach


98

nhn mi v tr ca mt cu lnh.

Cu lnh if/unless
phc tp tip theo trong cc cu lnh l cu lnh
if. Kt cu ny trng rt ging kt cu trong C: mt biu
thc iu khin (c tnh theo tnh ng n ca n),
v hai khi. Ni cch khc, n trng ta nh th ny:
if (biu thc no ) {
cu lnh 1 trong trng hp ng ;
cu lnh 2 trong trng hp ng ;
cu lnh 3 trong trng hp ng ;
} else {
cu lnh 1 trong trng hp sai ;
cu lnh 2 trong trng hp sai ;
cu lnh 3 trong trng hp sai ;
}
(Nu bn thnh tho v C th bn s ch rng cc
du ngoc nhn l cn thit. iu ny kh b nhu cu v
qui tc else lng thng.)
Trong khi thc hin, Perl s tnh biu thc iu
khin. Nu biu thc ny l ng th khi th nht (cc
cu lnh trong trng hp ng trn) s c thc hin.
Nu biu thc l sai th khi th hai (cc cu lnh trong
trng hp sai trn) s c thc hin.
Nhng ng sai l nh th no? Trong Perl, cc qui
tc c i cht hi huyn o, nhng chng cho bn kt
qu nh d kin. Biu thc iu khin c tnh cho mt
gi tr xu (nu n l xu, th chng c thay i g,

99

nhng nu n l s th n s c chuyn thnh xu
*
).
Nu xu ny hoc l xu rng (chiu di khng), hoc l
mt xu c cha mt k t 0 (khng), th gi tr ca
biu thc l sai. Mi th khc c t ng coi nh l
ng. Ti sao c ci qui tc bun ci ny vy? V iu
y lm cho d dng nhy theo ci rng
*
so vi mt xu
khc rng, cng nh s khng so vi s khc khng,
khng cn phi to ra hai cch hiu v cc gi tr ng v
sai. Sau y l nhng th d v cch hiu ng v sai:
0 # chuyn thnh 0, cho nn l sai
1-1 # chuyn thnh 0, ri chuyn thnh 0, cho nn l
sai
1 # chuyn thnh 1, nn l ng
# xu rng, cho nn l sai
1 # khong phi l hay 0, cho nn ng
00 # khng phi l hay 0, cho nn l ng (trng
hp ny c huyn o, xem m xem)
0.000 # cng ng vi cng l do v cnh bo
undef # tnh thnh , cho nn sai
V mt thc hnh m ni, cch hiu cc gi tr ng
sai th kh trc gic. ng ti lm bn s.
Sau y l mt th d v cu lnh if y :
print Bn bao nhiu tui ri?
$a = <STDIN>;
chop($a);
if ($a < 18) {
print Ny, bn cha tui bu c u nh?\n;
} else {
print tui ri! Hy bnh thn! Vy i bu c i!\n;

*
Bn trong, iu ny khng hon ton ng. Nhng n hnh ng
ging nh y l iu n thc hin.
*
Ny, rng l ngoi tr cho trng hp bnh hon ca mt k t
khng y

100

$voter++; # m s c tri v sau
}
Bn c th ct b khi else, ch li phn then, nh
trong:
print Bn bao nhiu tui ri?
$a = <STDIN>;
chop($a);
if ($a < 18) {
print Ny, bn cha tui bu c u nh?\n;
}
i khi, bn mun b i phn then m ch c phn
else, v s t nhin hn ni lm iu nu iu ny
sai, so vi lm iu nu iu ph nh ca iu ny
l ng. Perl gii quyt iu ny vi bin th unless:
print Bn bao nhiu tui ri?
$a = <STDIN>;
chop($a);
unless ($a < 18) {
print tui ri! Hy bnh thn! Vy i bu c i!\n;
$voter++;
}
Vic thay th if bng unless l c hiu qu khi ni
Nu biu thc iu khin l khng ng th lm... (mt
unless cng c th c mt else, nh if.)
Nu bn c nhiu hn hai chn la th bn c th
thm mt nhnh elsif vo cu lnh if , ging nh:
if (biu thc mt no ) {
cu lnh 1 trong trng hp ng mt;
cu lnh 2 trong trng hp ng mt;
cu lnh 3 trong trng hp ng mt;
} elsif (biu thc hai no ) {
cu lnh 1 trong trng hp ng hai;
cu lnh 2 trong trng hp ng hai;

101

cu lnh 3 trong trng hp ng hai;
} elsif (biu thc ba no ){
cu lnh 1 trong trng hp ng ba;
cu lnh 2 trong trng hp ng ba;
cu lnh 3 trong trng hp ng ba;
} else {
cu lnh 1 trong trng hp sai tt c ;
cu lnh 2 trong trng hp sai tt c;
cu lnh 3 trong trng hp sai tt c;
}
Mi biu thc ( y, biu thc mt no , biu thc
hai no , v biu thc ba no ) c tnh ln lt.
Nu mt biu thc l ng th nhnh tng ng s c
thc hin, v tt c phn cn li ca biu thc iu khin
cng cc nhnh cu lnh s b b qua. Nu tt c cc
biu thc ny sai th nhnh else s c thc hin
(nu c). Bn c th c nhiu nhnh elsif tu .

Cu lnh while/until
Khng mt ngn ng thut ton no hon chnh m
khng c mt dng lp no (thc hin lp li mt
khi cc cu lnh). Perl c th lp bng vic dng cu
lnh while:
while (biu thc no ) {
cu lnh 1;
cu lnh 2;
cu lnh 3;
}
thc hin cu lnh while ny, Perl tnh biu thc
iu khin (biu thc no trong th d ny). Nu gi tr
ny l ng (bng vic dng tng v ci ng ca cu
lnh if), th thn ca cu lnh while s c tnh mt ln.

102

iu ny c lp li cho ti khi biu thc iu khin
tr thnh sai, ti im Perl chuyn sang cu lnh tip
sau while. Chng hn:
print Bn bao nhiu tui ri?
$a = <STDIN>;
chop($a);
while ($a > 0) {
print Vo lc ny bn mi $a tui.\n;
$a--;
}
i khi ni lm vic trong khi iu ny sai li
d hn l ni lm vic trong khi ph nh iu ny l
ng. Mt ln na, Perl li c cu tr li. Thay cho
while l until, cng cho kt qu mong mun:
until (biu thc no ) {
cu lnh 1;
cu lnh 2;
cu lnh 3;
}
Ch rng trong c hai dng while v until, cc cu
lnh thn s b b qua hon ton nu biu thc iu
khin l gi tr kt thc ngay t lc bt u. Chng hn,
nu ngi dng a vo mt tui b hn khng cho
on chng trnh trn th Perl s b qua thn chu trnh.
C th l biu thc iu khin s chng bao gi
cho chu trnh ra c. iu ny hon ton hp php, v
i khi cng l mong mun na, v do vy khng b coi
nh li. Chng hn, bn c th mun mt chu trnh c
lp li mi chng no bn cn cha phm phi li, v ri
c mt on trnh gii quyt li i theo sau chu trnh.
Bn c th dng iu ny cho mt vic qui qu c th
chy hoi cho ti khi h thng sp.

103


Cu lnh for
Mt kt cu lp khc ca Perl l cu lnh for, trng
ging nh cu lnh for ca C, v lm vic th i th
cng ging th. Sau y l n:
for (biu thc khi u; biu thc kim tra; biu thc
tng) {
cu lnh 1;
cu lnh 2;
cu lnh 3;
}
G ra theo dng thy trc y, iu ny tr
thnh
biu thc khi u
while (biu thc kim tra) {
cu lnh 1;
cu lnh 2;
cu lnh 3;
biu thc tng
}
Trong c hai trng hp, biu thc khi u c
tnh trc. Biu thc ny v in hnh ch gn gi tr ban
u cho mt bin lp, nhng cng chng c hn ch no
v vic n c th cha ci g - thc ra n c th rng
(chng lm g c). Ri biu thc kim tra s c tnh
xc nh ng sai. Nu gi tr tnh c l ng th thn
chu trnh s c tnh, tip theo l tnh biu thc tng
(m in hnh l c dng tng b lp). Perl tip
s tnh li biu thc kim tra, lp li khi cn cn.
Th d ny in ra cc s t 1 n 10, mi s c sau
n mt du cch:

104

for ($i = 1; $i <= 10; $i++)
print $i ;
}
Ban u, bin $i c t l 1. Ri, bin ny c so
snh vi 10, m thc s n ang b hn hay bng. Thn
ca chu trnh (mi cu lnh print) c thc hin, v ri
biu thc tng (biu thc t tng $i++) s c thc
hin, thay i gi tr trong $i thnh 2. V iu ny vn
cn b hn 10 nn lp li tin trnh, cho ti khi ln lp
cui m gi tr 10 ca $i i thnh 11. Ri iu ny
khng cn b hn hay bng 10 na, cho nn chu trnh i
ra (vi $i c gi tr 11).

Cu lnh foreach
Vn cn mt kt cu lp khc l cu lnh foreach.
Cu lnh ny rt ging nh cu lnh foreach ca v C: n
nhn mt danh sch cc gi tr v mi ln li gn chng
cho mt bin v hng, ri thc hin mt khi m cng
vi vic gn . N trng ta nh th ny:
foreach $i (@danh sch no ) {
cu lnh 1;
cu lnh 2;
cu lnh 3;
}
Khng ging lp v C, gi tr nguyn gc ca bin
v hng c t ng khi phc khi chu trnh i ra -
mt cch khc ni iu ny l ch bin v hng l
cc b cho chu trnh.
Sau y l mt th d v foreach:
@a = (1,2,3,4,5);
foreach $b (reverse @a) {

105

print $b;
}
Mu chng trnh ny in ra 54321. Ch rng danh
sch c foreach s dng c th l mt biu thc danh
sch bt k, khng ch l mt bin mng. (y l in
hnh cho phn ln cc kt cu Perl c yu cu mt danh
sch.)
C th b tn ca bin v hng, trong trng hp
Perl gi thit rng bn xc nh dng tn bin $_.
Bn s thy rng bin $_ c dng nh mc nh cho
nhiu php ton Perl, cho nn bn c th coi n nh mt
vng nhp. (Tt c cc php ton c dng $_ theo mc
nh cng c th dng mt bin v hng thng
thng.) Chng hn, ton t print in ra gi tr ca $_ nu
khng c gi tr no khc c xc nh, cho nn th d
sau y s lm vic nh th d trc:
@a = (1,2,3,4,5);
foreach (reverse @a) {
print ;
}
Xem vic dng bin $_ lm n gin hn bao nhiu
khng? (Hay t nht th cng ngn hn.)
Nu danh sch m bn ang lp c to nn t mt
tham chiu bin mng n, thay v mt ton t no
m cho li mt gi tr danh sch, th bin v hng ang
c dng cho lp thc ra li l tham chiu ti tng phn
t ca mng , thay v l bn sao ca cc gi tr .
iu ny ng g theo ngha thng thng? N c ngha
l nu thay i bin v hng th cng thay i phn t
c bit trong mng m bin ang i din cho.
Chng hn:

106

@a = (3,5,7,9);
foreach $one ($a) {
$one *= 3;
}
# @a by gi l (9, 15,21,27)
Ch n vic thay i $one thc ra lm thay i
tng phn t ca @a.

Bi tp
Xem Ph lc A v li gii.
1. Vit mt chng trnh hi v nhit bn ngoi, ri
in qu nng nu nhit l trn 72 F, v qu
lnh trong cc trng hp khc.
2. Sa i chng trnh trong bi tp trc cho n in
ra qu nng nu nhit l trn 75F, qu lnh
nu nhit l di 68F, v va phi nu nhit
trong khong 68 v 75.
3. Vit mt chng trnh c mt danh sch cc s
(mi s mt hng) cho ti khi c ti s 999, ri in
ra ton b tt c cc s cng li vi nhau. (Phi
chc ng c cng c 999 vo!) Chng hn, nu bn
a vo 1,2,3 v 999 th chng trnh s p ng vi
cu tr li 6 (1+2+3).
4. Vit mt chng trnh c mt danh sch cc xu ri
in chng ra thnh danh sch cc xu theo th t o
ngc (khng dng ton t reverse cho danh sch).
(Nh rng ton t <STDIN> s c mt danh sch cc
xu trn tng dng tch bit khi c dng trong
hon cnh mng.)

107

5. Vit mt chng trnh in ra bng cc s v bnh
phng ca chng t khng n 32. Th a ra mt
cch m bn khng cn phi c tt c cc s t 0 n
32 trong danh sch, ri th mt cch bn phi c cc
s . ( trng cho p,
printf %5g %8g\n, $a, $b
s in ra $a v $b nh mt s c nm ct, cn $b nh
mt s c tm ct.


108


109


5


Mng kt hp



Mng kt hp l g?
Mng kt hp cng ta nh mng (kiu danh sch)
tho lun trc y, trong n l mt tuyn tp cc
d liu v hng, vi cc phn t ring c chn ra
bng mt gi tr ch s no . Khng ging mng danh
sch, gi tr ch s ca mng kt hp khng phi l s
nguyn khng m nh, m thay vo l v hng tu
. Nhng v hng ny (cn gi l kho) c dng v
sau tm kim cc gi tr t mng ny.
Cc phn t ca mng kt hp khng c th t c
bit. Xem chng ta nh bn y nhng qun bi. Na
trn ca cc con bi l kho, cn na di l gi tr ca
chng. Mi ln bn t mt gi tr vo trong mng kt
hp th mt con bi mi li c to ra. V sau khi bn

Trong chng ny:

Mng kt hp l g?
Bin mng kt hp
Biu din hng cho
mng kt hp
Cc ton t mng kt
hp

110

mun sa i gi tr ny, bn cho kho, cn Perl tm ra
ng con bi. Cho nn, thc s, trt t ca cc con bi l
khng quan trng. Thc ra, Perl ct gi cc con bi (cp
kho-gi tr) theo th t bn trong c bit d dng
tm ra mt con bi c bit, cho nn Perl khng phi
duyt qua tt c cc cp tm ra ng con bi. Bn
khng th kim sot c trt t ny, cho nn ng th.

Bin mng kt hp
Tn bin mng kt hp l du phn trm (%) theo
sau bi mt ch, theo sau na l khng hay nhiu ch,
ch s v du gch thp. Ni cch khc, phn i sau du
phn trm ging ht ci m chng c cho tn bin v
hng v bin mng. V ging nh chng c quan h g
gia $fred v @fred, bin mng kt hp %fred cng
chng lin quan g ti hai loi bin kia c.
Thay v tham chiu ti ton b mng kt hp, thng
dng hn c l to ra mt mng kt hp v truy nhp vo
n bng cch tham chiu ti cc phn t ca n. Mi
phn t ca mng l mt v hng tch bit, c
truy nhp ti bi mt ch mc v hng, gi l kho.
Cc phn t ca mng kt hp %fred vy c tham
chiu n bng $fred{$key} vi $key l bt k biu thc
v hng no. Li ch rng vic truy nhp vo mt
phn t ca mng khng bt u bng cng ch ngt nh
tn ca ton b mng.
Ging nh vi mng danh sch, c th to ra nhng
phn t mi bng vic gn cho mng mt phn t:
$fred{aaa} = bbb ; # to ra kho aaa, gi tr bbb
$fred{234.5} = 456.7; # to ra kho 234.5, gi tr 456.7

111

Hai cu lnh ny to ra hai phn t trong mng.
Nhng tham chiu v sau ti cng nhng phn t ny
(dng cng kho) s cho li gi tr c ct gi.
print $fred{aaa}; # in bbb
$fred{234.5} += 3; # lm cho n thnh 459.7
Vic tham chiu ti mt phn t khng c sn s
cho li gi tr undef, ging nh vi mng danh sch hay
bin v hng khng xc nh.

Biu din hng k hiu cho mng kt hp
Bn c th mun truy nhp vo mng kt hp nh
mt ton th, hoc khi u n hay sao chp n sang
mng kt hp khc. Perl khng thc s c biu din
hng k hiu cho mng kt hp, cho nn thay v th n
tho ri mng ra nh mt danh sch. Mi cp phn t
trong danh sch (m bao gi cng phi c mt s chn
phn t) xc nh ra mt kho v gi tr tng ng
ca n. Biu din tho ri ny c th c gn vo trong
mng kt hp khc, m ri s ti to li cng mng kt
hp . Ni cch khc:
@fred_list = %fred;
# @fred_list nhn (aaa, bbb, 234.5, 456.7)
%barney = @fred_list; # to ra %barney ging %fred
%barney = %fred; # cch nhanh hn lm cng vic

%smooth = (aaa, bbb, 234.5, 456.7);
# to ra %smooth ging nh %fred, t cc gi tr hng k
hiu
Trt t ca cc cp kho-gi tr l tu trong cch
biu din tho ri ny, v khng th kim sot c. Cho
d bn c tro i mt s gi tr v to ra mt mng nh

112

mt ton th th danh sch tho ri thu c vn c theo
bt k trt t no m Perl to ra truy nhp hiu qu
vo cc phn t ring. Bn ng bao gi nn da trn bt
k trt t c bit no.

Cc ton t mng kt hp
Sau y l mt s ton t cho mng kt hp.

Ton t keys()
Ton t keys(%tn mng) cho li danh sch cc tt
c cc kho hin c trong mng kt hp %tn mng . Ni
cch khc, n ta nh cc phn t c nh s l (mt,
ba nm vn vn) ca danh sch c vic tho ri %tn
mng cho li trong ng cnh mng, v thc ra, cho li
chng theo trt t . Nu khng c phn t no trong
mng kt hp th keys() cho li mt danh sch rng.
Chng hn, bng vic dng mng kt hp t th d
trc:
$fred{aaa} = bbb;
$fred{234.5} = 456.7;
@list = keys(%fred) ; # @list nhn c (aaa, 234.5)
hay (234.5, aaa)
Cc du ngoc trn l tu chn: keys %fred cng
ging nh keys(%fred).
foreach $key (key %fred) {# mt ln cho mi kho
ca %fred
print ti $key chng c $fred{$key}\n; # in kho v
gi tr }

113

Th d ny cng ch ra rng cc phn t mng kt
hp c th chen ln nhau trong cc xu nhy kp. Tuy
nhin bn khng th xen ln ton b mng
*
.
Trong ng cnh v hng, ton t keys() cho li s
cc phn t (cp kho-gi tr) trong mng kt hp.
Chng hn, bn c th tm ra liu mng kt hp c rng
hay khng:
if (keys(%mng no )) { # nu keys() khc khng:
...; # mng l khc rng
}
# ... hoc ...
while (keys(%mng no ) < 10) {
... ; # c lp chu trnh khi c t hn 10 phn t
}

Ton t values()
Ton t values(%tn mng) cho li mt danh sch
tt c cc gi tr hin ti ca %tn mng, theo cng trt
t nh cc kho c ton t keys(%tn mng) cho li.
Nh vi keys(), cc du ngoc trn l tu chn. Chng
hn:
%lastname = (); # buc %lastname l rng
$lastname(fred} = flintstore;
$lastname{barney} = rubble;
@lastname = values(%lastname); # ly cc gi tr
Ti im ny @lastname cha hoc (flintstore,
rubble) hay o ngc ca n.

*
Ny, bn c th y, bng cch dng lt ct, nhng chng ta khng
ni v lt ct y.

114


Ton t each()
Nu bn mun lp trn (tc l xem xt mi phn t
ca) ton b mng kt hp, bn c th dng keys(), duyt
xt tng kho c cho li v nhn gi tr tng ng.
Trong khi phng php ny thng hay c dng, mt
cch hiu qu hn l dng each(%tn mng), ton t s
cho li cp kho-gi tr nh mt danh sch hai phn t.
Vi mi ln thc hin ton t ny cho cng mng, cp
kho-gi tr k tip s c cho li, cho ti khi tt c cc
phn t c truy nhp ti. Khi khng cn cp no
na th each() cho limt danh sch rng.
Vy chng hn, i qua mng %lastname trong th
d trc, lm iu g ta nh th ny:
while (($first, $last) = each(%lastname)) {
print Tn cui cng ca $first l $last\n;
}
Vic gn mt gi tr mi cho ton b mng s t li
tng ton t each() cho t u. Vic b sung hay loi b
cc phn t ca mng rt c th gy ra ln ln each() (v
c th gy ln ln cho c bn na).

Ton t delete
Cho n gi, vi iu bn bit c, bn c th
thm phn t vo mng kt hp, nhng bn khng th
loi b chng (mt vic khc hn l gn gi tr mi cho
ton b mng). Perl cung cp ton t delete loi b
cc phn t. Ton hng ca delete l mt tham chiu
mng kt hp, ht nh nu bn ch nhn vo mt gi tr

115

c bit. Perl loi b cp kho-gi tr khi mng kt hp,
v cho li gi tr ca phn t b xo. Chng hn:
%fred = (aaa, bbb, 234.5, 34.56) ; # cho %fred 2 phn
t
delete $fred{aaa};
# %fred by gi ch cn mt cp kho-gi tr

Bi tp
Xem ph lc A v li gii.
1. Vit mt chng trnh c v in mt xu v gi tr
nh x ca n tng ng vi nh x c trnh by
trong bng sau:

Ci vo Ci ra

lc
xanh
to
l
i dng

2. Vit mt chng trnh c mt chui cc t vi mt
t trn dng cho ti cui tp, ri in ra mt tm tt c
bao nhiu ln mi t gp. (Thm mt thch thc,
sp xp cc t theo th t gim dn m ASCII khi
a ra.)


116



117


6


Vo / ra c bn


Vo t STDIN
Vic c t li vo chun (qua b iu khin Perl
c gi l STDIN) th tht d dng. Chng lm vic
ny vi ton t <STDIN>. Vic tnh ton t ny trong ng
cnh v hng cho bn mt dng tip ca ci vo, hay
undef nu khng cn dng no na, ging nh:
$a = <STDIN>; # c dng tip
Vic tnh ton t ny trong ng cnh mng s cho
bn tt c cc dng cn li nh mt danh sch - mi
phn t ca danh sch ny l mt dng, bao gm cc kt
thc dng mi ca n. Chng thy iu ny trc
y, nhng xem nh vic lm mi li, n c th trng
nh mt ci g ta nh th ny:
@a = <STDIN>;
Trong chng ny:

Vo t STDIN
Vo t ton t
Diamond
a ra STDOUT

118

Mt cch in hnh, mt trong nhng iu bn mun
lm l c tt c cc dng mt lc, v lm iu g trn
mi dng. Mt cch chung lm iu ny l:
while ($_ = <STDIN>) {
# x l $_ ti y (cho tng dng)
}
C mi khi mt dng c c vo, <STDIN> li cho
mt gi tr ng
*
, cho nn chu trnh tip tc thc hin.
Khi <STDIN> khng cn dng no c na th n cho
li undef , cho gi tr sai, kt thc chu trnh.
Vic c mt gi tr v hng cho <STDIN> v dng
gi tr lm biu thc iu khin cho chu trnh (nh
trong th d trc) thng hay xut hin n mc Perl c
hn mt cch vit tt cho n. Bt k khi no vic kim
th chu trnh ch bao gm mt ton t a vo (ci g
ta nh <...>), Perl t ng sao dng c c vo trong
bin $_.
while ($_ = <STDIN>) { # ging while ($_ = <STDIN>)
chop; # ging chop($_)
# cc php ton khc vi $_ y
}
V bin $_ l mc nh cho nhiu php ton nn bn
c th tit kim kh nhiu v vic g theo cch ny.


*
Nu dng cui cng ca tp ch c mt k t 0 th <STDIN> cho
li undef ti dng ; thay v ti cui tp. Nu bn to ra mt tp
ging nh th th ngi lp trnh Perl trn ton th gii s gi cho
bn th gin di. Nhng l mt tp bnh hon lm ph v vic
dng loi chu trnh ny.

119

a vo t ton t hnh thoi
Mt cch khc c ci vo l dng ton t hnh
thoi: <>. Ton t ny ging nh <STDIN> ch n cho
li mt dng ring l trong ng cnh v hng (vi undef
nu tt c cc dng ny c c), hay tt c cc
dng cn li nu c dng trong ng cnh mng. Tuy
nhin, khc vi <STDIN>, ton t hnh thoi ly d liu
t tp hay cc tp c xc nh trn dng lnh c gi
trong chng trnh Perl. Chng hn, nu bn c mt
chng trnh mang tn kitty, bao gm:
#! /usr/bin/perl
while (<>) {
print $_;
}
v nu bn gi kitty vi:
kitty file1 file2 file3
th ton t hnh thoi s c tng dng ca file1 theo sau
bi tng dng ca file2 v file3 ln lt, cho li undef khi
khi tt c cc dng c c ht. Nh bn c th
thy, kitty lm vic ging nh cat, gi tt c cc dng
ca tp c tn ra li ra chun theo tun t. Nu, ging
cat, bn khng xc nh bt k tn tp no trn dng lnh
th ton t hnh thoi s t ng c t li vo chun.
V mt k thut, ton t hnh thoi khng nhn y
nguyn vo cc i dng lnh - n lm vic t mng
@ARGV. Mng ny l mt mng c bit c b thng
dch Perl t sn l mt danh sch cc i dng lnh.
Mi i dng lnh li b b i sau khi Perl ly cc
chuyn mch dng lnh ca n a vo mt phn t
tch bit ca mng @ARGV. Bn c th hiu danh sch

120

ny theo bt k cch no bn mun
*
. Bn thm ch c th
t mng ny bn trong chng trnh ca mnh, v c
ton t hnh thoi lm vic trn danh sch mi thay v cc
i dng lnh, nh th ny:
@ARGV = (aaa, bbb, ccc);
while (<>) { # x l tp aaa, bbb v ccc
print Dng ny l: $_;
}
Trong Chng 10, Gii quyt tp v kim th tp,
chng ta s thy cch m v ng cc tp xc nh vo
thi im xc nh, nhng k thut ny c dng cho
mt s chng trnh nhanh-v-bn ca ti.

a ra STDOUT
Perl dng cc ton t print v printf ghi ln li ra
chun. Xem cch chng c dng.

Dng print cho a ra thng thng
Chng ta dng print hin th vn bn ln li ra
chun. M rng thm mt cht.
Ton t print nhn mt danh sch cc xu, v gi ln
lt tng xu ra li ra chun, khng can thip hay thm
cc k t vo ui. iu c th khng hin nhin l ch
print thc s ch l ton t danh sch, v cho li mt gi
tr ging nh bt k ton t danh sch no khc. Ni cch

*
Th vin chun ca Perl cha cc trnh cho vic phn tch kiu nh
getop cho cc i dng lnh ca chng trnh Perl. Xam Sch con
la bit thm thng tin v th vic ny.

121

khc:
$a = print (xin cho, mi ngi, \n) ;
s l mt cch khc ni xin cho mi ngi. Gi tr cho
li ca print l mt gi tr ng hay sai, ch ra s thnh
cng ca vic in. N gn nh bao gi cng thnh cng,
tr phi bn gp li vo/ra no , cho nn $a trong
trng hp ny s gn nh bao gi cng l 1.
i khi, bn s cn b sung thm cc du ngoc vo
print nh c nu trong th d ny, c bit nu iu
u tin bn mun in bt u vi mt du m ngoc
trn, nh trong:
print (2+3), xin cho; # sai! in 5, b qua xin cho
print ((2+3), xin cho); # ng! in 5xin cho
print 2+3, xin cho; # cng ng! in 5xin cho

Dng printf cho ci ra c dng thc
Bn c th mun c mt cht t kim sot vi ci ra
hn l kh nng print cung cp. Thc ra, bn c th quen
vi ci ra c dng thc ca hm printf ca C. Ch c s -
Perl cung cp mt php ton tng ng vi cng tn.
Ton t printf nhn mt danh sch i (c bao
trong du ngoc trn tu chn, nh ton t print). i th
nht l mt xu kim sot dng thc, xc nh cch in
cc i cn li. Nu bn cn cha quen thuc vi hm
printf chun, th bn nn kim tra xem li hm printf. Tuy
nhin, xem nh mt th d:
printf %15s %5d %10.2f\n, $s, $n, $r;
s in ra $s trong mt trng 15 k t, ri n du

122

cch, ri n $n xem nh mt s nguyn trong trng 5
k t, ri n mt du cch khc, n $r nh gi tr du
phy ng vi 2 v tr thp phn trong mt trng 10 k
t, v cui cng l mt du dng mi.

Bi tp
Xem Ph lc A v li gii.
1. Vit mt chng trnh hnh ng nh cat, nhng o
ngc th t cc dng. (Mt s h thng c tin ch
kiu nh vy mang tn tac.)
2. Vit mt chng trnh c mt danh sch cc xu ri
in ra xu trong mt ct c cn l phi 20 k t. Chng
hn, a vo xin cho, tm bit in ra xin cho v tm
bit c cn l phi trong ct 20 k t.
3. Sa i chng trnh ca bi tp trc cho php
ngi dng chn ly chiu rng ct. Chng hn, a
vo 20, xin cho v tm bit cng lm cng vic nh
chng trnh trc lm, nhng a vo 30, xin
cho v tm bit th phi cn l xin cho v tm bit
theo ct 30 k t.



123


7


Biu thc
chnh qui


Khi nim v biu thc chnh qui
Biu thc chnh qui l mt khun mu - mt khun
mu - c snh vi mt xu. Vic snh mt biu
thc chnh qui vi mt xu th hoc thnh cng hoc tht
bi. i khi, s thnh cng hay tht bi ny c th l tt
c nhng g bn quan tm ti. Vo lc khc, bn s
mun ly mt khun mu snh ng v thay th n
bng mt xu khc, mt phn trong c th ph thuc
ch xc vo cch thc v ni chn m biu thc chnh
qui c snh ng.
Biu thc chnh qui thng c nhiu chng trnh
UNIX dng ti, nh grep, sed, awk, ed, vi, emacs v
Trong chng ny:

Khi nim v biu
thc chnh qui
Cch dng n
gin v biu thc
chnh qui
Khun mu
Thm v ton t
i snh
Php th
Ton t split() v
join()


124

thm ch c nhiu v na. mi chng trnh c mt
tp cc k t khun mu khc nhau (phn ln l chm
ln nhau). Perl l mt siu tp ng ngha cho tt c
nhng cng c ny - bt k biu thc chnh qui no m
c th c vit trong mt trong nhng cng c UNIX
ny th cng c th c vit trong Perl, nhng khng
nht thit dng ht cc k t .

Cch dng n gin v biu thc chnh qui
Nu chng tm tt c cc dng ca mt tp c cha
xu abc, th c th dng ch lnh grep:
grep abc sonefile > result
Trong trng hp ny, abc l biu thc chnh qui m
ch lnh grep ly kim tra cho tng dng a vo.
Nhng dng snh ng s c chuyn ra li ra chun (
y, kt thc vi tp result v vic chuyn hng ca v).
Trong Perl, c th ni v xu abc nh biu thc
chnh qui bng vic bao xu ny trong hai du s cho:
if (/abc/) {
print $_;
}
Nhng ci g c kim tra so vi biu thc chnh
qui abc trong trng hp ny? Ti sao, anh bn c ca
chng ta, bin $_ li c mt y? Khi mt biu thc
chnh qui c bao trong hai du s cho (nh trn), th
bin $_ s c kim tra theo biu thc chnh qui .
Nu biu thc chnh qui snh ng, th ton t snh s
cho li gi tr ng. Ngoi ra, n cho li gi tr sai.
Trong th d ny, bin $_ c gi s c cha mt

125

dng vn bn no , v c in ra nu dng ny c
cha cc k t abc u bn trong dng - tng t nh
ch lnh grep trn. Khng ging nh ch lnh grep, vn
hnh trn tt c cc dng ca tp, on chng trnh Perl
ny ch nhn vo c mt dng thi. lm vic trn tt
c cc dng, cn thm vo mt chu trnh, nh trong:
while (<>) {
if (/abc/) {
print $_;
}
}
iu g s xy ra nu nh khng bit c s ca
cc b gia a v c? Tc l, iu g s xy ra nu mun in
dng c cha mt a v theo sau n l khng hay nhiu b,
ri theo sau na l mt c? Vi grep, phi ni:
grep ab*c somefile > result
(i ny c cha du sao trong ngoc kp bi v
chng khng mun lp v tri rng i c nh l mt
mu tn tp. N phi c truyn qua grep c hiu
qu.) Th m trong Perl, chng ta c th ni ch xc
cng iu :
while (<>) {
if (/ab*c/) {
print $_;
}
}
Cng ht nh grep, iu ny c ngha l mt a theo
sau bi khng hay nhiu b, theo sau l c.
Chng ta s xem xt nhiu tu chn khc v ton t
i snh trong mc Ni thm v ton t i snh,
cui chng ny, sau khi ni v tt c cc loi biu

126

thc chnh qui.
Mt ton t biu thc chnh qui na l ton t thay
th, lm vic thay th mt phn ca xu m snh ng
biu thc chnh qui bng mt xu khc. Ton t thay th
ging nh ch lnh s trong sed, bao gm mt ch s, mt
s cho, mt biu thc chnh qui, mt s cho, mt xu
thay th, v mt s cho cui cng, trng ta nh th
ny:
s/ab*c/def/;
Xu (trong trng hp ny l bin $_) c em ra
i snh vi biu thc chnh qui (ab*c). Nu vic i
snh thnh cng, th phn ca xu snh ng s b loi ra
v c thay th bng xu thay th (def). Nu vic i
snh khng thnh cng th chng c g xy ra c.
Nh vi ton t i snh, s cn xem xt li v s
cc tu chn v ton t thay th di y, trong mc
Thay th.

Khun mu
Mt biu thc chnh qui l mt khun mu. Mt s
phn ca khun mu snh ng ch cc k t trong xu
thuc kiu c bit. Nhng phn khc ca khun mu
snh ng cho a k t, hay a a k t. Trc ht, s
xem cc khun mu mt k t, ri n cc khun mu a
k t.


127

Khun mu mt k t
K t snh mu n gin nht v thng dng nht
trong cc biu thc chnh qui l mt k t snh vi chnh
n. Ni cch khc, t mt ch a vo trong biu thc
chnh qui i hi mt ch tng ng a trong xu.
K t snh mu thng dng nht tip l du chm
.. Du chm i snh bt k k t ring l no ngoi tr
du dng mi (\n). Chng hn, khun mu /a./ i snh
bt k dy hai k t no bt u bng a v khng phi l
a\n.
Lp k t snh mu c biu din bi cp du
ngoc vung m v ng, v mt danh sch cc k t
nm gia hai du ngoc ny. Mt v ch mt trong cc k
t ny phi hin din ti phn tng ng ca xu cn
snh mu. Chng hn,
/[abcde]/
snh vi bt k mt trong nm ch u tin ca bng
ch thng, trong khi
/[aeiouAEIOU]/
li snh vi bt k nm nguyn m hoc ch thng
hoc ch hoa. Nu bn mun t du ngoc vung phi
(]) vo danh sch th t mt s cho ngc trc n,
hay t n nh k t u tin bn trong danh sch. Phm
vi ca cc k t (nh a ti z c th c vit tt bng
vic ch ra nhng im cui ca phm vi c tch bit
bi du gch ngang (-); c c hng k hiu gch
ngang, t trc du gch ngang mt s cho ngc. Sau
y l mt s th d khc:
[0123456789] # snh vi mi ch s

128

[0-9] # cng th
[0-9\-] # snh 0-9 hay du tr
[a-z0-9] # snh bt k ch thng hay s no
[a-zA-Z0-9_] # snh bt k ch, s hay du gch thp
Cng c lp k t b ph nh, cng l cng lp k
t, nhng c thm du mi tn ngc (hay du m ^)
ng trc, i ngay sau du ngoc tri. Lp k t ny i
snh vi bt k k t n no khng trong danh sch.
Chng hn:
[^0-9] # snh vi bt k k t phi s no
[^aeiouyAEIOUY] # snh vi bt k k t no khng
nguyn m
[^\^] # snh vi mt k t n tr mi tn ngc
tin cho bn, c nh ngha sn mt s lp k
t chung, nh c m t trong Bng 7-1.

Bng 7-1: Vit tt cho lp k t nh sn
Kt cu Lp tng
ng
Kt cu
ph nh
Lp ph
nh tng
ng
\d (s) [0-9] \D (s,
khng!)
[^0-9]
\w (t) [a-zA-Z0-
9_]
\W (t,
khng!)
[^a-zA-Z0-
9_]
\s (cch) [ \r\t\n\f] \S (cch,
khng!)
[^ \r\t\n\f]

Khun mu \d snh vi s. Khun mu \w snh

129

vi k t t, mc du iu thc s snh ng l bt k
ci g hp l trong tn bin Perl. Khun mu \s snh vi
du cch (khong trng), y c xc nh nh du
cch, v u dng (khng hay dng my trong UNIX),
tab, xung dng (du dng mi ca UNIX), v ko giy.
Cc bn ch hoa snh ng vi ci i lp cho nhng
lp ny.

Khun mu nhm
Sc mnh thc s ca biu thc chnh qui l khi bn
c th ni mt hay nhiu nhng th ny hay cho ti
nm th ny. Ta ni v cch thc hin iu ny.

Dy
Khun mu nhm u tin (v c l km hin nhin
nht) l dy. iu ny c ngha l abc snh ng vi mt
a theo sau l b, theo sau l c. N dng nh n gin,
nhng ti c t tn cho n ti c th ni v n sau
ny.
Bi
Chng thy du sao (*) nh mt khun mu
nhm. Du sao ch ra rng khng hay nhiu k t (hay
lp k t) ng ngay trc n.
Hai khun mu nhm khc lm vic ging th l du
cng (+), ngha l mt hay nhiu k t ng ngay
trc, v du hi (?), ngha l khng hay mt k t
ngay trc. Chng hn, biu thc chnh qui /fo+ba?r/
snh ng cho mt f theo sau l mt hay nhiu o, theo

130

sau l a, b v tu chn a, theo sau l mt r.
Trong tt c ba khun mu nhm ny, cc khun
mu tham lam. Nu mt khun mu nh vy c c
hi snh ng gia nm v mi k t th n s lc ra
xu mi k t mi lc. Chng hn:
$_ = fred xxxxxxxxxx barney;
s/x*/boom/;
bao gi cng thay tt c cc x lin tip bng boom
(kt qu l fred boom barney), thay v ch thay th cho
mt hay hai x, cho d mt tp x ngn hn cng snh
c cho cng biu thc chnh qui
Nu bn cn ni nm ti mi x, th bn c th
xoay x bng cch t nm x theo sau bi nm x na i
lin sau du chm hi. Nhng lm th trng xu, m
cng chng lm vic tt lm. Thay v vy, c mt cch
d hn: s bi tng qut. S bi tng qut bao gm mt
cp du ngoc nhn vi mt hay hai s bn trong, nh
trong /x{5,10}/. Ging nh ba s bi khc, k t ng
ngay trc (trong trng hp ny l ch x) phi c
tm thy bn trong s ln lp ch ra (nm n mi
y).
Nu bn b i con s th hai, nh trong /x{5,}/, th
iu ny c ngha l nhiu hay hn na (nm hay
nhiu hn trong trng hp ny), v nu bn b nt du
phy, nh trong /x{5}/, th iu c ngha l ng con
s ny (nm x). c 5 x hay t hn, bn phi t s
khng vo, nh trong /x{0,5}/.
Vy, biu thc chnh qui /a.{5}b/ snh ng cho k
t a c tch vi k t b bi bt k nm k t khc k t
dng mi. (Nh li rng du chm snh vi bt k k t

131

khc du dng mi, v chng snh vi nm k t nh th
y.) Nm k t ny khng cn phi nh nhau. (Chng
ta s bit cch buc chng l nh nhau trong mc
tip.)
C th min tr hon ton bng *, +, v ?, v chng
hon ton tng ng vi {0,}, {1,}, v {0,1}. Nhng
d dng hn vn l g mt k t ngt tng ng, m
cng quen thuc hn.
Nu c hai s bi trong mt biu thc, th qui tc
tham lam c tng ln vi bn tri nht l tham nht.
Chng hn:
$_ = a xxx c xxxxxxx d;
/a.*c.*d/;
Trong trng hp ny, .* th nht trong biu thc
chnh qui snh vi tt c cc k t cho ti c th hai, cho
d vic snh ng ch vi cc k t cho ti c u tin vn
cho php ton b biu thc chnh qui c snh. iu
ny khng to ra khc bit g (khun mu s snh theo c
hai cch), nhng sau ny khi chng c th nhn vo cc
b phn ca biu thc chnh qui m c snh, th s c
i cht vn .
iu g xy ra nu biu thc xu v chnh qui hi b
thay i i, chng hn nh:
$_ = a xxx ce xxxxxxx ci xxx d;
/a.*ce.*d/;
Trong trng hp ny, nu .* snh vi phn ln cc
k t c th trc c tip, th k t biu thc chnh qui tip
(e) s khng snh vi k t tip ca xu (i). Trong trng
hp ny, thu c vic ln ngc t ng - s bi b

132

tho ra v th li, dng li ti ch no pha trc
(trong trng hp ny, ti c trc, tip sau l (e)
*
. Mt
biu thc chnh qui phc tp c th bao gm nhiu mc
ln ngc nh vy, dn ti thi gian thc hin lu.

Du ngoc trn nh b nh
Mt ton t nhm khc l cp m v ng ngoc
trn quanh bt k phn khun mu no. iu ny khng
lm thay i liu khun mu c snh ng hay khng,
nhng thay v th li lm cho mt phn ca xu c
khun mu snh ng s c ghi nh, cho n c th
c tham chiu ti v sau. Vy chng hn, (a) vn snh
vi a, cn ([a-z]) th vn snh vi bt k ch thng no.
nh li mt phn ghi nh ca mt xu, bn
phi a vo mt du s cho ngc theo sau bi mt s
nguyn. Kt cu khun mu ny biu th cho cng dy
cc k t c snh trc y trong cp du ngoc trn
cng s (m t mt) . Chng hn:
/fred(.)barney\1/;
snh mt xu c cha fred, tip theo l mt k hiu
khc du dng mi, tip na l barney, ri tip bi cng
mt k t . Vy, n snh vi fredxbarneyx, nhng
khng snh vi fredxbarneyy. So snh iu vi:
/fred.barney./
trong hai k t khng xc nh c th l mt, hay

*
V mt k thut, c nhiu cch ln ngc ca ton t * tm ra c
v tr u tin. Nhng phi hi th thut hn m t n, m n
vn hot ng theo cng nguyn l.

133

khc nhau - cng chng thnh vn g.
S 1 n t u vy? N c ngha l phn biu thc
chnh qui nm trong du ngoc u tin. Nu c nhiu
phn nh th, th phn th hai (m cc du ngc tri t
tri sang phi) s c tham chiu ti l \2, phn th ba
l \3, v c th. Chng hn:
/a(.)b(.)c\2d\1/;
s snh vi mt a, mt k t (gi n l #1), mt b,
mt k t khc (gi n l #2), mt c, k t #2, mt d, v
k t #1. Cho nn n snh vi axbycydx, chng hn.
Phn c tham chiu ti c th nhiu hn mt k
t. Chng hn:
/a(.*)b\1c/;
snh vi mt a, theo sau bi mt s bt k k t no
(thm ch khng), theo sau bi b, theo sau bi cng dy
k t , theo sau bi c. Vy, n s snh vi
aFREDnFREDc, hay thm ch abc, nhng khng
aXXbXXXc.
Mt cch dng khc ca phn c nh ca biu
thc chnh qui l trong xu thay th ca ch lnh thay
th. Kt cu kiu \1 vn gi gi tr ca chng trong xu
thay th, v c th c tham chiu ti xy dng xu,
nh trong:
$_ = a xxx b yyy c zzz d;
s/b(.*)c/d\1e/;
m s thay th b v c bng d v e, vn gi li phn
gia.


134

Thay phin
Mt kt cu nhm khc l thay phin, nh trong
a|b|c. iu ny c ngha l snh ng mt trong cc kh
nng (a hay b hay c trong trng hp ny). iu ny vn
c tc dng ngay c khi cc thay phin c nhiu k t,
nh trong /song|blue/, s snh hoc song hoc blue. (Vi
nhng thay phin n gin, tt hn c l bn c th b
lp k t nh /[abc]/.)
iu g xy ra nu mun snh songbird hay bluebird?
c th vit /songbird|bluebird/, nhng phn bird khng
nn c hai ln. Thc ra, cng c cch ra, nhng phi
ni ti th t u tin cho cc khun mu nhm, s c
cp ti trong mc Th t u tin di y.

Khun mu neo
Bn k php c bit ng neo cho mt khun mu.
Thng thng, khi mt khun mu c snh vi xu th
s bt u ca khun mu c r i trong ton b
xu t tri sang phi, snh vi c hi c th u tin.
Neo cng cho php bn m bo rng cc phn ca dng
khun mu sp thng vi nhng phn c bit ca xu.
Cp neo th nht i hi rng mt phn c bit ca
vic i snh phi c nh v ti bin gii t hay
khng ti bin gii t. Neo \b yu cu mt bin gii t
ti im ch ra cho khun mu i snh. Bin gii t
l ni gia cc k t snh vi \w v \W, hay gia cc k
t snh vi \w v ch bt u hay kt thc ca xu. Ch
rng iu ny t phi x l i vi ting Anh v phi
lm nhiu i vi cc k hiu C, nhng iu cng gn

135

thi khi t ti. Chng hn:
/fred\b/; # snh fred, nhng khng Frederick
/\bwiz/; # snh wiz v wizard, nhng khng qwiz
/\bFred\b/; # snh Fred nhng khng Frederick hay
alFred
/abc\bdef/; # khng bao gi snh (khng th c cn
y)
Ging th, \B yu cu khng c bin gii t ti v tr
ch ra. Chng hn:
/\bFred\B/; # snh Frederick nhng khng Fred
Flintstonee
Hai neo na yu cu rng mt phn c bit ca
khun mu phi i ngay sau cui xu. Du m (^) snh
vi im bt u ca xu nu n ang mt v tr to ra
ngha i snh ti ch bt u ca xu. Chng hn, ^a
snh mt a nu v ch nu a l k t u tin ca xu.
Tuy nhin, ^a cng snh vi hai k t a v ^ bt k u
trong xu. Ni cch khc, du m mt ngha c
bit ca n. Nu bn cn du m l mt hng k hiu du
m ngay ti ch bt u, t mt du s cho ngc pha
trc n.
Du $ cng ging nh ^, neo li khun mu, nhng
ti cui ca xu, khng phi bt u. Ni cch khc,
c$ snh vi mt c ch nu n xut hin ti cui xu. Du
la bt k ni u khc trong khun mu c l vn c
c din gii nh cch hiu gi tr v hng, cho nn
bn gn nh bao gi cng phi dng du s cho ngc
i snh mt du hiu l hng k hiu trong xu.


136

Th t u tin
Vy iu g xy ra khi ly a|b* cng nhau? Liu y
l a hay b mt s ln bt k hay ch mt a hay nhiu b?
c ri, cng ging nh cc ton t c s u tin,
cc khun mu b neo v gp nhm cng c s u tin.
S u tin ca khun mu t cao xung thp nht c
cho trong Bng 7-2.
Bng 7-2: S u tin ton t gp nhm biu thc
chnh qui (cao nht xung thp nht)
Tn Biu din
Du ngoc trn ( )
S bi + * ? {m,n}
Tun t v b neo abc^$\b\B
Thay phin |
Theo bng ny, * c s u tin cao hn |. Cho nn
/a|b*/ c din gii nh mt a, hay s bt k b.
iu g xy ra nu mun mt ngha khc, nh trong
bt k s a hay b no? Chng n thun ch nm vo
mt cp du ngoc. Trong trng hp ny, bao phn ca
biu thc m ton t * cn p dng, vo bn trong cc
du ngoc, v s c n, nh (a|b)*. Nu bn mun lm
r rng biu thc th nht, th bn c th ng du ngoc
d tha n vi a|(b*).
Khi bn dng du ngoc tc ng ti s u tin
chng cng t ly b nh, nh ch ra trc y trong
chng ny. Tc l tp cc du ngoc ny s cn c
m khi bn mun ni ti mt ci g l \2, \3 hay bt

137

k ci g. Mt ngy no c th c mt loi du ngoc
m khng phi m, nhng cha c trong ln a ra Perl
4.036.
Sau y l mt s th d khc v biu thc chnh
qui, v tc ng ca du ngoc:
abc* $ snh vi ab, abc, abcc, abccc, abcccc vn vn
(abc)* # snh vi , abc, abcabc, abcabcabc vn vn
^x|y # snh x ti u dng, hay y bt k u
^(x|y) # snh hoc vi x hoc vi y ti u dng
a|bc|d # a hoc bc hoc d
(a|b)(c|d) # ac, ad, bc hoc bd
(song|blue)bird # songbird hay bluebird

Thm v ton t i snh
Chng ta nhn vo cch dng n gin nht ca
ton t i snh (mt biu thc chnh qui c bao trong
s cho). By gi nhn vo v vn cch lm cho ton t
ny lm c iu g hi khc hn.

Chn mt mc tiu khc (ton t =~)
i khi xu bn mun snh vi khun mu li
khng bn trong bin $_, v s l sc thi t n
(c l bn c mt gi tr trong $_ m bn rt
thch). Khng h g. Ton t =~ s gip y. Ton t
ny nhn mt ton t biu thc chnh qui v bn phi,
ri thay i i tng ca ton t ny thnh mt ci g
bn cnh bin $_ - c ngha l mt gi tr no c
tn bn v tri ca ton t ny. N trng ta nh th ny:
$a = hello world;

138

$a =~ /^he/; # ng
$a =~ /(.)\l/; # cng ng (snh vi hai l)
if ($a =~ /(.)\1/) { # ng, cho nn c ...
# mt s cht liu khc
}
Mc tiu ca ton t =~ c th l bt k biu thc
no cho mt gi tr xu v hng no . Chng hn,
<STDIN> cho mt gi tr xu v hng khi c dng
trong hon cnh v hng, cho nn chng c th t hp
iu ny vi ton t =~ v mt ton t snh biu thc
chnh qui c mt kim tra gn gng v ci vo c
bit, nh trong:
print cn yu cu no na khng?;
if (<STDIN> =~ /^[yY]/) { # ci vo c bt u bng mt y
khng?
print Vy yu cu c th l g? ;
<STDIN>; # b mt dng ci vo chun
print Rt tic, ti khng th lm c iu .\n;
Trong trng hp ny, ton t <STDIN> cho dng
tip t ci vo chun, m ri ngay lp tc c dng nh
xu em snh vi khun mu ^[yY]. Lu rng bn
cha bao gi ct gi ci vo vo mt bin, cho nn nu
bn mun snh ci vo vi mu khc, hay c th cho
hin li d liu trong mt thng bo li th bn khng
gp may ri. Nhng dng ny thng hay n ng lc.

B qua ch hoa thng
Trong th d trc, ti dng [yY] i snh
hoc ch Y hoa hoc y thng. Vi nhng xu rt ngn
nh y hay fred th iu ny l d dng, nh [fF]
[oO][oO]. Nhng iu g xy ra nu xu ti mun snh

139

li l t procedure trong hoc ch thng hoc ch
hoa?
Trong mt s bn ca grep, c -i ch ra b qua hoa
thng. Perl cng c tu chn nh vy. Bn ch ra tu
chn b qua hoa thng bng cch thm vo ch i
thng vo sau s cho ng, nh trong /somepattern/i.
iu ny ni ln rng cc ch ca khun mu ny s
snh vi cc ch trong xu trong c ch hoa ln thng.
Chng hn, snh t procedure trong c hoa ln
thng ti u dng, dng /^procedure/i.
By gi th d trc ca trong ging th ny:
print cn yu cu no na khng?;
if (<STDIN> =~ /^y/i) { # ci vo c bt u bng mt y
khng?
# c! x l cho n
...
}

Dng mt nh bin khc
Nu bn ang tm kim mt xu vi mt biu thc
chnh qui c cha k t s cho (/), th bn phi t trc
mi s cho mt s cho ngc (\). Chng hn, bn c
th tm mt xu bt u bng /usr/etc ta nh th ny:
$path = <STDIN>; # c mt tn ng dn (c l t
find?)
if ($path =~ /^\/usr\/etc/) {
# bt u vi /usr/etc ...
}
Nh bn c th thy, t hp s cho ngc-s cho
lm cho n trng ging nh c mt thung lng nh gia
hai mu vn bn. Lm iu ny cho nhiu s cho c th

140

gy cng knh, cho nn Perl cho php bn xc nh mt
k t nh bin khc. Ch cn t trc bt k k t phi
ch-s
*
no (nh bin do bn chn) vi mt m, ri lit
k khun mu ca bn theo sau bi mt k t nh bin y
ht th na, l bn hon thnh, nh trong:
/^\/usr/etc/ # dng nh bin s cho chun
m@^/usr/etc@ # dng @ lm nh bin
m#^/usr/etc# # dng # lm nh bin (s thch ca ti)
Bn c th thm ch dng c s cho ln na nu
bn c mun, nh trong m/fred/, cho nn ton t snh
biu thc chnh qui thng thng thc s l ton t m,
tuy nhin, m l tu chn, nu bn chn s cho lm nh
bin.

Dng xen ln bin
Mt biu thc chnh qui l c xen ln bin trc
khi n c xem xt cho cc k t c bit khc. Do ,
bn c th xy dng mt biu thc chnh qui t cc xu
c tnh ton thay v ch l hng k hiu. Chng hn:
$what = bird;
$sentence = Mi con chim tt bay.;
if ($sentence =~ /\b$what\b/) {
print Cu ny cha t $what!\n;
}
Ti y chng xy dng mt cch c hiu qu
ton t biu thc chnh qui /\bbird\b/ bng vic dng mt

*
Nu du nh bin ngu nhin l k t bn tri hay cp tri-phi
(ngoc trn, ngoc nhn hay ngoc vung), th du nh bin ng
l k t bn phi ca cng cp . Nhng ngoi ra, cc k t l ht
nhau cho bt u v kt thc.

141

tham chiu bin.
Sau y l mt th d c hi phc tp hn:
$sentence = Mi con chim tt bay.;
print Ti phi tm ci g y?;
$what = <STDIN>;
chop ($what) ;
if ($sentence =~ /$what/) { # tm thy n!
print Ti thy $what trong $sentence.\n;
} else {
print khng... chng thy cc g c.\n;
}
Nu bn a vo bird, th n c tm ra. Nu bn
a vo scream n s khng tm thy. Nu bn a vo
[bw]ird, iu y cng c tm ra, ch ra rng cc k t i
snh khun mu biu thc chnh qui qu thc l vn c
ngha. Ti s ch ra cho bn trong phn Thay th di
y v cch thay i xu cho cc k t i snh khun
mu chnh qui c tt i.

Bin ch c c bit
Sau khi i snh khun mu thnh cng, cc bin
$1, $2, $3 vn vn s c t cho cng gi tr l \1, \2,
\3 vn vn. Bn c th dng iu ny nhn vo mt
phn ca vic i snh trong on chng trnh sau.
Chng hn:
$_ = y l php kim tra;
/(\W+)\W+(\W+)/; # i snh hai t u
# $1 by gi l y cn $2 by gi l l
Bn cng c th thu c cng cc gi tr ($1, $2,
$3 vn vn) bng vic t i snh trong hon cnh

142

mng. Kt qu l mt danh sch cc gi tr m s c
t cho $1 cho ti s cc vt c ghi nh, nhng ch
nu biu thc chnh qui snh ng. Ly li th d trc
theo cch khc
$_ = y l php kim tra;
($first, $second) = /(\W+)\W+(\W+)/; # i snh hai t
u
# $first by gi l y cn $second by gi l l
Lu rng cc bin $1 v $2 vn khng b thay i.
Cc bin ch c c xc nh trc cn bao gm
$&, m l mt phn ca xu snh ng vi biu thc
chnh qui; $`, l mt phn ca xu trc phn snh ng;
cn $ l phn ca xu sau phn snh ng. Chng hn:
$_ = y l xu mu;
/x.*u/; # snh xu bn trong xu
# $` by gi l y l
# $& by gi l xu
# $ by gi l mu
V tt c nhng bin ny c t li cho tng
ln snh thnh cng cho nn bn nn ct gi cc gi tr
trong cc bin v hng khc nu bn cn cc gi tr
v sau trong chng trnh.

Thay th
Chng ta ni v dng n gin nht ca ton t
thay th: s/old-regex/new-string/. By gi l lc ni ti vi
bin th ca ton t ny.
Nu bn mun vic thay th vn hnh trn tt c cc
i snh c th thay v ch vic i snh u tin th vit

143

thm g vo ton t ny, nh trong:
$_ = foot fool buffon;
s/foo/bar/g; # $_ by gi l bart barl bufbarn
Xu thay th c bin xen vo, cho php bn xc nh
xu thay th vo lc chy:
$_ = hello, world ;
$new = goodbye;
s/hello/$new/; # thay th hello bng goodbye
Cc k t khun mu trong biu thc chnh qui cho
php cc khun mu c i snh, thay v ch l cc k
t c nh:
$_ = y l php kim tra;
s/(\w+)/<$1>/g; # $_ by gi l <y> <l> <php>
<kim> <tra>
Nh li rng $1 c t l d liu bn trong vic
i snh ng mu trong du ngoc.
Hu t i (hoc trc hoc sau g nu c) lm cho biu
thc chnh qui trong ton t thay th b qua ch hoa
thng, ging nh cng tu chn trn ton t i snh
m t trc y.
Cng vy, ging nh ton t i snh, mt du nh
bin khc cng c th c tuyn la nu s cho l
khng tin. Ch cn dng cng k t ba ln:
*

s#fred#barney#; # thay fred bng barney, ging
s/fred/barney/

*
hoc hai cp snh nhau nu k t tri - phi c dng.

144

Cng vy, ging ton t i snh, bn c th xc
nh mt mc tiu thay phin bng ton t =~. Trong
trng hp ny, mc tiu c chn phi l mt ci g
m bn c th gn cho mt gi tr v hng vo, nh
mt bin v hng hay mt phn t ca mng. Sau y
l mt th d:
$which = y l php th;
$which =~ s/th//; # $which by gi l y l php

$someplace[$here] =~ s/left/right/; # i mt phn t
mng
$d{t} =~ s/^/x/; # thay bt k k t no bng x cho
phn t mng kt hp

Cc ton t split() v join()
Biu thc chnh qui c th c dng cht mt
xu thnh cc trng. Ton t split() thc hin iu ny
cn ton t join() li c th dnh cc mu li vi nhau.

Ton t split()
Ton t split() nhn mt biu thc chnh qui v mt
xu ri tm tt c mi s xut hin ca biu thc chnh
qui bn trong xu ny (dng nh bn thc hin ton
t s///g). Cc b phn ca xu khng snh vi biu thc
chnh qui s c cho li ln lt nh mt danh sch cc
gi tr. Chng hn, sau y l mt cch phn tch cc
thnh t /etc/passwd:
$line =

145

merlyn::118:10:Randal:/home/merlyn:/usr/bin/perl;
@fields = split(/:/,$line); # cht $line ra, dng : lm du
nh bin
# by gi @field l (merlyn, , 118, 10, Randal,
#
/home/merlyn,/usr/bin/perl)
Lu rng trng th hai rng tr thnh mt xu
rng. Nu bn khng mun iu ny, i snh tt c cc
hai chm trong mt ln phn tch:
@fields = split(/:+/, $line);
iu ny s snh c hai du hai chm i km, cho
nn s khng c trng th hai rng na.
Mt xu thng dng cht bin $_, v bin thnh
mc nh l:
$_ = xu no ;
@words = split(/ /); # ht nh @words = split(/ /, $_);
Lu rng i vi vic cht ny, cc khong cch
lin tip trong xu cn cht s gy ra cc trng khng
(xu rng) trong kt qu. Mt khun mu tt hn s l /
+/, hay mt cch l tng /\s+/, m s i snh mt hay
nhiu k t khong trng. Thc ra, khun mu ny l
khun mu mc nh, cho nn nu bn nh cht bin $_
theo cc khong trng, th bn c th dng tt c cc mc
nh v n thun ni:
@words = split; # ht nh @words = split(/\s+/, $_);
Cc trng theo sau rng khng tr thnh mt phn
ca danh sch. iu ny ni chung khng cn quan tm -
mt gii php ging th ny:
$line =
merlyn::118:10:Randal:/home/merlyn:/usr/bin/perl;

146

($name, $password, $uid,$gid,$gcos,$home,$shell) =
split(/:/, $line); # cht $line ra bng cch dng : lm du
nh bin
s n thun cho $shell mt gi tr khng (undef) nu
dng ny khng di, hay nu n cha cc gi tr rng
trong trng cui. (Cc trng ph th im lng b b qua,
v vic gn danh sch lm vic theo cch .)

Ton t join()
Ton t join() nhn mt danh sch cc gi tr v gn
chng li vi nhau dng xu gn gia tng phn t danh
sch. N trng ta nh th ny:
$bigstring = join($glue, @list);
Chng hn, xy dng li dng mt hiu, th mt
cch kiu nh:
$outline = join(:, @fields);
Lu rng xu gn khng phi l biu thc chnh
qui - ch l mt xu bnh thng gm khng hay nhiu k
t.

Bi tp
Xem Ph lc A v li gii.
1. Xy dng mt biu thc chnh qui snh cho:
(a) t nht mt a theo sau bi mt s bt k b
(b) mt s bt k du s cho ngc theo sau bi mt
s bt k du sao

147

(c) ba bn sao lin tip ca bt k ci g c cha
trong $whatever
(d) bt k nm k t no, k c du dng mi
(e) cng mt t c vit hai hay nhiu ln trong
mt hng, vi t c xc nh nh dy cc k
t khc khong trng khng rng.
2. (a) Vit mt chng trnh nhn mt danh sch cc t
trn STDIN v tm mt dng c cha tt c nm
nguyn m (a, e, i, o , u). Chy chng trnh ny trn
/usr/dict/words v xem n cho ra ci g. Ni cch
khc, a vo:
$ myprogram < /usr/dict/words
(iu ny gi s bn t tn chng trnh ca mnh
l myprogram)
(b) Sa i chng trnh ny cho nm nguyn m
ny c sp th t
3. Vit mt chng trnh tm trong /etc/passwd (trn
STDIN), in ra tn ng nhp v tn tht ca tng
ngi dng. (Hng dn: dng split cht dng
ny thnh cc trng, ri s/// b cc phn trng
comment i sau du phy th nht.)
4. Vit mt chng trnh tm trong /etc/passwd (trn
STDIN) hai ngi dng c cng h, ri in ra tn ca
h. (Hng dn: sau khi trch ra tn, to ra mt mng
kt hp vi tn lm kho v s ln gp n l gi
tr. Khi dng cui ca STDIN c c vo th
duyt qua mng kt hp m cc s ln hn 1.)
5. Lp li bi tp trc, nhng bo co v tn ng

148

nhp ca tt c ngi dng vi cng tn ca h.
(Hng dn: thay v ct gi mt s m, ct gi mt
danh sch cc tn ng nhp cch nhau bng du
cch. Khi kt thc, duyt qua cc gi tr c cha mt
du cch.)


149


8


Hm


Hm h thng v hm ngi dng
Chng ta thy v dng cc hm h thng,
nh chop, print vn vn. By gi nhn vo cc hm bn
nh ngha ra, to nn cc lnh chng trnh Perl.

Xc nh mt hm ngi dng
Mt hm ngi dng, thng hay c gi l
chng trnh con hay trnh con, c xc nh trong
chng trnh Perl ca bn bng vic dng mt kt cu
nh:
sub subname {
cu lnh 1;
cu lnh 2;
cu lnh 3;
Trong chng ny:

Cc hm h
thng v ngi
dng
nh ngha mt
hm ngi dng
Cho li gi tr
i
Bin cc b
trong hm


150

}
subname l tn ca chng trnh con, l bt k tn
no ging nh tn t cho bin v hng, mng v
mng kt hp. Mt ln na, nhng tn ny li n t mt
khng gian tn khc, cho nn bn c th c mt bin v
hng $fred, mt mng @fred, mt mng kt hp %fred,
v by gi mt trnh con fred.
Khi cc cu lnh i sau tn trnh con tr thnh nh
ngha ca trnh con. Khi trnh con c gi ti (c m
t ngn gn), th khi cc cu lnh to nn trnh con ny
s c thc hin, v bt k gi tr cho li no (c m
t sau y) c tr v cho ni gi.
Chng hn sau y l mt trnh con cho hin th cu
ni ni ting:
sub say_hello {
print Xin cho, mi ngi!\n;
}
nh ngha trnh con c th bt k u trong vn
bn chng trnh ca bn (chng b b qua khi thc
hin), nhng ti th thch t tt c cc trnh con ca ti
vo cui tp, cho phn cn li ca chng trnh c v
nh l u tp. (Nu bn thch ngh theo kiu Pascal
th bn c th t cc trnh con ca mnh vo u v cc
cu lnh thc hin vo cui. iu y th tu bn.)
Cc nh ngha trnh con l ton cc; khng c trnh
con cc b. Nu bn c hai nh ngha trnh con vi cng
tn th trnh sau s lp trnh trc m khng c cnh
bo g c.
Bn trong thn trnh con, bn c th truy nhp hay

151

t cc gi tr cho cc bin c dng chung vi phn
cn li ca chng trnh (bin ton cc). Thc ra, theo
mc nh, mi tham chiu bin bn trong thn trnh con
tham chiu ti bin ton cc. Ti mch bn v cc
ngoi l trong mc Bin cc b trong hm di y.
Trong th d sau:
sub say_what {
print Xin cho, $what\n;
}
$what tham chiu ti gi tr ton cc cho $what m
c dng chung vi phn cn li ca chng trnh.

Gi mt hm ngi dng
Bn gi mt trnh con t bn trong bt k biu thc
no bng vic t trc tn trnh con ny mt du v &,
nh trong:
&say_hello; # mt biu thc n gin
$a = 3 + &say_hello; # phn ca biu thc ln hn
for ($x = &start_value; $x < &end_value; $x +=
&increment) {
...
} # gi ba trnh con xc nh cc gi tr
Mt trnh con c th gi mt trnh con khc, v trnh
con khc ny n lt n li c th gi trnh con khc
na, v c nh th, cho ti khi tt c b nh c sn b
cht y bng a ch quay v v cc biu thc c tnh
ton b phn. (Khng c tm hay 32 mc no c th tho
mn c cho ngi m Perl.)


152

Gi tr cho li
Ging nh trong C, mt trnh con bao gi cng l
mt phn ca mt biu thc no (khng c ci tng
ng trong li gi th tc ta Pascal). Gi tr ca vic
gi trnh con c gi l gi tr cho li. Gi tr cho li
ca mt trnh con l gi tr ca biu thc cui cng c
tnh bn trong thn ca trnh con cho mi ln gi.
Chng hn, nh ngha trnh con ny:
sub sum_of_a_and_b {
$a + $b;
}
Biu thc cui cng c tnh trong thn ca trnh
con ny (thc ra, l biu thc duy nht c tnh) l
tng ca $a v $b, cho nn tng ca $a v $b s l gi tr
cho li. Sau y l iu trong hnh ng:
$a = 3; $b = 4;
$c = &sum_of_a_and_b; #c nhn 7
$d = 3*sum_of_a_and_b; # $d nhn 21
Mt trnh con cng c th cho li mt danh sch cc
gi tr khi c tnh trong hon cnh mng. Xt trnh con
ny v li gi:
sub list_of_a_and_b {
($a, $b);
}
$a = 5; $b = 6;
$c = &list_of_a_and_b; # @c nhn (5, 6)
Biu thc cui c tnh thc s ngha l biu thc
cui cng c tnh, thay v l biu thc cui cng c
xc nh trong thn ca trnh con. Chng hn, trnh con
ny cho li $a nu $a > 0, ngoi ra n cho $b:

153

sub gime_a_or_b {
if ($a > 0) {
print chn a ($a)\n;
$a;
} else {
print chn b ($b)\n;
$b;
}
}
Lu rng trnh con ny cng cho hin th mt
thng bo. Biu thc cui cng c tnh l $a hay $b,
m tr thnh gi tr cho li. Nu bn o ngc cc dng
c cha $a v print ngay trc n, th bn s nhn c
mt gi tr cho li l 1 (gi tr c cho li bi hm print
thnh cng) thay v gi tr ca $a.
Tt c chng l cc th d kh tm thng. Tt
hn c l nn truyn cc gi tr khc nhau cho mi ln
gi ti mt trnh con thay v phi da vo cc bin ton
cc. Thc ra, iu cng ng n ch cn ni.

i
Mc du cc trnh con c chc nng c bit l c
ch, ton b mc c ch mi tr thnh sn c cho bn
khi bn c th truyn cc i cho trnh con. Trong Perl
nu li gi trnh con (vi du v @ cng tn trnh con)
c theo sau n mt danh sch nm trong ngoc trn, th
danh sch ny s c t ng gn cho mt bin c bit
c tn @_ trong sut thi gian hot ng ca trnh con.
Trnh con c th truy nhp vo bin ny xc nh s
cc i v gi tr ca cc i . Chng hn:
sub say_hello_to {

154

print Hello, $_[0]!\n; # tham bin u l mc tiu
}
Ti y thy mt tham chiu ti $_[0], chnh l phn
t u tin ca mng @_. Lu c bit: tng t nh
dng v ca chng, gi tr $_[0] (phn t u tin ca
mng @_) chng c bt k lin quan g vi bin $_ (mt
bin v hng ca ring n). Bn ng lm ln chng!
T chng trnh ny, r rng n ni hello vi bt k ci
g chng truyn cho n nh tham bin u tin. iu
c ngha l chng c th gi n ging th ny:
&say_hello_to (world); # scho hello, world!
$x = somebody;
&say_hello_to ($x); # cho hello, somebody!
&say_hello_to (me) + &say_hello_to (you) # v me v
you
Lu rng trong dng cui, gi tr cho li khng
thc s c dng. Nhng trong khi tnh tng Perl phi
tnh tt c cc b phn ca n, cho nn trnh con ny
c gi hai ln.
Sau y l mt th d v vic dng nhiu hn mt
tham bin:
sub say {
print $_[0], $_[1]!\n;
}
&say (hello, world); # hello world, ln na
&say (goodbye, cruel world) # im lng
Cc tham bin vt qu b b qua - nu bn cha
bao gi nhm ng ti $_[3], th Perl cng chng bn
tm. Cc tham s khng cng b b qua - bn n
thun nhn c undef nu bn nhn vt ra cui ca

155

mng @_, nh vi mi mng khc.
Bin @_ l cc b cho trnh con ny; nu c mt
bin ton cc cho @_, n s c ct gi trc khi trnh
con c gi v c khi phc li gi tr trc ca n
khi tr v t chng trnh con. iu ny cng c ngha
l mt trnh con c th truyn cc i cho mt trnh con
khc m khng s mt bin @_ ring ca n - vic gi
trnh con lng nhau nhn c @_ ring ca n theo
cng cch.
Xem xt li trnh cng a v b ca mc trc. Ti
y mt trnh con thc hin vic cng hai gi tr bt k,
c bit, hai gi tr c truyn cho trnh con ny nh
tham bin.
sub add_two {
$_[0] + $_[1];
}
print &add_two (3, 4) ; # in 7
$c = &add_two (5, 6) ; $c c 11
By gi tng qut ho chng trnh ny. Nu chng
ta c ba, bn hay hng trm gi tr cn phi cng li th
sao? Chng ta c th lm vic bng mt chu trnh, ta
nh:
sub add {
$sum = 0 ; # khi u gi tr cho sum
foreach $_ (@_ ) {
$sum += $_ ; # cng tng phn t
}
$sum ; # biu thc cui c tnh: tng ca tt c
cc phn t
}
$a = &add(4,5,6) ; # cng 4+5+6 = 15, v gn cho $a
print &add(1,2,3,4,5) ; # ina ra 15

156

print &add(1..5); # cng in ra 15, v 1..5 c m rng
iu g xy ra nu c mt bin mang tn $sum khi
gi &add_list? Chng ta nh trng vo n. Trong mc
tip chng ta s xem cch thc trnh iu ny.

Bin cc b trong hm
Chng ta ni ti bin @_ v cch thc vic sao
chp cc b c to ra cho tng trnh con c gi ti
tham bin. Bn c th to ra cc bin v hng, mng
hay mng kt hp ca ring mnh lm vic theo cng
cch. Bn lm iu ny vi ton t local(), nhn mt danh
sch cc tn bin v to ra cc bn cc b ca chng
(hay cc th nghim, nu bn thch t ao to ba ln).
Sau y li l hm cng , ln ny dng local():
sub add {
local ($sum) ; # lm cho $sum thnh bin cc b
$sum = 0 ; # khi u gi tr cho sum
foreach $_ (@_ ) {
$sum += $_ ; # cng tng phn t
}
$sum ; # biu thc cui c tnh: tng ca tt c
cc phn t
}
Khi cu lnh thn u tin c thc hin, th bt k
gi tr hin ti no ca bin ton cc $sum cng c
ct gi v mt bin mi mang tn $sum s c to ra
(vi gi tr undef). Khi trnh con ny i ra, th Perl b qua
bin cc b v khi phc gi tr trc (ton cc). iu
ny vn hnh c khi bin $sum hin l bin cc b ca
mt trnh con khc (mt trnh con m gi ti trnh con
ny, hay mt trnh con gi ti mt trnh m gi ti trnh

157

con ny, vn vn). Cc bin c th c nhiu bn cc b
lng nhau, mc du bn c th truy nhp mi lc ch vo
mt bin.
Sau y l cch to ra mt danh sch tt c cc
phn t hn 100 ca mt mng ln:
sub bigger_than_100 {
local ($result) ; # tm thi gi gi tr tr v
foreach $_ (@_ ) { # i qua danh sch i
if ($_ > 100) { # c t cch khng?
push (@result, $_) ; # cng n
}
$result ; # cho li danh sch cui
}
iu g xy ra nu chng ta mun tt c cc phn t
ny ln hn 50 thay v 100? Chng ta phi sa chng
trnh ny, i tt c cc s 100 thnh 50. Nhng iu g
xy ra nu chng ta li cn c hai? c, chng ta c th
thay th 50 hay 100 bng mt bin tham chiu. iu ny
lm chng trnh trng ging th ny:
sub bigger_than {
local ($n, @values) ; # to ra cc bin cc b no
($n, @values) = @_ ; # cht arg thnh gii hn v gi
tr
local (@result) ; # tm thi gi gi tr tr li
foreach $_ (@values) { # i qua danh sch i arg
if ($_ > $n) { # c t cch khng?
push (@result, $_) ; # cng n
}
$result ; # cho li danh sch cui
}
# mt s li gi
@new = &bigger_than (100, @list); # @new nhn tt c
@list > 100
@this = &bigger_than(5,1,5,15,30); # @this nhn

158

(15,30)
L rng ln ny ti dng hai bin cc b ph
t tn cho cc i. iu ny kh thng dng trong
thc hnh - d ni v $n v @values hn ni v $_[0] v
@_[1..$#_] nhiu lm.
Kt qu ca local() l mt danh sch gn c, ngha
l n c th c dng v bn tri ca ton t gn
mng. Danh sch ny c th c t gi tr khi u
cho tng bin mi c to ra. (Nu bn khng t gi
tr cho danh sch ny, th cc bin mi bt u vi mt
gi tr ca undef, ging nh bt k bin mi no khc.)
iu ny c ngha l chng ta c th t hp hai cu lnh
u ca trnh con ny, bng cch thay th:
local ($n, @values) ;
($n, @values) = @_ ; # cht arg thnh gii hn v gi
tr
bng
local ($n, @values) = @_ ;
Thc ra, y l mt th rt c th thng dng Perl
cng ht nh khai bo vy, local() thc s l mt ton t
thc hin c. Nu bn t n vo bn trong chu trnh,
th bn s thu c mt bin mi cho mi ln lp chu
trnh, m gn nh l v dng tr phi bn thch lng ph
b nh v qun mt mnh tnh g trong ln lp trc.
Chin lc lp trnh Perl tt gi rng bn nn nhm tt
c cc ton t local() ca mnh vo phn u nh ngha
trnh con, trc khi bn chui vo phn tht ca trnh ny.


159

Bi tp
1. Vit mt trnh con nhn mt gi tr s t 1 ti 9 v
cho li tn ting Anh (nh mt, hai, hay chn). Nu
gi tr a vo ngoi phm vi ny, th cho li s
ban u thay v cho tn. Th n vi mt s d liu
vo - c l bn s phi vit ra mt loi khin trnh
no .
2. Ly chng trnh trong bi tp trc, vit mt
chng trnh nhn hai s v cng chng li, hin th
kt qu kiu hai cng hai l bn. (Ch qun vit
hoa t u!)
3. M rng trnh con ny cho li m chn qua m
mt v khng. Th chng trnh ny.



160


161


9


Cc cu trc
iu khin khc


Ton t last
Trong mt s bi tp trc y bn c th ngh,
Nu ti c c mt cu lnh break ca C y, th
xong ri. Cho d bn khng ngh nh th, th hy c
ti ni cho bn v s tng ng ca Perl thot sm
khi chu trnh : ton t last.
Ton t last ngt khi chu trnh bao quanh bn
trong nht, gy ra vic thc hin tip tc vi cu lnh i
ngay sau khi . Chng hn:
while (ci g ) {
ci g ;
ci g ;
ci g ;
Trong chng ny:

Ton t last
Ton t next
Ton t redo
Khi c nhn
B thay i biu
thc
&&, || v ?: xem
nh cc cu trc
iu khin

162

if (iu kin no ) {
ci g khc ;
ci g khc ;
last ; # nhy ra khi chu trnh while
}
thm na ;
thm na ;
}
# last nhy ti y
Nu iu kin no l ng, th ci g khc s
c thc hin, v th ri ton t last buc chu trnh
while phi kt thc.
Ton t last ch tnh ti khi chu trnh, khng tnh
khi cn to nn kt cu c php no . iu ny c
ngha l khi to nn nhnh then ca cu lnh if khng
c tnh ti - ch khi to nn for, foreach, while v cc
khi trn mi c tnh. (Khi trn l khi khng
thuc phn khc ca mt kt cu ln hn, nh mt chu
trnh, hay mt trnh con, hay mt cu lnh if/then/else).
Gi s ti mun xem liu thng bo th c ct
gi trong mt tp c l t ti hay khng. Mt thng bo
nh vy c th ging nh l:
From: merlyn@ora.com (Randal L. Schwartz)
To: stevet@ora.com
Date: 01-SEP-93 08:16:24 PM PDT - 0700
Subject: A sample mail message

Heres the body of the mail message. And here is some
more.
Ti phi duyt qua thng bo ny t dng bt u
vi From: v ri liu dng ny c cha tn ng
nhp ca ti hay khng, merlyn.

163

Ti c th lm iu nh th ny:
while (<STDIN>) { # c dng vo
if (/^From:/) { #c bt u vi From: khng? Nu c...
if (/merlyn/) { # n l t ti!
print Email from Randal! Its about
time!\n;
}
last ; # khng cn tm From: na, cho nn ra
} # kt thc if from:
if (/^$/) { # dng trng ?
last ; # nu ng, ng kim tra thm na
}
} # kt thc while
Lu rng mt khi dng c cha From: c tm
thy th chng ta i ra khi chu trnh chnh bi v ti
mun xem ch dng From: u tin. Cng lu rng mt
u th kt thc ti dng trng u tin, cho nn
chng c th ra khi chu trnh chnh na.

Ton t next
Ging nh last, next cng lm thay i lung thc
hin theo trnh t thng thng. Tuy nhin, ton t next
lm cho vic thc hin b qua phn cn li ca khi chu
trnh c bao bn trong nht m khng kt thc khi
ny
*
. N c dng nh th ny:
while (ci g ) {
phn th nht ;
phn th nht ;

*
Nu c mt khi continue cho chu trnh ny, m chng ta th cha
tho lun ti, th ton t next i ti ch bt u ca khi continue
thay v ti cui khi ny. Kh gn.

164

phn th nht ;
if (iu kin no ) {
phn no ;
phn no ;
next ; # nhy ra khi chu trnh while
}
phn khc ;
phn khc ;
# next ti y
}
Nu iu kin no l ng, th phn no c
thc hin, v phn khc b b qua.
Ln na, khi ca mt cu lnh if khng c tnh
ti nh khi chu trnh.

Ton t redo
Cch th ba m bn c th nhy qua trong mt khi
chu trnh l bng redo. Ton t ny nhy ti ch bt u
ca khi hin ti (khng tnh li biu thc iu kin),
kiu nh:
while (ci g ) {
# redo ti y
ci g ;
ci g ;
ci g ;
if (iu kin no ) {
phn no ;
phn no ;
redo ;
}
phn khc ;
phn khc ;
phn khc ;

165

}
Mt ln na, khi if khng c tnh ti. Ch tnh
cc khi chu trnh.
L rng vi redo v last v khi trn, bn c th
to nn chu trnh v hn m i ra t gia, kiu nh:
{
phn bt u ;
phn bt u ;
phn bt u ;
if (iu kin no ) {
last ;
}
phn sau ;
phn sau ;
phn sau ;
redo ;
}
iu ny s ph hp cho mt chu trnh kiu while m
cn ti vic c mt phn no ca chu trnh ny c
thc hin nh vic khi u trc php kim th th
nht. (Trong mc B thay i biu thc, di y, ti
s ch ra cho bn cch vit cu lnh if vi t k t ngt
hn.)

Khi c nhn
iu g xy ra nu bn mun nhy ra khi mt khi
c cha khi bn trong nht, hay ni theo cch khc, ra
khi hai khi lng nhau ngay mt lc? Trong C, bn phi
vin ti ton t goto i ra. Khng cn phi lm nh
vy trong Perl - bn c th dng last, next v redo ti bt
k khi kt no bng vic cho khi mt ci tn c nhn.

166

Nhn l mt kiu tn khc t mt khng gian tn
khc m tun theo cng qui tc nh v hng, mng,
mng kt hp v trnh con. Tuy nhin, nh chng ta
thy, mt nhn khng c k t ngt i u c bit (nh
$ cho v hng, & cho trnh con, vn vn), cho nn mt
nhn c tn print s xung t vi t dnh ring print v s
khng c php. Bi l do ny, Larry gi chn cc
nhn bao gm ton ch hoa v s, m anh y m bo s
khng bao gi b chn nhm thnh mt t dnh ring
trong tng lai. Bn cnh , tt c cc ch hoa cho
php d nhn thy hn trong mt vn bn chng trnh
m phn ln l ch thng.
Mt khi bn chn cn thn nhn, n s ng ngay
trc cu lnh c cha khi, theo sau du hai chm, kiu
nh th ny:
SOMELABEL: while (iu kin) {
cu lnh ;
cu lnh ;
cu lnh ;
if (iu kin khc) {
last SOMELABEL ;
}
}
L rng ti thm SOMELABEL, nh mt
tham bin vo cu lnh last. Tham bin ny bo cho Perl
ra khi khi c tn SOMELABEL, thay v ra khi khi
bn trong nht. Trong trng hp ny, chng ta khng
c ci g khc ngoi khi bn trong nht. Nhng gi s
ti c cc chu trnh lng nhau:
OUTER: for ($i = 1; $i <= 10 ; $i++) {
INNER: for ($j = 1 ; $j >= 10 ; $j++) {
if ($i + $j == 63) {

167

print $i ln $j l 63!\n ;
last OUTER;
}
if ($j >= $i) {
next OUTER ;
}
}
}
Tp hp cc cu lnh ny th tt c cc gi tr k
tip ca hai s nh nht c nhn vi nhau cho ti khi
n tm ra mt cp c tch l 63 (7 v 9). Lu rng mt
khi tm c mt cp th khng cn phi kim tra cc
s khc na, cho nn cu lnh if th nht ra khi c hai
chu trnh for bng vic dng last vi nhn. Cu lnh if th
hai c gng m bo rng s ln hn trong hai s bao
gi cng l s th nht bng vic b qua vic lp tip
ca chu trnh bn ngoi ngay khi iu kin ny khng
cn xy ra na. iu ny c ngha l cc s s c
kim th vi ($i, $j) l (1,1), (2,1), (2,2), (3,1), (3,2),
(3,3), (4,1) vn vn.
Cho d khi bn trong nht c gn nhn, th cc
ton t last, next, v redo khng c tham bin tu chn
(nhn) vn vn hnh tn trng khi bn trong nht. Cng
vy, bn khng th dng nhn nhy vo trong mt
khi - ch nhy ra khi. Cc ton t last, next hay redo
phi bn trong khi.

B thay i biu thc
Xem nh mt cch khc ch ra nu th ny, th
th kia, Perl cho php bn gn nhn cho mt b sa i
if ln mt biu thc vn l mt biu thc ng ring.

168

Kiu nh:
biu thc no if biu thc iu khin ;
Trong trng hp ny, biu thc iu khin c tnh
trc xt gi tr chn l ca n (bng vic dng cng
qui tc nh thng l), v nu ng, th biu thc no
s c tnh tip. iu ny i th tng ng vi:
if (biu thc iu khin no ) {
biu thc no ;
}
ngoi tr rng bn khng cn thm du ngt ph,
cu lnh ny c ngc li, v biu thc phi l mt biu
thc n (khng phi l mt khi cu lnh). Tuy nhin,
nhiu ln cch m t ngc ny bin thnh cch t nhin
nht pht biu vn , trong khi cng tit kim c
vi ln g. Chng hn, sau y l cch bn c th ra khi
chu trnh khi mt iu kin no ny sinh:
LINE: while (<STDIN>) {
last LINE if /^From: / ;
}
Bn xem d vit lm sao. V bn thm ch cn c
th c n theo kiu ting Anh: dng cui nu n bt
u vi From.
Cc dng song song khc bao gm nhng dng sau:
exp2 unless exp1; # ging: unless (exp1) { exp2 ; }
exp2 while exp1; # ging: while (exp1) { exp2 ; }
exp2 until exp1; # ging: util (exp1) { exp2 ; }
L rng tt c cc dng ny tnh exp1 trc ri
da trn , tnh hay khng tnh ci g vi exp2.
Chng hn, sau y l cch tm ra lu tha u tin

169

ca hai s ln hn mt s cho:
chop ($n = <STDIN>) ;
$i = 1; # khi u
$i *= 2 until $i > $n ; # lp cho ti khi tm ra n.
Cc dng ny khng lng nhau - bn khng th ni
c exp3 while exp2 if exp1. iu ny l v dng exp2
if exp1 khng cn l mt biu thc, m l mt cu lnh
hon ton, v bn khng th gn thm mt trong cc b
sa i ny vo sau cu lnh.

&&, || v ?: xem nh cc cu trc iu khin
Nhng cu trc ny trng ta nh cc k t ngt, hay
mt phn ca biu thc. Liu chng c th thc s c
coi l cc cu trc iu khin khng? Th ny, theo cch
ngh Perl, gn nh bt k ci g cng u c th c, cho
nn xem iu ti ni y.
Thng thng, bn bt gp nu ci ny, th ci n.
Trc y chng ta thy hai dng ny:
if (ci ny) { ci n ; } # mt cch
ci n if ci ny ; # cch khc
y l cch th ba (v tin ti i, vn cn na y):
ci ny && ci n ;
Ti sao n li lm vic? N chng phi l ton t
logic v sao? kim tra xem ci g xy ra khi ci ny ly
gi tr ng hay sai:
Nu ci ny l ng, th th gi tr ca ton b biu
thc vn cn cha c bit ti, v n ph thuc vo
gi tr ca ci n. Cho nn ci n phi c tnh.

170

Nu ci ny l sai, th th chng cn g m nhn vo
ci n na, bi v gi tr ca ton b biu thc phi l
sai ri. V chng cn g phi tnh ci n nn chng ta
c th b qua.
V thc ra, y l iu m Perl lm. Perl tnh ci n
ch khi ci ny l ng, lm cho n thnh tng ng
vi hai dng trc.
Ging th, ton t logic hoc ging nh cu lnh
unless (hay b sa i unless). Cho nn bn c th thay
th:
unless (ci ny) { ci n ; }
bng
ci ny || ci n ;
Nu bn quen thuc vi vic dng cc ton t ny
trong lp v kim sot cc ch lnh thc hin iu
kin, th bn s thy rng chng vn hnh tng t trong
Perl.
Cui cng ton t ba ngi kiu C:
exp1 ? exp2 : exp3 ;
tnh exp2 nu exp1 ng, ngc li tnh exp3. Cng
dng nh l chng ni:
if (exp1) { exp2 ; } else { exp3 ; }
nhng mt ln na khng c tt c cc du ngt .
Chng hn, bn c th vit:
($a < 10) ? $b = $a : $a = $b ;
nn dng ci no y? Tu vo tm trng bn thi,
i khi, hay tu theo tng phn biu thc ln n u,
hay liu cn thm ng m ngoc no bi v xung t

171

th t u tin. Nhn vo chng trnh ca ngi khc v
xem chng lm g. C l bn s thy i iu . Larry
gi rng nn t phn quan trng nht ca biu thc
ln trc, cho n ni bt ra.

Bi tp
1. M rng bi ton ca chng trc lp li php
ton cho ti khi t end c a vo cho mt
trong cc gi tr. (Hng dn: dng mt chu trnh v
hn, v ri thc hin last nu gi tr a vo l end.)


172



173


10


Tc hiu tp
v kim th tp




Tc hiu tp l g?
Tc hiu tp l tn trong mt chng trnh Perl
dnh cho vic ni gia tin trnh Perl ca bn v th gii
bn ngoi. Chng ta thy v dng tc hiu tp mt
cch khng tng minh: STDIN l mt tc hiu tp, t
tn cho vic ni gia tin trnh Perl v li vo chun ca
UNIX. Ging nh vy, Perl cung cp STDOUT (cho li
ra chun) v STDERR (cho li ra chun cho li). Nhng
tn ny l trng vi cc tn c dng trong b trnh th
vin vo/ra chun ca UNIX, Perl dng chng cho hu
Trong chng ny:

Tc hiu tp l
g?
M v ng tc
hiu tp
die()
Dng tc hiu
Kim th tp -x
Cc ton t stat()
v lstat()
Dng tc hiu
tp

174

ht vic vo/ra.
Tn tc hiu tp cng ging nh tn dnh cho cc
khi c nhn, nhng chng n t mt khng gian tn
khc (cho nn bn c th c mt v hng $fred, mt
mng @fred, mt mng kt hp %fred, mt chng trnh
con &fred, mt nhn fred, v by gi mt tc hiu tp
fred). Ging nh nhn khi, tc hiu tp c dng
khng cn mt k t c bit ng trc, v do vy c
th b ln ln vi cc t dnh ring hin c hay trong
tng lai. Mt ln na, khuyn co ca Larry l dng
TT C CC CH HOA trong tc hiu tp ca mnh
- khng ch n biu th tt hn, m n cng s m bo
rng chng trnh ca bn s khng hng khi cc t
dnh ring tng lai c a vo.

M v ng mt tc hiu tp
Perl cung cp ba tc hiu tp, STDIN, STDOUT,
STDERR, t ng m cho cc tp hay thit b do tin
trnh cha m ca chng trnh ny thit lp (c th l
lp v). Bn dng ton t open() m cc tc hiu tp
ph, ht nh bn lm trong chng trnh c vit trong
C. C php ca n ging th ny:
open (FILEHANDLE, tn no );
vi FILEHANDLE l tc hiu tp mi, cn tn
no l tn tp UNIX ngoi (nh mt tp hay thit b)
m s c lin kt vi tc hiu tp mi. Vic gi ny
m tc hiu tp c. Vic m mt tp ghi cng
dng cng ton t open, nhng phn tin t ca tn tp
c mt du ln hn (nh trong v):

175

open (OUT, >outfile);
Chng ta s thy trong mc Dng tc hiu tp,
di y cch s dng tc hiu tp ny. Cng vy, nh
trong v, bn c th m mt tp thm vo sau bng
vic dng hai du ln hn lm tin t, nh trong:
open (LOGFILE, >>mylogfile);
Tt c ba dng ny ca open cho li ng nu
vic m thnh cng v sai nu tht bi. (Vic m mt tp
a vo s sai, chng hn, nu tp khng c hay
khng th truy nhp ti c bi khng c php; vic
m tp a ra s sai nu danh mc khng cho ghi hay
khng cho truy nhp ti.)
Khi bn kt thc vi mt tc hiu tp, bn c th
ng n bng ton t close, ta nh:
close(LOGFILE);
Vic m li mt tc hiu tp cng lm ng tp
m trc mt cch t ng, cng nh khi ra khi
chng trnh. V iu ny, phn ln cc chng trnh
Perl khng bn tm vi close(). Nhng n vn c nu
bn mun c cht ch hay chc chn rng tt c d
liu c y ra ht i khi sm hn vic kt thc ca
chng trnh.

Mt cht tiu khin: die()
Coi y nh l mt ch thch cui trang ln, nhng
li nm gia trang.
Mt tc hiu tp m khng c m thnh cng th
c th vn c dng m thm ch khng gy ra cnh

176

bo g nhiu lm trong ton b chng trnh. Nu bn
c t tc hiu tp, bn s nhn c ngay cui tp.
Nu bn ghi ln tc hiu tp, d liu c im m b b i
(ging nh li ha hn vn ng bu c nm trc).
Thng bn mun kim tra li kt qu ca vic m
tp v bo co li li nu kt qu khng phi l iu bn
d kin. Chc chn, bn c th ri rc trong chng trnh
ca mnh vi nhng th kiu nh:
unless (open(DATAPLACE, >/tmp/dataplace)) {
print Rt tic, ti khng th to c
/tmp/dataplace\n;
} else {
# phn cn li chng trnh ca bn
}
Nhng y l c ng vic. V iu thng xy ra
vi Perl l a ra mt li tt. Ton t die() ly mt danh
sch bn trong du ngoc trn tu chn, phun ra danh
sch (ging nh print) trn li ra li chun, v ri kt
thc tin trnh Perl (tin trnh ang chy chng trnh
Perl) vi mt trng thi ra khc khng ca UNIX (ni
chung ch ra mt ci g bt thng xy ra). Cho nn,
vit li on m trn th s thy n ging nh th ny:
unless (open(DATAPLACE, >/tmp/dataplace)) {
die Rt tic, ti khng th to c
/tmp/dataplace\n;
}
# phn cn li chng trnh ca bn
Nhng chng ta thm ch cn c th i thm mt
bc na. Nh rng c th dng ton t (logic hoc) ||
lm ngn thm iu ny, nh trong
unless (open(DATAPLACE, >/tmp/dataplace)) ||
die Rt tic, ti khng th to c

177

/tmp/dataplace\n;
Vy die s c thc hin ch khi kt qu ca open
l sai. Cch thng dng c iu ny l m tp ra
nu khng th cht quch i cho ri! v l cch d
dng nh bt k khi no dng ton t logic v hay
logic hoc.
Thng bo vo lc cht (c xy dng t i ca
die) c tn chng trnh Perl v s dng c gn t
ng vo, cho nn bn c th d dng xc nh c die
no trong chng trnh ca bn chu trch nhim cho
vic ra khng ng lc ny. Nu bn khng thch s
dng hay tp b l ra, th phi chc chn rng vn bn
cht c mt du dng mi cui. Chng hn:
die bn nu nc xt - ln sa;
s in ra tn tp v s dng, trong khi
die bn nu nc xt - ln sa\n;
th khng in ra tn tp v s dng.

Dng tc hiu tp
Mt khi tc hiu tp c m ra c, bn c th
c cc dng t n ht nh bn c th c t li vo
chun vi STDIN. Vy, chng hn, c cc dng t
tp mt hiu:
open (EP, /etc/passwd);
while (<EP>) {
chop;
print Ti thy $_ trong tp mt hiu!\n;
}

178

Lu rng tc hiu tp mi m c dng bn
trong du ngoc nhn ht nh dng STDIN trc y.
Mt tc hiu tp m ra ghi hay hiu nh
phi c cho nh mt i ca ton t print, xut hin
ngay sau t kho print nhng trc danh sch i:
print LOGFILE Khon mc kt thc ca $max\n;
print STDOUT Xin cho, mi ngi!\n; # ging nh in
xin cho mi ngi!\n
Trong trng hp ny, thng bo bt u vi Khon
mc kt thc s ghi ln tc hiu tp LOGFILE, m gi
thit l m trc y trong chng trnh. V xin cho
mi ngi s i ra li ra chun, ht nh khi bn khng
xc nh tc hiu tp. Chng ta ni rng STDOUT l
tc hiu x l tp ngm nh cho cu lnh print.
Vy, tm li, sau y l cch sao chp tt c vn
bn t mt tp c xc nh trong $a vo mt tp c
xc nh trong $b. N minh ho gn nh mi th m
hc trong vi trang va qua:
open (IN,$a) || die khng th m c $a c;
open (OUT, >$b) || die khng th to dc $b;
while (<IN>) { # c mt dng t tp $a vo $_
print OUT $_; # in dng vo tp $b
}
close(IN);
close(OUT);

Kim tra tp -x
By gi bn bit cch m mt tc hiu tp
ghi ra, vit ln bt k tp hin c no vi cng tn.
Gi s bn mun chc chn rng khng c mt tp no

179

vi tn ( gi cho bn khi ngu nhin lm mt tiu
d liu bng tnh hay lch ngy sinh quan trng). Nu
bn nh vit mt bn ghi v th bn nn dng ci g
ta nh -e tn tp kim tra liu tp c tn ti hay
khng. Tng t th, Perl dng -e $filevar kim tra s
tn ti ca tp mang tn bi gi tr v hng $filevar. Nu
tp ny tn ti th kt qu l ng; ngc li n l sai.
Chng hn:
$x = /etc/passwd;
if (-e $x) { # liu /etc/passwd c tn ti khng?
# tt
} else {
print how in the world did you get logged in?\n;
}
Ton hng ca ton t -e thc s l bt k biu thc
v hng no tnh mt xu no , k c mt xu hng.
Sau y l mt th d kim tra cho c mt hiu h thng
v tp nhm:
if (-e /etc/passwd && -e /etc/group) {
print looks like you have a normal system\n;
Cc ton t khc cng c xc nh r. Chng hn,
-r $filevar cho li gi tr ng nu tp c tn trong
$filevar ang tn ti v c c. Tng t, -w $filevar
kim tra xem liu c ghi c c khng. Sau y l
mt th d kim tra tn tp do ngi dng xc nh cho
c tnh c c v ghi c:
print u? ;
$filename = <STDIN>;
chop($filename); # qung ci du dng mi kh chu i
if (-r $filename && -w $filename) {
# tp c, v ti c th c v ghi n
...

180

}
Nhiu vic kim tra tp c sn. Xin xem Bng
10-1 bit danh sch y .
Bng 10.1: Kim tra tp v ngha ca chng

Kim
tra tp
ngha
-r Tp hay danh mc c c
-w Tp hay danh mc ghi c
-x Tp hay danh mc thc hin c
-o Tp hay danh mc do ngi dng s
hu
-R Tp hay danh mc c c bi
ngi dng thc, khng phi ngi
dng hiu qu (khc -r vi chng
trnh setuid)
-W Tp hay danh mc ghi c bi ngi
dng thc, khng phi ngi dng
hiu qu (khc vi -w cho chng
trnh setuid)
-X Tp hay danh mc thc hin c bi
ngi dng thc, khng phi ngi
dng hiu qu (khc vi -x cho
chng trnh setuid)
-O Tp hay danh mc c s hu bi
ngi dng thc, khng phi ngi
dng hiu qu (khc vi -o cho
chng trnh setuid)
-e Tp hay danh mc c
-z Tp c v c kch thc khng

181

Kim
tra tp
ngha
(danh mc th khng bao gi rng)
-s Tp hay danh mc c v c kch
thc khc khng (gi tr c tnh
theo byte)
-f Khon mc l tp r
-d Khon mc l danh mc
-l Khon mc l symlink
-S Khon mc l ch cm
-p Khon mc l ng ng c tn (mt
fifo)
-b Khon mc l tp khi c bit (ging
nh a tho lp c)
-c Khon mc l tp k t c bit (nh
thit b vo/ra)
-u Tp hay danh mc l setuid
-g Tp hay danh mc l setgid
-k Tp hay danh mc c tp bit dnh
-t isatty() trn tc hiu tp l ng
-T Tp l vn bn
-B Tp l nh phn
-M sa tui theo ngy
-A Tui truy nhp theo ngy
-C Tui thay i inode theo ngy
Phn ln trong nhng php kim tra ny cho li
mt iu kin ng-sai n gin. S t th khng, cho
nn hy ni v chng.
Ton t -s khng cho li gi tr ng nu tp l khc
rng, nhng gi tr cho li l mt loi ng c bit.

182

l chiu di theo byte ca tp, vn c coi l ng i
vi mt s khc khng.
Ton t tui -M, -A v -C (ng, chng l ch
hoa c) cho li s ngy k t tp c sa i, truy nhp
hay c thay i inode
*
ln cui. (inode cha tt c cc
thng tin v tp ngoi tr ni dung ca n - xem chi tit
trong li gi h thng stat). Gi tr tui ny l phn s
vi phn gii mt giy - 36 gi c cho li l 1.5
ngy. Nu bn so snh tui ny vi ton b s (chng
hn ba), bn s thu c ch cc tp b thay i ng
nhiu ngy trc y, khng nhiu hay t hn mt giy.
iu ny c ngha l c l bn s mun c vic so snh
theo phm vi (hay ton t int()) hn l so snh chnh xc
c cc tp nm gia ba v bn ngy l.
Tt c nhng ton t ny c th vn hnh trn tc
hiu tp cng nh tn tp. Vi tc hiu tp lm ton
hng l tt c nhng g ton t cn. Vy kim tra
xem liu tp c c m nh SOMEFILE c l thc
hin c hay khng, bn c th dng:
if (-x SOMEFILE) {
# m tp trn SOMEFILE l thc hin c
}
Nu bn tham bin tn tp hay tc hiu tp b
khng (tc l, bn ch c -r hay -s) th ton hng mc
nh l tp c tn trong bin $_ (n vn c y!). Cho
nn, kim th mt danh sch cc tn tp xem tp no

*
Tui c o tng i theo thi gian chng trnh bt u, nh
c ly theo thi gian UNIX trong bin S^T. C th ly c s
m cho nhng tui ny nu gi tr hi tham chiu ti mt s kin
xy ra sau khi chng trnh bt u.

183

c c, th ch cn n gin l:
foreach (@some_list_of_filenames) {
print $_ l c c\n if -r; # cng nh -r $_
}

Cc ton t stat() v lstat()
Trong khi cc php kim tra tp ny l tt cho vic
kim tra nhiu thuc tnh lin quan ti mt tp hay danh
mc c bit, th chng li khng ni c ton b cu
chuyn. Chng hn, khng c vic kim tra tp no cho
li s cc lin kt vi mt tp. thu c thng tin cn
li v tp, n thun gi ti ton t stat(), ton t cho li
mi th m li gi hm h thng UNIX stat() cho (hi
vng nhiu th hn iu bn mun bit).
Ton hng ca stat() l tc hiu tp, hay mt biu
thc tnh cho tn tp. Gi tr cho li hoc l undef, ch ra
rng stat khng sinh c, hay mt mng 13 gi tr, phn
ln d m t bng vic dng danh sch sau y cc
bin v hng:
($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,
$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat(...)
Cc tn y tr ti cc b phn ca cu trc
stat, c m t chi tit trong stat(2) ca bn. C l bn
nn nhn vo xem cc m t chi tit.
Chng hn ly ID (s hiu) ngi dng v ID
nhm ca tp mt hiu, th:
($uid,$gid) = (stat (/etc/passwd)) [4, 5];
V l cch lm.

184

Gi ton t stat() trn tn ca mt lin kt k hiu s
cho li thng tin v lin kt k hiu ny ang tr ti ci
g, khng phi thng tin v bn thn lin kt k hiu (tr
phi lin kt ny xy ra khng tr vo ci g hin thi
truy nhp c). Nu bn cn thng tin (phn ln v
dng) v bn thn lin kt k hiu, dng lstat() thay v
stat() (cho cng thng tin theo cng th t). Ton t
lstat() lm vic ta nh stat() trn nhng iu khng phi
l lin kt k hiu.
Ging nh vic kim tra tp, ton hng ca stat hay
lstat mc nh l $_, ngha l stat s c thc hin trn
tp c tn trong bin v hng $_.

Dng _Filehandle
Mi ln bn ni stat(), -r, -w hay bt k ci g trong
chng trnh, Perl phi tr ra h thng hi b m
stat trn tp (b m cho li t li gi h thng stat).
iu c ngha l nu bn mun bit liu tp c va
c c v ghi c khng, bn v bn cht hi h
thng hai ln cho cng mt thng tin (iu ny khng
th thay i c trong mt mi trng kh khng thn
thin)
iu ny c v nh lng ph, v thc ra, c th trnh
c. Thc hin vic kim tra tp, stat, hay lstat trn
_filehandle (mt du gch thp) xem nh ton hng s
bo cho Perl dng bt k ci g ngu nhin c trong b
nh t ln kim tra tp trc . i khi iu ny l
nguy him: mt chng trnh con c th gi stat mt
cch khng ch nh, nm tiu b m ca bn i.
Nhng nu bn cn thn, bn c th tit kim mt vi li

185

gi h thng khng cn thit. Sau y l th d na v
vic kim tra tnh ghi c v c c $filevar, dng
mo mi:
if (-r $filevar && -w _) {
print $filevar l va c c v ghi c\n;
}
Lu rng ti dng $filevar cho php kim tra
ln th nht - iu ny ly d liu t h iu hnh. Ln
kim tra th hai dng _filehandle o thut; vi php
kim tra ny, bn thn d liu b b li t php kim tra
$filevar v tnh c c nay li c dng, ng l iu
mong mun.
Ch rng vic kim th _filehandle khng ht nh
vic cho php ton hng ca vic kim tra tp, stat, hay
lstat c mc nh kim tra $_; iu ny s l vic kim
tra mi mi ln trn tp hin ti mang tn theo ni dung
ca $_. y li l mt trng hp khc khi cc tn tng
t uc chn cho cc chc nng kh khc nhau. Hin ti,
bn c l quen vi n.

Bi tp
Xem ph lc A v li gii.
1. Vit mt chng trnh c vo mt tn tp t
STDIN, ri m tp v hin th ni dung ca n c
ng trc bi tn tp v mt du hai chm. Chng
hn, nu fred c c vo, v tp fred bao gm ba
dng aaa, bbb v ccc, bn s thy fred: aaa, fred: bbb
v fred: ccc.

186

2. Vit mt chng trnh nhc a vo mt tn tp vo,
mt tn tp ra, mt mu tm kim, v mt xu thay
th, ri thay th tt c mi ln xut hin ca mu tm
kim bng xu thay th trong khi sao tp vo sang
tp ra. Th n trn cc tp. Bn c th ghi mt tp
hin c (ng th n vi nhng tp quan trng!)
khng? Bn c th dng cc k t biu thc chnh qui
trong xu tm kim khng? Bn c th dng \1 trong
xu thay th khng?
3. Vit mt chng trnh c vo mt danh sch cc
tn tp v ri cho hin th t cc tp no l c
c, ghi c, v/hoc thc hin c, v tp no
khng tn ti. (Bn c th thc hin tng php kim
th cho tng tn tp khi bn c chng; hay trn ton
b tp cc tn khi bn c tt c chng. ng
qun loi b du dng mi ti cui mi tn tp m
bn c vo.
4. Vit mt chng trnh c vo mt danh sch cc
tn tp, v tm tp c nht trong chng. In ra tn ca
tp , tui ca n theo s ngy.


187


11


Dng thc


Dng thc l g?
Trong s nhiu vic lm c, Perl thng c
dng lm ngn ng trch rt v bo co thc hnh.
y l lc bit v vic ngn ng bo co .
Perl cung cp mt khi nim v khun mu vit bo
co n gin, c gi l dng thc. Dng thc xc nh
ra phn khng i (tiu ct, nhn, vn bn c nh
hay bt k ci g) v phn bin i (d liu hin ti m
bn bo co). Hnh dng ca dng thc, rt gn vi hnh
dng ca ci ra, tng t nh ci ra c dng thc
trong COBL hay mnh print using ca mt s ngn
ng BASIC.
Vic dng dng thc bao gm ba iu sau:
1. nh ngha dng thc
Trong chng ny:

Dng thc l g?
Gi mt dng
thc
Ni thm v
Fieldholder
Dng thc u
trang
i mc nh cho
dng thc

188

2. Np d liu cn in vo phn bin i ca dng
thc (trng)
3. Gi ti dng thc
Thng, bc th nht c thc hin ngay (trong
vn bn chng trnh sao cho n c xc nh vo lc
dch), v hai bc sau c thc hin lp i lp li.

nh ngha mt dng thc
Dng thc c nh ngha bng vic dng nh
ngha dng thc. nh ngha dng thc ny c th xut
hin bt k u trong vn bn chng trnh ca bn,
ging nh chng trnh con. nh ngha dng thc trng
ta nh th ny:
format tndngthc =
dngtrng
gi_tr_mt, gi _tr_hai, gi _tr_ba
dngtrng
gi_tr_mt, gi _tr_hai, gi _tr_ba
dngtrng
gi_tr_mt, gi _tr_hai, gi _tr_ba
.
Dng th nht c cha t dnh ring format, tip
l tn dng thc v ri n du bng (=). Tn dng thc
c chn t mt khng gian tn khc, v tun theo
cng qui tc nh mi th khc. V tn dng thc khng
bao gi c dng bn trong thn chng trnh (ngoi
tr bn trong gi tr xu), nn bn c th an ton dng
cc tn trng vi vi cc t dng ring. Nh bn s thy
trong mc sau, Gi dng thc, phn ln cc tn dng

189

thc ca bn c l s l mt nh tn tc hiu tp (m
th, lm cho chng khng phi l mt nh cc t dnh
ring)
Tip theo sau dng th nht l bn thn khun mu,
m rng t khng n nhiu dng vn bn. Phn cui
ca khun mu c ch ra bng mt du chm. Khun
mu l nhy cm vi khong trng - y l mt trong vi
ch m mt s khong trng (du cch, xung dng, hay
tab) gy ra vn trong vn bn chng trnh Perl.
nh ngha khun mu c cha mt chui cc dng
trng. Mi dng trng c th cha vn bn c nh -
vn bn s c in ra theo tng k t khi dng thc ny
c gi ti. Sau y l mt th d v dng trng c
vn bn c nh:
Hello, my name is Fred Flintstone.
Tn trng c th cha c ni gi trng cho vn
bn bin i. Nu mt dng c cha ni gi trng,
dng tip sau ca khun mu (c gi l dng gi tr)
s m t cho mt lot cc gi tr v hng - mi gi tr
ng vi mt ni gi trng - m cung cp ra gi tr s
c gn vo trong trng. Sau y l mt th d v
dng trng vi mt ni gi trng, v dng gi tr i
theo:
Hello, my name is @<<<<<<<<<<<.
$name
Ni gi trng l @<<<<<<<<<<<, s xc nh ra
trng vn bn c dn tri bi 11 k t. Cc chi tit
y hn v ni gi trng s c nu trong mc c
tn Ni thm v ni gi trng di y.

190

Nu dng trng c nhiu ni gi trng, n cn
nhiu gi tr, cho nn cc gi tr c tch nhau bi du
phy:
Hello, my name is @<<<<<<<<<<< and Im @<< years
old..
$name, $age
Gn tt c nhng iu ny li chng ta c th to ra
mt dng thc n gin cho mt nhn a ch:
format ADDRESSLABEL =
========================
| @<<<<<<<<<<<<<<<<<<<< |
$name
| @<<<<<<<<<<<<<<<<<<<< |
$address
| @<<<<<<<<<<<, @< @<<<< |
$city, $state, $zip
========================
.
Lu rng cc dng c du bng trn nh v di
y ca dng thc khng c trng, v do vy khng c
dng gi tr theo sau. (Nu bn t mt dng gi tr i
theo sau dng trng nh vy, n s c din gii nh
mt dng trng khc, c th khng lm iu bn
mun.)
Khong trng bn trong dng gi tr b b qua. Mt
s ngi chn vic dng khong trng ph trong dng
gi tr ni dng bin vi ni gi trng trn dng
trc (nh t $zip di trng th ba ca dng
trc trong th d ny), nhng th ch m trng
thi. Perl khng quan tm ti iu , v n khng nh
hng ti ci ra ca bn.

191

Cc gi tr c tnh ton cho cc gi tr v hng
ca chng, cho nn tt c cc biu thc c din gii
theo ng cnh v hng
*
. Vn bn theo sau du xung
dng th nht trong mt gi tr b b qua (ngoi tr trong
trng hp c bit nhiu ni gi trng, s c m t
v sau).
nh ngha dng thc cng ging nh nh ngha
chng trnh con. N khng cha chng trnh thc hin
ngay lp tc, v do c th c t bt k u trong
tp vi phn cn li ca chng trnh - ti c khuynh
hng t nhng dng thc ca mnh vo cui tp, trc
cc nh ngha chng trnh con.

Gi mt dng thc
Bn gi ti mt dng thc bng ton t write. Ton
t ny ly tn ca tc hiu tp, v sinh ra vn bn cho
tc hiu tp bng vic dng dng thc hin thi cho
tc hiu tp . Theo ngm nh, dng thc hin thi
cho mt tc hiu tp l dng thc vi cng tn (cho nn
vi tc hiu tp STDOUT, dng thc STDOUT s
c dng), nhng chng ta s thy ngay rng bn c th
thay i n.
Ly mt th d khc bng vic xt dng thc nhn
a ch, v to ra mt tp cha cc nhn a ch. Sau y
l mt on chng trnh:
format ADDRESSLABEL =

*
Trong Perl 5.0, ti c bit rng ton b dng by gi c tnh
theo ng cnh mng, cho nn pht biu ny l khng ng. ng
phi ni khc i nu bn c iu g nh @a l mt gi tr.

192

========================
| @<<<<<<<<<<<<<<<<<<<< |
$name
| @<<<<<<<<<<<<<<<<<<<< |
$address
| @<<<<<<<<<<<, @< @<<<< |
$city, $state, $zip
========================
.
open (ADDRESSLABEL, >labels-to-print) || die cant
create;
open (ADDRESSLABEL, addresses) || die can not
open addresses;
while ( <ADDRESSES> ) {
chop; # remove newline
($name, $address, $city, $state, $zip) = split (/:/) ;
# load up the global variables
write ADDRESSLABEL; # send the output
}
Ti y chng ta thy nh ngha dng thc trc,
nhng by gi chng ta cng cn c thm c chng
trnh thc hin na. Trc ht, chng ta m mt tc
hiu tp ln mt tp ra c gi l labels-to-print. Lu
rng tn tc hiu tp (ADDRESSLABEL) l cng tn
ca dng thc. iu ny l quan trng. Tip , m tc
hiu tp trn danh sch a ch. Dng thc ca danh sch
a ch c gi s l mt ci g ta nh:
Stonehenge:4470 SW Hall Suite 107:
Beaverton:OR:97005
Fred Flintstone:3737 Hard Rock Lane:Bedrock:OZ:999bc
Ni cch khc, nm trng tch bit, m chng
trnh s phn tch nh m t di y.
Chu trnh while trong chng trnh ny c tng

193

dng ca tp a ch mi lc, b i du xung dng, ri
ch dng ny (khng c du xung dng) vo nm bin.
Lu rng cc tn bin cng l tn m dng khi nh
ngha dng thc. iu ny na cng l quan trng.
Mt khi c tt c cc bin c np vo ( cho cc
gi tr c dng thc s dng l ng n), ton t write
gi ti dng thc ny. Lu rng tham bin cho write l
tc hiu tp cn ghi ra v theo mc nh dng thc cho
cng tn cng c dng.
Mi trng trong dng thc c thay th bi
mt gi tr tng ng t dng tip ca dng thc. Sau
khi hai bn ghi mu c nu trn c x l, tp
labels-to-print c cha:
=====================
| Stonehege |
| 4470 SW Hall Suite 107 |
| Beaverton , OR 97005|
=====================
=====================
| Fred Flintstone |
| 3737 Hard Rock Lane |
| Bedrock , OZ 999bc |
=====================

Ni thm v ni gi tp
Cho n gi, qua th d, bn bit rng ni gi
trng @<<<< c ngha l mt trng c dn tri vi
nm k t v rng @<<<<<<<<<<< ngha l mt trng
c dn tri vi 11 k t. Sau y l ton b phm vi,
nh ha trc y.


194

Trng vn bn
Phn ln nhng ni gi trng bt u bng @.
Cc k t i sau @ ch ra kiu ca trng, trong khi s
cc k t (k c @) ch ra chiu rng ca trng.
Nu cc k t i sau @ l du m ngoc gc tri
(<<<<), bn nhn c mt trng c dn tri - tc
l, gi tr s c gn thm bn phi bng du cch nu
gi tr ny ngn hn chiu rng trng. (Nu mt gi tr
qu di, n s b cht ct t ng - dng ca dng thc
bao gi cng c bo tn.)
Nu cc k t i sau @ l du ng ngoc gc phi
(>>>>), bn nhn c mt trng c dn phi - tc
l nu gi tr qu ngn, n s c b sung du cch vo
bn tri.
Cui cng, nu cc k t i sau @ l du s ng (| |
| |), bn nhn c mt trng nh tm: nu gi tr qu
ngn, n c b sung thm du cch vo c hai bn,
cho tng bn lm cho gi tr thnh nh tm nht bn
trong trng.

Trng s
Mt loi ni gi trng khc l trng s chnh
xc tnh, c ch cho nhng bo co ti chnh ln. Trng
ny cng bt u vi @, v c theo sau bi mt hay
nhiu du # vi mt du chm tu chn (ch ra du chm
thp phn). Mt ln na, @ li c m nh mt trong
cc k t ca trng. Chng hn:
format MONEY
Assets: @#####.## Liabilities: @#####.## Net:

195

@#####.##
$assets, $liabilities, $assets-$liabilities
.
Ba trng s cho php su v tr bn tri du chm
thp phn v hai v tr bn phi (c ch cho la M v
phn xu). Lu ti vic dng mt biu thc theo dng
thc - hon ton hp l v thng hay c dng.
Perl khng a ra iu g cho ngi thnh tho khc
hn iu ny: bn khng th no ly k hiu tin tri ni
hay du ngoc nhn quanh gi tr m hay bt k ci g
khc. lm iu , bn phi vit chng trnh con ca
ring mnh, kiu nh:
format MONEYCOOL =
Assets: @#####.## Liabilities: @#####.## Net:
@#####.##
&cool ($assets, 10), &cool ($liabilities, 9) , &cool
($assets-$liabilities, 10)
.
sub cool {
local ($n, $width) = @_ ;
$width -= 2 ; # back off for negative stuff
$n = sprintf (%.2f, $n) ; # sprintf is in later chapter
if ($n < 0) {
sprintf ([%$width.2f], - $n) ;
# negative numbers get spaces
instead
}
}
## body of program:
$assets = 32125.12; $liab = 45212.15; write
MONEYCOOL;


196

Trng nhiu dng
Nh ni trc y, Perl thng thng dng ti
du xung dng u tin ca mt gi tr khi t kt qu
vo u ra. Mt loi ni cha trng, ni cha trng
nhiu dng, cho php bn a vo mt gi tr m c th
c nhiu dng thng tin. Ni cha trng ny c k
hiu bi @* trn mt dng bi chnh n - bao gi cng
vy, dng i theo sau xc nh ra gi tr m s c th
vo trong trng ny, m trong trng hp ny c th l
mt biu thc cho kt qu c cha trn nhiu dng.
Gi tr c th vo s trng ht nh vn bn gc:
bn dng ca gi tr tr thnh bn dng ca ci ra.
Chng hn:
format STDOUT =
Text Before.
@*
$long_string
Text After.
.
$long_string = Fred\nBaney\nBetty\nWilma\n;
write ;
sinh ra ci ra:
Text Before.
Fred
Baney
Betty
Wilma
Text After.

Trng c lp y
Mt loi ni cha trng khc l trng c lp

197

y. Ni cha trng ny cho php bn to ra mt on
c lp y, b vn bn thnh cc dng c kch c qui
c ti bin gii t, bao bc dng nu cn. C vi phn
cng lm vic y, nhng chng ta hy xt chng mt
cch tch bit.
Trc ht, mt trng c lp y c k hiu
bng vic thay th du hiu @ trong ni cha trng vn
bn bi du m (vy bn nhn c ^<<<<, chng hn).
Gi tr tng ng cho trng c lp y (trn dng
tip ca dng thc) phi l mt bin v hng c cha
vn bn, thay v mt biu thc cho li mt gi tr v
hng. L do cho iu ny l ch Perl s thay i bin
ny trong khi rt y trng c lp, v cng hi kh
m thay i mt biu thc.
Khi Perl rt y trng c lp, n ly gi tr ca
bin v vt ly nhiu t (bng vic dng mt nh ngha
hp l v t)
*
kht vo trong trng. Nhng t ny
thc t vt ra ngoi bin - gi tr ca bin ny sau khi
rt y trng ny l bt k ci g b b li sau khi loi
b t. Bn s thy ti sao ngay sau y.
Cho n y, iu ny dng nh khng khc nhiu
lm vi cch thc trng vn bn lm vic - chng ta ch
in ra va trng (ngoi tr rng chng ta vn tn
trng bin gii t thay v ct b n theo chiu rng t).
Ci p ca trng c rt ny xut hin khi bn c
nhiu tham chiu ti cng bin theo cng dng thc.
Nhn vo iu ny:
format PEOPLE =
Name: @<<<<<<<<<<< Comment: ^<<<<<<<<<<<<<<<<<<

*
K t tch t c nh ngha bi $:bin

198

$name, $comment
Comment: ^<<<<<<<<<<<<<<<<<<
$comment
Comment: ^<<<<<<<<<<<<<<<<<<
$comment
Comment: ^<<<<<<<<<<<<<<<<<<
$comment
.
Lu rng bin $comment xut hin bn ln. Dng
th nht (dng vi trng tn) in ra tn ngi v vi t
u ca gi tr trong $comment. Nhng trong tin trnh
tnh dng ny, $comment b thay i cho cc t bin
mt. Dng th hai li tham chiu n cng bin ny
($comment), v do vy s ly i vi t mi na t cng
bin ny. iu ny cng ng cho dng th ba v th t.
Mt cch c hiu qu, iu ti to ra l mt hnh ch
nht trong ci ra m s c rt y vi cc t trong
$comment tri qua bn dng.
iu g xy nu ton b vn bn chim t hn bn
dng? c, bn s c mt hay hai dng trng. iu
ny c l l c nu bn nh in ra cc nhn v cn
ng cng s dng cho mi mc snh ng vi nhn .
Nhng nu bn nh in ra mt bo co, nhiu dng trng
s lm tn giy my in ca bn.
gii quyt vn ny, chng ta c th dng mt
ch bo ct b. Bt k dng no c cha du ng (~) b
ct b (khng in ra) nu dng ch c du cch. Bn thn
du ng bao gi cng in ra nh du trng, v c th c
t bt k u m du cch c th c t trong dng.
Vit li th d va ri:
format PEOPLE =
Name: @<<<<<<<<<<< Comment: ^<<<<<<<<<<<<<<<<<<

199

$name, $comment
~ Comment: ^<<<<<<<<<<<<<<<<<<
$comment
~ Comment: ^<<<<<<<<<<<<<<<<<<
$comment
~ Comment: ^<<<<<<<<<<<<<<<<<<
$comment
.
By gi, nu li bnh lun ch chim hai dng, cc
dng th ba v th t t ng b ct b.
iu g xy ra nu li bnh lun di hn bn dng?
c, chng ta c th to 20 bn sao cho hai dng cui
ca dng thc , hi vng rng 20 dng s cho n.
Nhng iu i ngc vi tng rng Perl gip bn
li bing, cho nn c mt cch li bing thc hin
iu . Bt k dng no c cha hai du ng lin tip s
c lp li mt cch t ng cho ti khi kt qu l mt
dng trng hon ton. (Dng trng b ct b.) iu ny
lm thay i dng thc ca chng trng ging th ny:
format PEOPLE =
Name: @<<<<<<<<<<< Comment: ^<<<<<<<<<<<<<<<<<<
$name, $comment
~~ Comment: ^<<<<<<<<<<<<<<<<<<
$comment
.
Cch ny, nu li bnh lun chim mt, hai hay 20
dng, chng vn gii quyt n tho.
Lu rng tiu chun chm dt dng lp li i
hi dng phi trng ti im no . iu ngha l
bn c l khng mun bt k vn bn hng no (khc hn
du trng hay du ng) trn dng ny, hay nu khng n
s chng bao gi tr thnh trng. (C y, Perl s lp

200

mi trong trng hp ny. iu ny nghe n c
gii quyt trong Perl 5.0)

Dng thc u trang
Nhiu bo co kt thc trn mt thit b in ra my in
no . Giy my in thng thng c ct ra thnh
chm cc trang, bi v phn ln chng thi l cun
giy t lu ri. Cho nn vn bn c np vo my in v
c bn phi tnh ti bin gii trang a vo cc dng
trng hay k t ko trang nhy qua ch d. By gi
bn c th ly mt ci ra ca chng trnh Perl v np n
vo mt trnh tin ch no (c th thm ch l c
vit trong Perl) m lm vic phn trang ny, nhng vn
cn cch d hn.
Perl cho php bn xc nh dng thc u trang
ci by x l trang. Perl m tng dng c sinh ra v
gi ti dng thc cho mt tc hiu tp c bit. Khi
dng thc ci ra tip khng cn kht vo phn cn li ca
trang, Perl phun ra mt du ko trang tip sau t ng
gi ti dng thc u trang, v cui cng l in ra vn bn
theo dng thc gi. Theo cch , kt qu ca mt ln
gi write s khng bao gi ct ngang qua bin gii trang
(tt nhin tr phi n qu ln m khng th kht trn
chnh bn thn trang).
Dng thc u trang c xc nh ging nh cc
dng thc khc. Tn mc nh cho dng thc u trang
i vi mt tc hiu tp c bit l ging nh tn ca
tc hiu tp c theo sau bi _TOP (xin vit ch hoa).
Perl nh ngha bin $% l s dng ca dng thc

201

u trang m c gi cho mt tc hiu tp c bit,
cho nn bn c th dng bin ny trong dng thc u
trang ca mnh nh s trang cho ng. Chng hn,
vic thm nh ngha dng thc sau cho on chng
trnh trc ngn cn cc nhn khng b x l qua bin
gii trang, v cng nh s trang lin tc:
format ADDRESSLABEL_TOP =
My Address -- Page @<
$%
.
Chiu di trang mc nh l 60 dng. Bn c th
thay i iu ny bng vic t mt bin c bit, c
m t tm tt.
Perl khng liu bn c dng print in ln cng
tc hiu tp hay khng cho nn n c th nm i s
dng trn trang. Bn c th hoc l vit li chng trnh
ca mnh dng cc dng thc gi i mi th, hay
trnh n bin s dng trn trang hin ti sau khi bn
thc hin lnh print. Cht na chng ta s thy cch thay
i gi tr ny.

Thay i mc nh cho dng thc
Ti thng ni ti mc nh cho iu ny iu n.
c, Perl cung cp mt cch vt qua cc mc nh
cho mi bc. Ta ni v iu ny.

Dng select() thay i tc hiu tp
Quay tr li khi ni v print, trong chng 6, C s

202

v vo/ra, ti ni rng print v print STDOUT l ng
nht, bi v STDOUT l mc nh cho print. Khng hn
hon ton th. Mc nh thc cho print (v write cng mt
vi php ton khc m s gp ngay sau y) l mt khi
nim k cc c gi l tc hiu tp hin ang c
la.
Tc hiu tp hin ang c la vit tt l
STDOUT - lm cho n d in mi th trn u ra
chun. Tuy nhin, bn c th thay th tc hiu tp hin
ang c la bng ton t select(). Ton t ny nhn
mt tc hiu tp (hay bin v hng c cha tn ca
tc hiu tp) nh mt i. Mt khi tc hiu tp hin
c la m thay i, n nh hng ti tt c cc php
ton tng lai ph thuc vo tc hiu tp hin c
la. Chng hn:
print hello world\n; # ging nh print STDOUT hello
world\n;
select(LOGFILE) ; # chn mt tc hiu tp mi
print howdy, world\n; ging nh print LOGFILE howdy
world\n;
print more for the log\n; # thm v LOGFILE
select (STDOUT); # chn li STDOUT
print back to stdout\n; # li tr v vi u ra chun
Lu rng php ton select l kh tnh - mt khi bn
la mt tc hiu mi, n vn cn c hiu qu cho ti
select tip.
Cho nn, mt nh ngha tt hn cho STDOUT vn
tn trng print v write l ch STDOUT l tc hiu
hin c la mc nh, hay tc hiu mc nh mc
nh
Cc chng trnh con c th thy nhu cu thay i

203

tc hiu tp hin c la. Tuy nhin, s bt ng nu
bn gi mt chng trnh con ri pht hin ra l tt c
cc dng vn bn bn son cng phu li dn thnh
mt b cc bit no bi v chng trnh con thay
i tc hiu tp hin c la m khng khi phc li
n. Cho nn mt chng trnh con hnh x tt cn phi
lm g? Nu chng trnh con ny bit rng tc hiu
hin thi l STDOUT, chng trnh con c th khi
phc tc hiu la vi chng trnh tng t nh
trn. Tuy nhin, iu g xy ra nu ni gi chng trnh
con ny thay i tc hiu tp la?
Vy vn tr thnh gi tr cho li t select l mt
xu c cha tn ca tc hiu la trc . Bn c
th nm ly gi tr ny khi phc tc hiu tp la
trc , bng vic dng on chng trnh nh th ny:
$oldhandle = select(LOGFILE) ;
print this goes to LOGFILE\n;
select($oldhandle); # khi phc tc hiu trc
y, lm th d, d dng hn nhiu l ch cn t
LOGFILE mt cch tng minh nh mt tc hiu tp
cho print, nhng c mt s thao tc i hi tc hiu tp
hin c la phi thay i, nh s thy ngay sau y.

Thay i tn dng thc
Tn dng thc ngm nh cho mt tc hiu tp l
ging nh tc hiu tp. Tuy nhin, bn c th cthay i
iu ny cho tc hiu tp hin c la bng vic thit
t tn dng thc mi trong mt bin c bit c gi
l $~. Bn c th cng xem xt li gi tr ca bin ny
xem dng thc hin thi l g i vi tc hiu tp hin

204

c la.
Chng hn, dng dng thc ADDRESSLABEL
trn STDOUT, cng d nh:
$_ = ADDRESSLABEL ;
Nhng iu g xy ra nu bn mun t dng thc
cho tc hiu tp REPORT l SUMMARY? Ch cn vi
bc lm iu y:
$oldhandle = select (REPORT) ;
$~ = SUMMARY ;
select ($oldhandle) ;
Ln tip chng ta ni:
write REPORT ;
thu c vn bn trn tc hiu tp REPORT,
nhng dng dng thc SUMMARY.
Lu rng chng ta ct gi tc hiu trc
vo bin v hng v ri khi phc li n sau ny. y
l mt thc hnh lp trnh tt. Thc ra, khi vit chng
trnh ti c l gii quyt s tng t in hnh trn
mt dng trc , v khng gi thit rng STDOUT l
tc hiu ngm nh.
Bng vic t dng thc hin thi cho mt tc hiu
tp c bit, bn c th xen ln nhiu dng thc khc
nhau trong mt bo co.

i tn dng thc u trang
Cng nh chng ta c th thay i tn ca dng thc
cho mt tc hiu tp c bit bng vic t bin $~,

205

chng ta cng c th thay i dng thc u trang bng
vic t bin $^. Bin ny gi tn ca dng thc u
trang cho tc hiu tp hin ang c la v l c/ghi,
c ngha l bn c th kim tra li gi tr ca n xem
tn dng thc hin thi v bn c th thay i n qua
vic gn cho n.

i chiu di trang
Nu dng thc u trang c xc nh, chiu di
trang tr thnh quan trng. Theo mc nh, chiu di
trang l 60 dng - tc l, khi lnh write khp vi cui
dng 60, dng thc u trang s c t ng gi ti
trc khi in vn bn.
i khi 60 dng li khng khp. Bn c th thay i
iu ny bng vic t bin $=. Bin ny gi chiu di
trang hin thi cho tc hiu tp ang c la. Mt ln
na, thay i n sang mt tc hiu tp khc hn
STDOUT (tc hiu tp hin ang c la ngm nh),
bn s cn dng ton t select(). Sau y l cch thay i
tc hiu tp LOGFILE c trang 30 dng:
$old = select(LOGFILE) ; # la LOGFILE v ct
gi tc hiu c
$= = 30 ;
select($old) ;
Vic thay i chiu di trang s khng c hiu lc
cho ti ln tip gi ti dng thc u trang. Nu bn t
n trc khi bt k vn bn no c a ra qua tc
hiu tp ny qua mt dng thc, n s lm vic tt v

206

dng thc u trang c gi ngay lp tc ti vn bn
u tin c dng thc.

Thay i v tr trn trang
Nu bn dng print in mt vn bn ca mnh ln
mt tc hiu tp, n s trn ln s m dng v tr trang
v Perl khng m s dng qua bt k ci g khc ngoi
write. Nu bn mun cho Perl bit rng bn ang a
ra mt vi dng ph, bn c th iu chnh s dng c
m bi vic thay i bin $-. Bin ny cha s dng
cn li trn trang trn tc hiu tp hin c la. Mi
write s lm gim gi tr ca s dng cn li theo s dng
thc t a ra; khi s m ny t ti khng, dng thc
u trang s c gi ti v gi tr ca $- c sao t
bin $= (chiu di trang).
Chng hn, bo Perl rng bn gi mt dng
ph ra STDOUT, lm iu nh th ny:
write ; # gi dng thc STDOUT trn STDOUT
... ;
print Mt dng ph ... y ri!\n ; # dng ny i ra
STDOUT
$- -- ; # gim $- ch ra dng khng ghi gi ti
STDOUT
... ;
write ; # iu ny vn lm vic, tnh c dng ph
Ti u chng trnh, $- c t l khng cho mi
tc hiu tp. iu ny m bo rng dng thc u
trang s l ci u tin c gi ti cho tng tc hiu
tp tu theo write u tin.


207


Bi tp
1. Vit mt chng trnh m tp /etc/passwd v in ra
tn ngi dng, (s hiu) ID ngi dng, v tn thc
theo ct c dng thc. Dng format v write.
2. Thm dng thc u trang vo chng trnh trc.
(Nu tp mt hiu cn t, bn c th cn t chiu di
trang thnh s no nh 10 dng chng hn cho
bn c th thu c nhiu th nghim ca u trang.)
3. Thm s trang tng tun t vo u trang, cho bn
thu c trang 1, trang 2 vn vn trn ci ra.



208



209


12


Truy nhp
danh mc



Chuyn vng quanh cy danh mc
Cho ti nay, c l bn quen thuc vi khi nim
v danh mc hin thi v dng ch lnh cd ca v. Trong
lp trnh UNIX, bn vn gi li gi h thng chdir()
thay i danh mc hin thi ca tin trnh, v y l tn
m Perl cng dng.
Ton t chdir() trong Perl nhn mt i - mt biu
thc tnh ra mt tn danh mc s t lm danh mc
hin thi. Nh vi hu ht cc ton t khc, chdir() cho
li ng khi bn i c sang danh mc yu cu v
cho li sai nu bn khng th lm c iu ny. Sau
Trong chng ny:

i quanh cy
danh mc
Globbing
Tc hiu danh
mc
M v ng
tc hiu danh
mc
. c tc hiu
danh mc

210

y l mt th d:
chdir(/etc) || die khng th chuyn sang /etc (k tht!) ;
Cc du ngoc trn l tu chn, cho nn bn cng c
th vit cch khc bng chng trnh nh:
print Bn mun i u? ;
chop ($where) {
if (chdir $where) {
# ti
} else {
# khng ti
}
Bn khng th tm ra c bn u m khng a
ra ch lnh pwd. Chng ta s hc v vic a ra cc ch
lnh trong Chng 14, Qun l tin trnh.
Mi tin trnh UNIX c danh mc ring ca n.
Khi mt tin trnh mi c a ra, n k tha danh mc
hin thi ca cha m, nhng l chm ht mi ghp
ni. Nu chng trnh Perl ca bn i danh mc ca n,
iu y s nh hng ti lp v (hay bt k ci g)
khi ng tin trnh Perl. Ging vy, cc tin trnh m
Perl to ra khng th no nh hng ti danh mc hin
thi ca chng trnh Perl. Cc danh mc hin thi cho
nhng tin trnh mi ny c k tha t danh mc hin
thi ca chng trnh Perl.

Globbing
Lp v thng nhn i dng lnh c du sao ring
bit (*) v chuyn n thnh mt danh sch tt c cc tn
tp trong danh mc hin thi. Vy, khi bn ni rm *, bn

211

s loi b i tt c cc tp khi danh mc hin thi. (Ch
th iu ny nu bn khng mun chc tc ngi qun
tr h thng ca mnh khi bn yu cu cc tp phi
c ct gi.) Tng t, [a-m]*.c xem nh i dng lnh
s bin thnh mt danh sch tt c cc tn tp trong danh
mc hin thi m c ch bt u thuc vo na trc
ca bng ch ci, v kt thc vi .c, v /etc/host* l danh
sch tt c cc tn tp bt u vi host trong danh mc
/etc. (nu iu ny l mi i vi bn, c l bn mun
c thm nhiu na v kch on lp v u khc
trc khi x l tip.)
Vic m rng i dng lnh nh * hay /etc/host*
thnh mt danh sch cc tn tp snh ng c gi l
globbing. Perl h tr cho globbing qua mt c ch rt
n gin - ch t mu globbing vo gia hai ngoc
nhn, nh:
@a = < /etc/host*> ;
Trong hon cnh mng, nh trnh by y, glob
cho li mt danh sch tt c cc tn snh ng vi mu
(cng nh lp v m rng cc i glob), hay mt
danh sch rng nu khng snh ng. Trong hon cnh
v hng, s cho li tn tip snh ng, hay undef nu
khng cn tn no snh ng: iu ny rt ging vi vic
c t mt tc hiu tp. Chng hn, mi lc nhn vo
mt tn:
while ($nextname = </etc/host*> ) {
print mt trong cc tp l $nextname\n ;
}
Ti y tn tp c cho li bt u vi /etc/host,
cho nn nu bn mun ch phn cui cng ca tn, bn

212

s phi t mnh o gt n, ging nh:
while ($nextname = </etc/host*> ) {
$nextname =~ s#.* / ## ; # b phn trc du s
cho
print mt trong cc tp l $nextname\n ;
}
Nhiu khun mu c php t vo bn trong i
glob - cc danh sch c xy dng tch bit v ri c
ni li dng nh chng l mt danh sch ln:
@fred_barney_files = <fred* barney*> ;
Ni cch khc, glob cho li cng cc gi tr tng
ng vi ch lnh echo vi cng cc tham bin s cho
li
*
.
Mc du globbing v hm snh biu thc chnh qui
l tng t nhau, ngha ca cc k t c bit y li
hon ton khc nhau. Bn ng ln ln gia hai cch k
hiu ny, nu khng bn s kh hiu ti sao <\.c$> li
khng tm thy tt c cc tp c tn cng l .c!
i cho glob l mt bin c chen vo trc khi
m rng. Bn c th c cc tham chiu bin Perl la
ra mt du i din da trn mt xu c tnh vo lc
chy:
if (-d /usr/etc) {
$where = /usr/etc ;
} else {
$where = /etc ;
}

*
iu ny thc ti khng ng ngc nhin khi bn hiu rng thc
hin glob, Perl n thun bn ra lp v C ly danh sch c bit
ri phn tch ci n nhn c.

213

@files = <$where/*> ;
Ti y ti t $where l mt trong hai tn danh mc
khc, da trn liu danh mc /usr/etc c tn ti hay
khng. Ri ti ly mt danh sch cc tp trong danh mc
c chn. Lu rng bin $where c m rng, c
ngha l khun mu c glob hoc l /etc/* hay /usr/etc/*.
C mt ngoi l cho qui tc ny: khun mu <$var>
(ngha l dng bin $var nh mt khun mu glob ton
b) phi c vit l <${var}> bi l do ti khng mun
a vo ti im ny
**
.

Tc hiu danh mc
Nu bn mun c hng v UNIX c bit nh hm
th vin readdir, Perl cng cung cp vic truy nhp vo
trnh con (v php so snh ca n) bng vic dng
tc hiu danh mc. Tc hiu danh mc l mt tn ly
t mt khng gian tn khc, v nhng thn trng cng
li khuyn p dng cho tc hiu tp, cng p dng cho
tc hiu danh mc (bn khng th dng mt t dnh
ring, v ch hoa c khuyn nn dng). Tc hiu tp
FRED v tc hiu danh mc FRED l khng c quan
h.
Tc hiu danh mc biu th cho mt ghp ni ti
mt danh mc c bit. Thay v c d liu (nh t tc

**
Kt cu <$fred> c mt dng t tc hiu tp c tn theo ni
dung ca bin v hng $fred. Cng vi mt s tnh nng khc
khng c ni ti trong cun sch ny, kt cu ny cho php bn
dng tc hiu tp gin tip, ch m tn ca tc hiu c
truyn quanh v thao tc dng nh l mt d liu

214

hiu tp), bn dng tc hiu danh mc c mt danh
sch cc tn tp bn trong danh mc . Tc hiu danh
mc bao gi cng c m ch c - bn khng th no
dng mt tc hiu danh mc thay i tn ca tp hay
xo tp.
Nu th vin ca bn khng cung cp readdir (v
bn khng cung cp mt trong trong nhng ci t thay
th sao chp c trong khi xy dng Perl), vic dng
bt k mt trong nhng trnh con ny s l li nh mnh,
v chng trnh ca bn s khng qua c trnh bin
dch - n s b b trc khi dng chng trnh u tin
c thc hin. Perl c gng rt vt v c lp bn vi
mi trng, nhng n khng phi l mt cng nhn mu
nhim.

M v ng tc hiu danh mc
Hm opendir() lm vic ging nh li gi th vin
ca cng tn. Bn trao cho n tn ca mt tc hiu
danh mc mi v mt gi tr xu k hiu cho tn ny ca
danh mc s c m ra. Gi tr cho li t opendir() l
ng nu danh mc c th c m, v l sai trong cc
trng hp khc. Sau y l mt th d:
opendir(ETC, /etc) || die Khng th m opendir /etc ;
Thng thng, ti im ny, chng ta ang chi vi
tc hiu danh mc ETC, nhng c th hay hn nu bit
cch ng tc hiu danh mc ny trc. iu ny c
thc hin vi closedir(), theo cch tng t nh vic dng
close(), ging nh:
closedir(ETC) ;

215

Ging nh close(), closedir() thng cng chng cn,
v tt c cc tc hiu danh mc t ng c ng
li trc khi chng c m li hay ti cui chng
trnh.

c mt tc hiu danh mc
Mt khi chng ta c vic m mt tc hiu danh
mc, chng ta c th c danh sch cc tn bng
readdir(), nhn mt tham bin: tn ca tc hiu danh
mc. Mi ln gi ti readdir() trong hon cnh v hng
cho li tn tp tip (ht nh basename - bn s khng
bao gi nhn c bt k du s cho no trong gi tr
cho li) theo mt trt t dng nh ngu nhin
*
. Nu
khng cn tn no na, readdir() cho li undef. Vic gi
readdir() trong hon cnh mng cho li tt c cc tn cn
li nh mt danh sch vi mi tn cho mt phn t. Sau
y l mt th d v danh sch tt c cc tn ly t danh
mc /etc:
opendir(ETC, /etc) || die Khng c etc? ;
while ($name = readdir(ETC)) { # hon cnh v hng
print $name\n ; # in ., .., passwd, group vn vn
}
closedir(ETC) ;
V sau y l cch ly chng tt c theo trnh t
bng ch vi s h tr ca sort:
opendir(ETC, /etc) || die Khng c etc? ;
foreach ($name (sort readdir(ETC)) { # hon cnh v

*
Ni ring, y l trt t m cc tn tp c ct gi trong danh
mc - cng trt t cha sp m bn nhn c t ch lnh find hay
ls -f.

216

hng, c sp xp
print $name\n ; # in ., .., passwd, group vn vn
}
closedir(ETC) ;
L rng cc tn bao gm cc tp bt u vi mt
du chm. iu ny khng ging nh glob vi <*> m
khng cho li cc tn bt u vi mt chm (ging nh
echo * ca lp v ).

Bi tp
1. Vit mt chng trnh thay i danh mc cho mt
v tr c xc nh nh ci vo, ri lit k cc tn
ca cc tp ny theo trnh t abc sau khi thay i
. (ng hin danh sch nu vic i danh mc
khng thnh cng - n gin ch cnh bo cho c
gi.)
2. Sa i chng trnh ny bao qut tt c cc tp,
khng ch nhng tp khng bt u vi du chm.
Th lm iu ny vi c mt glob v mt tc hiu
danh mc.


217

13


Thao tc tp
v danh mc


Loi b tp
Trc y, bn bit cch to ra mt tp t bn
trong Perl bng vic m n lm ci ra thng qua mt
tc hiu tp. By gi, chng ta s gp nguy him hn,
v hc cch loi b mt tp (rt thch hp vi Chng
13, bn c ngh nh vy khng?)
Ton t unlink() ca Perl (c ly theo tn ca li
gi h thng UNIX) s xo i mt tn i vi mt tp
(m c th mang nhiu tn). Khi tn cui cng cho mt
tp b xo i, bn thn tp ny cng s b loi b i. iu
ny ch xc l l iu ch lnh rm thc hin. Bi v
mt tp thng ch c mt tn (tr phi bn to ra mc
ni cng), bn c th ngh n vic loi b mt tn nh
vic loi b tp i vi phn ln cc trng hp. Gi s
Trong chng ny:
. Loi b tp
. i tn tp
. To ra tn khc cho
tp (mc ni)
. To v loi b danh
mc
.Sa i quyn thao tc
. Sa i quyn s hu
. Sa i thi gian

218

nh th, sau y l cch loi b mt tp c tn l fred v
ri loi b mt tp c xc nh trong khi thc hin
chng trnh:
unlink(fred) ; # ni li tm bit vi fred
print Bn mun xo b tp no? ;
chop ($name = <STDIN>) ;
unlink ($name) ;
Ton t unlink c th nhn mt danh sch cc tn cn
phi tho mc ni nh:
unlink (spottedowl, meadowlark) ; # git cht hai con
chim
unlink (<*.o>) ; # ht nh rm *.o trong lp v
Lu rng glob c tnh ton theo hon cnh
mng, to ra mt danh sch cc tn tp snh ng vi
khun mu, v iu ny ch th l iu cn np vo
unlink().
Gi tr cho li ca unlink() l s cc tp b nh
hng thnh cng. Nu c mt i tn tp v n b xo
i, kt qu l mt, ngoi ra, n l khng. Nu c ba tn
tp nhng ch c hai tn c th b xo i, kt qu l hai.
Lu rng bn khng th bit c hai tp no, cho nn
nu bn cn phi hnh dung ra vic xo no b hng, bn
phi thc hin ln lt tng vic xo mt. Sau y l
cch xo i tt c cc tp ch (tn cng bi o.) trong khi
bo co li li vi bt k tp no m khng th no xo
c.
foreach $file (<*.o>) { # bc qua danh sch cc tp .o
unlink ($file) || print gp rc ri vi tp $file\n ;
}
Nu unlink cho li 1 (c ngha l mt tp xc nh
qu thc b xo), kt qu ng s nhy qua cu lnh

219

print. Nu tp ny khng th no b xo i, kt qu 0 l
sai, cho nn cu lnh print c thc hin. Li mt ln
na, iu ny c th c c mt cch tu nh tho
mc ni tp ny hay cho ti bit v n.
Nu ton t unlink c nu ra khng c i, bin $_
ln na li c dng nh mc nh. Vy, chng ta c
th vit chu trnh trn l:
foreach (<*.o>) { # bc qua danh sch cc tp .o
unlink || print gp rc ri khi xo $_\n ;
}

i tn tp
Trong lp v, bn i tn tp bng ch lnh mv. Vi
Perl, cng php ton ny c k hiu bng rename($old,
$new). Sau y l cch thay i tp c tn fred thnh
barney:
rename(fred, barney) || die Khng th i tn fred
thnh barney;
Ging nh hu ht cc ton t khc, ton t rename()
cho li gi tr ng nu cng vic din ra thnh cng,
cho nn y ti kim tra kt qu ny xem liu
vic i tn c thc s xy ra khng.
Ch lnh mv thc hin mt cht t o thut hu cnh
to ra mt ng dn y khi bn ni mv file
some-directory. Tuy nhin, ton t rename(), li khng
th lm iu . Php ton Perl tng ng l:
rename(file, some-directory/file) ;
L rng trong Perl chng ta phi ni tn ca tp

220

bn trong danh mc mi mt cch tng minh. Cng
vy, ch lnh mv sao tp ny khi tp c i tn t thit
b ny sang thit b khc (nu bn c mt trong cc ci
t UNIX tt hn). Ton t rename() khng tht khn
cho lm, cho nn bn s nhn c li, ch ra bn phi
chuyn vng n theo cch khc (c l bi vic gi ch
lnh mv theo cng tn).

To ra tn thay phin cho mt tp (mc ni)
Dng nh l mt tn cho mt tp vn khng ,
i khi bn mun c hai tn, ba tn hay c t tn cho
cng mt tp. Php ton to ra nhiu tn thay phin cho
mt tp c gi l mc ni. Hai dng chnh ca mc
ni l mc ni cng v mc ni tng trng (cng cn
c gi l mc ni mm).

V mc ni cng v mm
Mc ni cng vi mt tp l khng th no phn
bit c vi tn gc cho tp ny - khng c mc ni
c bit no nhiu hn l tn tht cho tp ny so vi bt
k tn khc.
Li UNIX gi du vt s cc mc ni cng tham
chiu ti mt tp vo bt k lc no. Khi mt tp ln u
tin c to ra, n bt u vi mt lin kt. Mi lin kt
cng mi li lm tng thm s m ny. Mi khi lin kt
b loi b, s m li c gim i. Khi lin kt cui
cng vi mt tp bin mt, tp cng mt theo.
Mi mc ni cng vi mt tp phi nm cng mt

221

n v lu thng tin (thng thng l mt a hay mt
phn ca a). Bi iu ny, bn khng th no to ra
mt mc ni cng mi vi mt tp nm trn mt n v
lu thng tin khc.
Mc ni cng cng b hn ch vo cc danh mc.
gi cho cy cc tp ca UNIX cn l mt cy thay v
l mt m hn n bt k, mt danh mc mi ln ch
c php mang mt tn t gc, mt mc ni t tp
chm bn trong n, v mt chm cc mc ni cng chm
chm t tng danh mc con ca n. Nu bn th to ra
mt mc ni cng khc cho mt danh mc, bn s nhn
c mt li (chng no m bn cn cha l siu ngi
dng).
Mt mc ni tng trng l mt loi tp c bit c
cha ng dn nh d liu. Khi tp ny c m, li
UNIX s nhn vo ni dung ca n xem nh cc k t
ph cho ng dn, lm cho li phi d qua cy danh
mc thm na, bt u vi tn mi.
Chng hn, nu mt mc ni tng trng c tn fred
li cha tn barney, vic m fred thc s l mt ch bo
m barney. Nu barney l mt danh mc, fred/wilma
s thay v th m tham chiu ti barney/wilma.
Ni dung ca mc ni tng trng (ni mc ni
tng trng tr ti) khng phi tham chiu ti mt tp
hay danh mc c. Khi fred c to ra, barney thm
ch phi khng c tn ti - thc ra, n c th chng
bao gi tn ti c! Ni dung ca mt mc ni tng
trng c th tham chiu ti mt ng dn m s a
bn ti ni ct gi hin ti, cho nn bn c th to ra mt
mc ni tng trng ti mt tp trn mt thit b lu tr

222

khc.
Trong khi i theo tn mi, li c th chy qua mt
mc ni tng trng khc. Mc ni tng trng ny
thm ch cn cho phn mi hn so vi ng dn phi
theo. Thc ra, mc ni tng trng c th tr ti cc
mc ni tng trng khc, m thng thng c t nht
tm mc mc ni tng trng c php, mc du iu
ny him khi c dng trong thc hnh.
Mc ni cng bo v cho ni dung ca tp khi b
mt (v n vn cn m khi c mt trong cc tn ca
tp). Mc ni tng trng khng th no gi c ni
dung khi b mt. Mt mc ni tng trng c th xuyn
qua cc thit b lu tr hin c trong khi mc ni cng,
li khng th th c. Ch mc ni tng trng mi c
th c lm thnh mt danh mc.
Bn phi c kh nng ghi ln danh mc ni bn
ang to ra ra hoc l mt loi mc ni, cho d bn c
th khng cn phi c kh nng m tp m ang mc ni
ti. Bn phi c kh nng thng k stat cho tp (nh c
th ni bi ls -l filename) to ra mt mc ni cng,
nhng bn khng cn mt truy nhp nh vy xem nh
mt mc ni tng trng.

To ra cc mc ni cng v mm bng Perl
Ch lnh ln ca UNIX to ra mc ni cng. Ch lnh
ln fred bigdumbguy
to ra mt mc ni cng t tp fred (m phi tn ti)
i vi bigdumbguy. Trong Perl iu ny c din t l:

223

link (fred, bigdumbguy) ||
die khng th mc ni fred vi bigdumbguy ;
Ton t link() nhn hai i, tn tp c v bit hiu
mi cho tp . Ton t ny cho li ng nu vic mc
ni thnh cng. Nh vi ch lnh mv, ch lnh ln ca
UNIX thc hin vi th thut ng sau hu trng, cho
php bn xc nh danh mc ch i vi bit hiu mi
m khng t tn tp bn trong danh mc ny. Ton t
link() (ging nh ton t rename()) cng khng tht thng
minh cho lm, v bn phi xc nh tn tp hon ton
tng minh.
Vi mt mc ni cng, tn tp c khng th l mt
danh mc, cn bit hiu mi li phi l trn cng h
thng tp. (Hn ch ny l mt phn ca l do rng cc
mc ni tng trng c to ra.)
Trn h thng c h tr cho mc ni tng trng,
ch lnh ln ca UNIX c th c cho thm tu chn -s
to ra mc ni tng trng. Cho nn, to ra mt
mc ni tng trng t barney sang neighbor ( cho
tham chiu ti neighbor thc ti l mt tham chiu ti
barney), bn phi dng ci g ta nh th ny:
ln -s barney neighbor
v trong Perl, bn nn dng ton t symlink(), ta
nh
symlink(barney, neighbor) ||
die Khng th to mc ni tng trng sang
neighbor ;
Lu rng barney khng cn tn ti (Betty ng
thng i!), c by gi hay trong tng lai. Trong
trng hp ny, mt tham chiu ti neighbor s cho li

224

ci g m h ta nh file not found.
Khi bn gi ls -l trn danh mc c cha mt mc ni
tng trng, bn nhn c mt ch bo v c hai tn
ca mc ni tng trng v ni mc ni tr ti. Perl cho
bn cng thng tin ny qua ton t readlink(), lm vic
ng ngc nhin ging nh li gi h thng vi cng tn,
cho li mt tn c tr ti bi mt mc ni tng trng
c bit. Cho nn, php ton ny:
if ($x = readlink(neighbor)) {
print neighbor tr ti $x\n ;
}
nn ni v barney nu tt c n tho. Nu mc
ni tng trng khng tn ti hay khng th c c
hay thm ch khng phi l mc ni tng trng,
readlink() cho li undef (sai tt nh), m y l l do ti
sao ti li ang th n y.
Trn h thng khng c mc ni tng trng, c hai
ton t symlink() v readlink() khng c dch, lm
cho chng trnh b b trc khi n c bt u. iu
ny l v khng c s tng ng snh c no cho
mc ni tng trng trn cc h thng khng h tr cho
n. Perl c th che du mt s tnh nng ph thuc h
thng vi bn, nhng mt s tnh nng s d r ra ngay.
y l mt trong chng.

To ra v xo danh mc
C l bn khng th lm c iu ny thm nu
khng bit v ch lnh mkdir ca UNIX, ch lnh to ra
danh mc cha cc tp khc, v cc danh mc khc.

225

Thnh phn tng ng ca Perl l ton t mkdir(),
nhn mt tn cho mt danh mc mi v mt mt m s
nh hng ti quyn v danh mc c to ra. Mt ny
c xc nh nh mt s m c din gii theo dng
thc quyn bn trong. Nu bn cha quen thuc vi cc
quyn bn trong ny, xem chmod(2) trong ti liu. Nu
bn vi v, ch cn dng 0777 cho mt ny v mi th s
gn nh lm vic c. Sau y l mt th d v cch to ra
mt danh mc c tn gravelpit:
mkdir (gravelpit, 0777) || die khng th mkdir
gravelpit ;
Ch lnh rmdir ca UNIX loi b i danh mc rng -
bn s thy thnh phn Perl tng ng vi cng tn.
Sau y l cch lm cho Fred thnh tht nghip:
rmdir(gravelpit) || die khng th rmdir gravelpit ;
Mc du nhng ton t Perl ny li dng cng tn
li gi h thng, chng ta vn lm vic trn cc h thng
khng c nhng li gi ny (mc du c chm hn i
cht). Perl t ng gi ti cc tin ch /bin/mkdir v
/bin/rmdir cho bn (hay bt k ci g chng c gi trn
h thng ca bn). Cng l gip mt phn nhn danh
tnh kh chuyn.

Thay i php s dng
Php s dng i vi mt tp hay danh mc xc
nh ra ai (theo phm tr rng) c th lm g (nhiu hay
t) i vi tp hay danh mc . Di UNIX, cch in
hnh thay i php trn tp l dng ch lnh chmod
(xem ti liu nu bn cha quen thuc vi s vn hnh

226

ca n). Tng t nh vy, Perl thay i php qua ton
t chmode(). Ton t ny nhn mt mt s v mt danh
sch cc tn tp, v c gng thay i php ca tt c cc
tn tp sang theo mt ch ra. lm cho cc tp fred
v barney c hai l c/ghi vi mi ngi, chng hn,
lm iu g ta nh th ny:
chmod(0666, fred, barney) ;
Ti y, gi tr ca 0666 cho php c/ghi i vi
ngi dng, nhm v ngi khc, cho chng php mong
mun.
Gi tr cho li ca chmod() l s cc tp c iu
chnh thnh cng (cho d nu vic iu chnh chng lm
g c), cho nn n lm vic ging nh unlink(), v bn nn
x l n nh x l kim tra li. Sau y l cch thay i
php cho fred v barney trong khi kim tra li cho tng
tp:
foreach $file (fred, barney) {
unless (chmod(0666, $file) {
print H ... khng th i c chmod
$file.n ;
}
}

Thay i quyn s hu
Mi tp (hay danh mc, hay li vo thit b, hay bt
k ci g) trong h thng tp c mt ngi ch v mt
nhm. Ngi ch v nhm ca mt tp xc nh ra ai l
ngi c php tin hnh (c, ghi v/hoc thc hin
tp). Ngi ch v nhm ca mt tp c xc nh vo
lc tp c to ra, nhng trong hon cnh no , bn

227

c th thay i c chng. (Hon cnh ng n tu
thuc vo dng UNIX c bit m bn ang chy - xin
xem chi tit ti liu v chwn.)
Ton t chown() nhn mt s hiu ngi dng ID
(UID), s hiu nhm ID (GID), v mt danh sch cc tn
tp, d nh thay i quyn s hu cho tng tp c
lit k nh xc nh. Vic thay i thnh cng c
ch ra bng gi tr cho li khc khng, gi tr bng s
lng cc tp thay i thnh cng - ging ht chmod()
hay unlink(). Lu rng bn ang thay i c ngi ch
v nhm mt lc; bn khng th thay i ch mt thnh
phn. Cng cn ch rng bn phi dng UIS v GID
s, khng phi l tn tng trng tng ng (mc du
ch lnh chmod chp nhn tn). Chng hn, nu fred l
UID 1234 cn nhm mc nh stoners ca fred l GID
35, th, ch lnh sau y to ra tp slate v granite thuc
vo fred v nhm mc nh cho anh ta:
chown (1234, 35, slate, granite) ; # ht nh:
# chown fred slate granite
# chgrp stoners slate granite
Trong chng sau, bn s hc cch chuyn fred sang
1234 v stoners sang 35.

Thay i nhn thi gian
Lin kt vi tng tp l mt tp ba nhn thi gian.
Cc nhn thi gian ny c cp ngn gn ti khi
chng ni v vic ly thng tin v tp: ln truy nhp cui
cng, thi gian sa i cui cng, v thi gian thay i
inode. Hai nhn thi gian u c th c t cho gi tr
tu bng ton t utime() (m tng ng trc tip vi li

228

gi h thng UNIX cng tn). Vic t hai gi tr ny s
t ng t li gi tr th ba thnh thi gian hin ti, cho
nn khng c vn g lin quan ti vic t gi tr th
ba.
Cc gi tr c o theo thi gian ni b ca UNIX,
c ngha l mt s nguyn ch ra s giy tri qua t
na m GMT, 1 thng 1 nm 1970 - mt con s t ti
qung by trm triu, khi cun sch ny ang c vit
ra. (Bn trong, n c biu din nh mt s 32-bit c
du, v i khi s b trn sm trong th k ti.)
Ton t utime() lm vic ging nh chmod() v
unlink(). N nhn mt danh sch cc tn tp v cho li s
cc tp b nh hng. Sau y l cch lm cho cc tp
fred v barney trng ging nh chng b thay i u
mi y:
$atime = $mtime = 700000000 ; # thi gian trc y
utime($atime, $mtime, fred, barney) ;
Khng c gi tr hp l cho nhn thi gian: bn c
th lm cho mt tp trng thc l c k nh n c
sa i u trong tng lai xa xi (c ch nu bn
ang vit chuyn khoa hc vin tng). Chng hn, dng
ton t time (m cho li thi gian hin ti nh mt nhn
thi gian UNIX), sau y l cch lm cho tp
max_headroom c v nh c cp nht 20 pht trong
tng lai:
$when = time + 20*60 ; # 20 pht na t by gi
utime($when, $when, max_headroom) ;


229

Bi tp
1. Vit mt chng trnh lm vic ging nh rm, xo i
cc tp c cho nh i dng lnh khi chng trnh
ny c gi ti. (Bn khng cn phi gii quyt bt
k tu chn no ca rm.)
Kim th cn thn chng trnh ny trong mt danh
mc gn rng cho bn khng ngu nhin xo i
mt cht liu c ch! Nh rng i dng lnh th
nht c sn trong mng @ARGV khi chng trnh
bt u.
2. Vit mt chng trnh lm vic ging nh mv, i
tn i dng lnh th nht thnh i dng lnh th
hai. (Bn khng cn gii quyt bt k tu chn no
ca ln, hay nhiu hn hai i dng lnh.)
3. Vit mt chng trnh lm vic ging nh ln, to ra
mt mc ni cng t i dng lnh th nht sang i
dng lnh th hai. (Bn khng cn gii quyt bt k
tu chn no ca ln, hay nhiu hn hai i dng
lnh.)
4. Nu bn c cc mc ni tng trng, thay i
chng trnh trong bi tp trc gii quyt mt
kho tu chn -s
5. Nu bn c mc ni tng trng, vit mt chng
trnh tm tt c cc tp c mc ni tng trng tng
t nh cch ls -l thc hin n (name -> value). To ra
mt s mc ni tng trng trong danh mc hin
thi v kim th n.


230


14


Qun l
tin trnh


Dng system() v exec()
Khi bn trao cho lp v mt dng ch lnh thc
hin, lp v to ra mt tin trnh thc hin ch lnh
ny. Tin trnh mi ny tr thnh tin trnh con ca lp
v, thc hin c lp v khng phi hp g vi lp v c.
Tng t, mt chng trnh Perl c th pht ng
cc tin trnh mi, v ging nh hu ht cc php ton
khc, c nhiu cch thc hin n.
Cch n gin nht pht ng mt tin trnh mi
l dng ton t system. Di dng n gin nht ca n,
ton t ny trao mt xu cho lnh lp v /bin/sh c
thc hin nh mt ch lnh. Khi ch lnh ny c hon
Trong chng ny:

Dng system() v
exec()
Dng trch dn li
Dng tin trn hv
tc hiu tp
Dng fork
Tm tt v php
ton tin trnh
Gi v nhn tn
hiu

231

thnh, ton t system cho li gi tr ra ca ch lnh (in
hnh l 0 nu mi th din tin tt p). Sau y l mt
th d v mt chng trnh Perl thc hin ch lnh date
bng vic dng lp v
*
:
system (date) ;
Lu rng ti ang khng bit g v gi tr cho li
y, nhng chng th no m ch lnh date li khng
thc hin c.
Ci ra s i u? Thc ra, ci vo ti t u, nu y
l mt ch lnh mun a vo? y l nhng cu hi
hay, v cu tr li cho nhng cu hi ny l phn ln
nhng iu phn bit cc dng khc nhau ca vic to ra
tin trnh.
Vi ton t system, ba tp chun (ci vo chun, ci
ra chun, v li chun) c k tha t tin trnh Perl.
Cho nn vi ch lnh date trong th d trn, ci ra s
chuyn n bt k u m print STDOUT i ra - c l l
trn mn hnh ca ni gi. Bi v bn ang pht ho ra
lp v, nn bn c th thay i v tr ca ci ra chun
bng vic dng cch chuyn hng vo/ra thng thng
/bin/sh. Chng hn, t ci ra ca ch lnh date vo
trong mt tp c tn right_now, iu g ta th ny s
c tc dng:
system (date > right_now) && die Khng th to ra
right_now ;
Ln ny, ti khng ch gi ci ra ca ch lnh date

*
iu ny thc t khng dng ti lp v - Perl thc hin cc php
ton ca lp v nu dng ch lnh n gin, v y l mt trng
hp.

232

vo mt tp vi vic i hng sang lp v, m ti cn
kim tra trng thi cho li. Nu trng thi cho li l ng
(khc khng), ci g b sai vi ch lnh lp v, v ton
t die s tin hnh hnh ng ca n. y l nhc im
theo qui c ton t thng thng ca Perl - gi tr cho
li khc khng t ton t system ni chung ch ra rng
iu g b sai.
i cho ton t system c th l bt k ci g m bn
s np vo /bin/sh, cho nn nhiu ch lnh c th c
bao hm vo, tch bit nhau bng du chm phy hoc
dng mi. V cc tin trnh kt thc trong & s c
khi ng v khng i, d cho bn g mt dng kt
thc vi mt & vo lp v.
Sau y l mt th d v vic sinh ra ch lnh date v
who cho lp v, gi ci ra ti tn tp c xc nh bi
mt bin Perl. Tt c iu ny xy ra trong hu cnh sao
cho chng khng phi i n trc khi tip tc vi bn
ghi Perl:
$where = who_out..++$i ; # ly mt tn tp mi
system ((date; who) > $where &) ;
Gi tr cho li t system trong trng hp ny l gi
tr ra ca lp v, v do vy ch ra liu tin trnh hu cnh
khi ng thnh cng hay cha, nhng khng ch ra
liu cc ch lnh date hay who c thc hin thnh cng
hay khng. Xu nhy kp l mt bin xen ln, cho nn
$where c thay th bng gi tr ca n trc khi lp v
thy n. Nu bn mun tham chiu ti bin lp v c
thn $where, bn phi t du s cho ngc trc du
la, hay dng mt xu nhy n, hay mt ci g
ging th.

233

Mt tin trnh con k tha nhiu iu t cha m n
bn cnh cc tc hiu tp chun. Nhng tin trnh ny
bao gm vic b mt n hin ti, danh mc hin ti, v
tt nhin c ID ngi dng.
Bn cnh , cc bin mi trng cng c tin
trnh con k tha. Cc bin ny c thay i in hnh
qua ch lnh csh setenv hay php gn tng ng v
export bi lp v /bin/sh. Cc bin mi trng c
nhiu trnh tin ch dng, k c lp v, thay i hay
kim sot cch thc trnh tin ch ny vn hnh.
Perl cho bn mt cch kim tra v thay i bin mi
trng hin ti qua mt mng kt hp bun ci gi
l %ENV (ch hoa). Mi kho ca mng ny tng ng
vi tn ca mt bin mi trng, vi gi tr tng ng,
tt nhin, l gi tr tng ng. Vic xem xt mng ny
ngay u chng trnh ch ra cho bn mi trng c
trao cho Perl bi lp v cha m - vic thay i mng ny
nh hng ti mi trng do Perl s dng v cho cc
tin trnh con ca n.
Chng hn, sau y l mt chng trnh n gin
hnh ng ging nh printenv:
for $key (sort keys %ENV) {
print $key = $ENV{$key}\n ;
}
Lu rng du bng y khng phi l php gn,
nhng n gin l mt k t vn bn m print dng in
ra cht liu nh TERM=xterm hay USER=merlyn.
Sau y l mt chng trnh nhi ranh lm thay i
gi tr ca PATH bo m rng ch lnh grep do
system cho chy c tm ti ch nhng ch thng

234

thng:
$oldPATH = $ENV{PATH} ; # ct gi ng dn trc
$ENV{PATH} = /bin:/usr/bin:/usr/ucb ; # buc ng
dn bit
system (grep fred bedrock > output) ; cho chy ch lnh
$ENV{PATH} = $oldPATH ; # khi phc li ng dn
trc
Ton t system cng c th nhn mt danh sch i,
thay v mt i. Trong trng hp ny, thay v cho
lp v din gii danh sch i, Perl x l i th nht
nh mt ch lnh chy (c nh v tng ng theo
PATH nu cn thit) v cc i cn li nh cc i cho
ch lnh khng c din gii lp v thng thng. Ni
cch khc, bn khng cn trch dn khong trng hay lo
lng v cc i c cha du ngoc nhn bi v tt c
nhng ci n thun ch l cc k t truyn cho
chng trnh. Vy, hai ch lnh sau y l tng ng:
system grep fred flnttone buffaloes ; # dng lp v
system grep, fred flnttone, buffaloes ; # dng danh
sch
Cho mt danh sch ch khng cho mt xu n s
tit kim cho bn mt tin trnh lp v, cho nn lm iu
ny khi bn c th. (Thc ra, khi dng mt i ca
system l n gin, Perl ti u ton b li gi lp v,
gi chng trnh kt qu mt cch trc tip dng nh
bn dng li gi nhiu i.)
Sau y l mt th d khc v cc dng tng
ng:
@cfiles = ( fred.c, barney.c) ; # tp phi dch
@options = ( -DHARD, -DGRANITE) ; # tu chn
system cc -o slate @option @cfiles ; # dng lp v
system cc, -o, slate, @options, @cfiles ; # dng danh

235

sch

Dng du nhy n ngc
Mt cch khc pht ng mt tin trnh l t
dng ch lnh v /bin/sh gia cc du nhy n ngc.
Ging nh lp v, dng lnh ny pht ra mt ch lnh v
i vic hon tt, a ra u ra chun. Khng ging nh
lp v, vn bn kt qu khng c m rng ti ch (tr
thnh nhiu ci vo ca kt cu Perl) m thay v th tr
thnh gi tr ca xu nhy n ngc. Chng hn:
$snow = Thi gian by gi l . `date` ; # ly vn bn v
ngy a ra
Gi tr ca $now s l vn bn Thi gian by gi l
cng vi kt qu ca ch lnh date (k c du xung
dng cui cng), cho nn n ging nh:
Thi gian by gi l Fri Aug 13 23:59:59 PDT 1993
Nu ch lnh du nhy n ngc c dng trong
hon cnh mng ch khng phi hon cnh v hng,
bn thu c mt danh sch cc xu, mi mt xu l mt
dng (c kt thc vi du xung dng) t ci ra ca
ch lnh. Vi th d v date, chng ch c mt phn t,
bi v n ch sinh ra mt dng vn bn. Ci ra ca who,
trong ging th ny:
merlyn tty13 Sep 1 14:55
fred tty1A Aug 31 07:02
barney tty1F Sep 1 09:22
Sau y l cch ly ci ra ny trong ng cnh mng:
foreach $_ (`who`) { # mt ln cho mi dng vn bn t
who

236

($who, $where, $when) = / (\S+)\s+(\S+)\s+(.*)/ ;
print $who trn $where ti $when\n ;
}
Mi bc qua chu trnh lm vic trn mt dng
tch bit ca ci ra ca who, bi v ch lnh du ngoc
n ngc c tnh bn trong hon cnh mng.
Ci vo chun v li chun ca ch lnh bn trong
du nhy n ngc l c k tha t tin trnh Perl.
iu ny c ngha l bn thng thng ch ly c ci
ra chun ca cc ch lnh bn trong du nhy n ngc
nh gi tr ca xu du nhy n ngc. Mt iu thng
dng thng lm l gp li chun vo trong ci ra chun
cho ch lnh du nhy n ngc ly c hai, dng kt
cu 2>&1 ca lp v:
die rm mawi! if rm fred 2>&1 ;
Ti y, tin trnh Perl c kt thc nu rm khng
ni g, hoc ni vi ci ra chun v li chun, bi v kt
qu s khng l mt xu rng (xu rng s sai).

Dng cc tin trnh nh tc hiu tp
Cn cch khc pht ng mt tin trnh l to ra
mt tin trnh ging nh mt tc hiu tp (tng t nh
trnh th vin popen nu bn quen thuc vi n). Bi v
tc hiu tp m hoc c hoc ghi, nn chng ta c
th to ra mt tc hiu tp-tin trnh m hoc ly ci ra
t hoc cung cp ci vo cho tin trnh. Sau y l mt
th d v vic to ra mt tc hiu t tin trnh who. Bi
v tin trnh ny ang sinh ra ci ra nn chng ta to ra
mt tc hiu m c, nh:

237

open (WHOPROC, who |) ; # m c
n thanh s ng pha bn phi ca who.
Thanh bo cho Perl rng open ny khng phi l tn
tp, m thay vo l ch lnh cn bt u. Bi v thanh
ny l bn phi ca ch lnh, nn tc hiu tp c m
c, c ngha l ci ra chun ca who c d nh b
bt gi. (Ci vo chun v li chun vn cn c dng
chung vi tin trnh Perl.) Vi phn cn li ca chng
trnh ny, WHOPROC gii quyt n thun tc hiu
tp m m c, c ngha l tt c cc ton t
vo/ra tp thng thng p dng c. Sau y l
cch c d liu t ch lnh who vo mng:
@whosaid = <WHOPROC> ;
Tng t, m mt ch lnh m trng i ci vo,
chng ta c th m mt tc hiu tp-tin trnh ghi
bng vic t thanh s ng bn tri ca ch lnh, nh:
open(LPR, | lpr -Pslatewrite) ;
print LPR @rockreport ;
close(LPR) ;
Lu rng trong trng hp ny, sau vic m LPR,
chng ta ghi d liu no ln n, v ri ng n li.
Vic m mt tin trnh vi tc hiu tp-tin trnh cho
php ch lnh c thc hin song song vi chng trnh
Perl. Vic ni close() trn tc hiu tp ny buc chng
trnh Perl phi i n khi tin trnh ny ra. Nu bn
khng ng tc hiu tp, tin trnh ny c th tip tc
chy thm ch bn ngoi vic thc hin chng trnh
Perl.
Vic m mt tin trnh ghi s lm cho u vo
chun ti t tc hiu tp. Tin trnh ny dng chung ci

238

ra chun v li chun vi Perl. Nh trc y, bn c th
dng vic nh hng vo-ra kiu /bin/sh, cho nn y
c mt cch n gin lc b thng bo li t ch
lnh lpr trong th d trc:
open(LPR, | lpr -Pslatewrite > /dev/null 2>&1) ;
/dev/null gy ra ci ra chun c nh hng li ti
thit b khng. 2>&1 gy cho li chun c gi ti ch
ci ra chun c gi ti, kt qu li s b ct b i.
Bn thm ch c th t hp tt c nhng iu ny li,
sinh ra mt bo co v mi ngi ch tr Fred trong danh
sch cc vo, kiu nh:
open(WHO, who |) ;
open (LPR, | lpt -Pslatewrite) ;
while (<WHO>) {
unless (/fred/) { # khng a ra fred
print LPR $_ ;
}
}
close (WHO) ;
close (LPR) ;
Khi on chng trnh ny c t tc hiu WHO
mt dng mi lc, n in ra tt c cc dng m khng
cha xu fred cho tc hiu LPR. Cho nn ch ci ra trn
my in mi l dng khng cha fred.

Dng fork
Vn cn mt cch khc to ra mt tin trnh ph
l bm theo mt tin trnh Perl hin ti bng vic dng
nguyn s UNIX c tn l fork. Ton t fork n gin lm
iu m li gi h thng fork thc hin; ton t ny to ra

239

mt bn bm theo tin trnh hin ti. Bn bm theo ny
(c gi l con, vi bn gc c gi l b m) dng
chung cng chng trnh thc hin, bin, v thm ch c
cc tp m. phn bit hai tin trnh ny, gi tr cho
li t ton t fork l khng i vi con, v khc khng
i vi b m. Bn c th kim tra iu ny v hnh
ng tng ng:
if (fork) {
# ti l b m
} else {
# ti l con
}
dng tt nht bn bm theo, chng ta cn hc v
vi iu mi na m song song vi cc thnh phn cng
tn trong UNIX: cc ton t wait, exit v exec.
Ton t n gin nht l exec. N cng ging nh
ton t system, ngoi tr rng thay v dng thc hin tin
trnh mi thc hin ch lnh v, Perl thay th tin
trnh hin ti vi lp v. (Trong cch ni UNIX, Perl
thc hin v). Sau khi ton t exec thc hin thnh cng,
chng trnh Perl kt thc, b thay th bi chng trnh
c yu cu. Chng hn:
exec date ;
thay th chng trnh Perl hin ti bng ch lnh
date, lm cho ci ra ca date chuyn thng ra ci ra
chun ca chng trnh Perl. Khi ch lnh date kt thc,
khng cn g phi thc hin na bi v chng trnh Perl
xong.
Mt cch khc nhn vo iu ny l ch ton t
system ging nh fork c theo sau mt exec, nh sau:

240

# Phng php 1... dng h thng:
system (date) ;
# Phng php 2... dng fork/exec
unless (fork) {
# fork cho khng, cho nn ti l con v ti exec:
exec (date) ; # tin trnh con tr thnh ch lnh date
}
Vic dng fork v exec theo cch ny khng hon
ton phi lm, bi v ch lnh date v tin trnh b m c
hai chy ng thi, c th an cho ci ra v lm mi
s ln ln. iu cn l cch bo cho tin trnh b m
i cho ti khi tin trnh con hon tt. iu c xc
l iu ton t wait thc hin - n i cho ti khi tin
trnh con (bt k con no, cn phi chnh xc) hon
tt:
unless (fork) {
# fork cho khng, cho nn ti l con v ti exec:
exec (date) ; # tin trnh con tr thnh ch lnh date
}
wait ; # b m i cho con (date) hon tt
Nu tt c iu ny dng nh kh m vi bn, bn
c l nn nghin cu cc li gi h thng fork v exec
trong sch UNIX truyn thng, v Perl thng ly kh
trc tip li gi h thng UNIX chuyn sang.
Ton t exit() to nn vic i ra tc khc khi tin
trnh Perl hin ti. Bn dng cch ny b chng
trnh Perl t u gia, hay vi ton t fork thc
hin chng trnh Perl no ang tin hnh v ri ra.
Sau y l mt trng hp ca vic loi b mt s tp
trong /tmp trn nn tng dng mt tin trnh Perl ch ra.
unless (fork) { # Ti l tin trnh con
unkink < /tmp/bedrock.* > ; # ph cc tp ny

241

exit ; # tin trnh con dng thc hin y
}
# Tin trnh b m tip t y
Khng c exit, tin trnh con vn tip tc thc hin
chng trnh Perl (ti dng nh du Tin trnh b m
tip tc y) v dt khot khng phi l iu chng
ta mun.
Ton t exit nhn mt tham bin ph, phc v nh
gi tr ra s m c th c tin trnh b m lu ti.
Gi tr mc nh l cho vic ra vi gi tr khng, ch ra
rng mi th n tho.

Tm tt v cc php ton tin trnh
Bng 14-1 tm tt cc php ton m bn c khi
ng tin trnh.
Bng 14-1 Tm tt v cc php ton tin trnh
Php ton Ci vo
chun
Ci ra
chun
Li
chun
Cn i
khng?
system()

K tha
t
chng
trnh
K tha
t
chng
trnh
K tha
t
chng
trnh
C
xu nhy
n ngc
K tha
t
chng
trnh
c ly
nh gi
tr xu
K tha
t
chng
trnh
C
ch lnh
open() xem
nh tc
hiu tp cho
ci ra
c ni
vi tc
hiu tp
K tha
t
chng
trnh
K tha
t
chng
trnh
Ch vo
lc
close()

242

Php ton Ci vo
chun
Ci ra
chun
Li
chun
Cn i
khng?
ch lnh
open() xem
nh tc
hiu tp cho
ci vo
K tha
t
chng
trnh
c ni
vi tc
hiu tp
K tha
t
chng
trnh
Ch vo
lc
close()
fork, exec,
wait
Ngi
dng la
chn
Ngi
dng la
chn
Ngi
dng la
chn
Ngi
dng la
chn

Vic to tin trnh n gin nht l vi ton t
system. Ci vo, ci ra chun v li chun khng b
nh hng (chng ta c k tha t tin trnh Perl).
Mt xu nhy n ngc to ra mt tin trnh, ly ci ra
chun ca tin trnh ny nh mt gi tr xu cho chng
trnh Perl. Ci vo chun v li chun khng b nh
hng. C hai phng php ny i hi rng tin
trnh ny kt thc trc khi bt k chng trnh Perl no
c thc hin.
Mt cch n gin c tin trnh d b (tin trnh
m cho php chng trnh Perl tip tc trc khi tin
trnh ny c hon tt) l m mt ch lnh nh mt
tc hiu tp, to ra mt ng ng cho ci vo chun
hay ci ra chun ca ch lnh. Mt ch lnh c m nh
tc hiu tp c s k tha ci vo chun v li
chun t chng trnh Perl; mt ch lnh c m nh
mt tc hiu tp ghi s k tha ci ra chun v li
chun t chng trnh Perl.
Cch mm do nht bt u mt tin trnh l
cho chng trnh ca bn gi cc ton t fork, exec v

243

wait, m tng ng trc tip vi cc tn li gi h thng
UNIX. Bng vic dng cc ton t ny, bn c th chn
liu bn c ch i hay khng, v t cu hnh cho ci
vo, ci ra v li chun theo bt k cch no bn chn
*
.

Gi v nhn tn hiu
Mt phng php cho vic truyn thng lin tin
trnh l gi v nhn tn hiu. Tn hiu l thng bo mt
bit (c ngha l tn hiu ny xy ra) c gi cho
mt tin trnh t mt tin trnh khc hoc t li UNIX.
Cc tn hiu c nh s, thng thng t mt ti mt
s nh hn 15 hay 31. Mt s tn hiu c ngha nh
trc v c gi mt cch t ng cho mt tin trnh
di mt iu kin no (nh li b nh hay ngoi l
du phy ng) - mt s khc ring do ngi dng sinh
ra t cc tin trnh khc. Cc tin trnh ny phi c php
gi tn hiu nh vy. Ni chung, nu tin trnh c
cng userID, tn hiu l c php.
Vic p ng cho mt tn hiu c gi l hnh
ng ca tn hiu . Cc tn hiu nh sn c nhng
hnh ng mc nh c ch no , nh b tin trnh hay
cho chy tip. Cc tn hiu khc hon ton b b qua theo
mc nh. Gn nh tt c cc tn hiu c th c hnh
ng mc nh ca n b thay i, hoc l b b qua hoc
b bt gi (gi phn chng trnh do ngi dng xc
nh mt cch t ng).
Cho ti nay, tt c iu ny l cht liu kiu

*
Mc du cng c th c ch l bit v open (STDERR,
>&STDOUT) cho li tc hiu tp.

244

UNIX - ti y n mang theo ngha ring ca Perl. Khi
mt tin trnh Perl bt ly mt tn hiu, mt chng trnh
con do bn chn s c gi mt cch d b v t ng,
tm thi ngt bt k ci g ang c thc hin. Khi
chng trnh con ny ra, bt k ci g ang c thc
hin cng c chy li dng nh khng c g xy
ra c (ngoi tr cc hnh ng c thc hin bi
chng trnh con con ny, nu c).
Mt cch in hnh, chng trnh con bt tn hiu s
thc hin mt trong hai iu: b chng trnh sau khi
thc hin mt s vic dn sch, hoc t c no (nh
bin ton cc) m chng trnh ny n kim tra.
Bn cn bit tn hiu no c t tn ng k
cho b gii quyt tn hiu vi Perl. Bng vic ng k
vi b gii quyt tn hiu, Perl s gi chng trnh con
c la chn khi nhn c tn hiu ny.
Cc tn tn hiu c nh ngha trong ti liu li
gi h thng signal, v thng thng cng c trong tp
bao hn ca C /usr/include/sys/signal.h. Cc tn ni
chung c bt u vi SIG, nh SIGINT, SIGQUIT v
SIGKILL. khai bo chng trnh con
&my_sigint_catcher nh b x l tn hiu gii quyt vi
SIGINT, chng ta t mt gi tr vo trong mng kt
hp %SIG o thut. Trong mng ny, chng ta t mt
gi tr ca kho INT ( l SIGINT khng c SIG) cho
tn ca trnh con m s bt tn hiu SIGINT, kiu nh:
$SIG {INT } = my_sigint_catcher ;
Nhng chng ta cng cn mt nh ngha cho trnh
con . Sau y l mt th d n gin:
sub my_sigint_catcher {

245

$saw_signit = 1 ; # t c
}
B bt tn hiu ny t mt bin ton cc, v ri ra
ngay lp tc. Vic tr v t trnh con ny gy ra vic
thc hin li bt k ch no n b ngt. Mt cch in
hnh, trc ht bn t khng cho c $saw_sigint, t
trnh con ny nh b bt SIGINT, v ri thc hin trnh
bn vn chy, kiu nh:
$saw_sigint = 0 ; # xo c
$SIG {INT } = my_sigint_catcher ; # ng k b bt
foreach (@huge_array) {
# lm iu g
# lm thm vi vic
# vn lm thm vi vic
if ($saw_sigint) { # cn ngt khng?
# dn dp g y
last ;
}
}
$SIG {INT} = DEFAULT ; # khi phc hnh ng mc
nh
Mo y l ch gi tr ca c ny c kim tra
ti nhng im c ch trong khi tnh ton v c dng
ra khi chu trnh khi cha xong, ti y cng gii
quyt mt s hnh ng dn dp. Lu ti cu lnh cui
trong chng trnh trn: t hnh ng DEFAULT khi
phc li hnh ng ngm nh trn mt tn hiu c bit
(SIGINT khc s b chng trnh ny ngay lp tc). Mt
gi tr c ch c bit khc ging th ny l IGNORE, c
ngha l b qua tn hiu ny (nu hnh ng mc nh
khng b qua tn hiu , nh SIGINT). Bn c th lm
mt hnh ng tn hiu IGNORE nu khng cn hnh
ng dn dp no, v bn khng mun kt thc cc php

246

ton sm.
Mt trong nhiu cch tn hiu SIGINT c sinh
ra l bng vic cho ngi dng nhn vo mt k t
ngt chn (nh Delete hay Control-C) trn bn phm.
Nhng mt tin trnh cng c th sinh ra tn hiu
SIGINT trc tip bng vic dng ton t kill. Ton t ny
nhn mt s hiu hay tn tn hiu, v gi tn hiu cho
danh sch cc tin trnh c cho theo tn hiu ny. Cho
nn vic gi mt tn hiu t mt chng trnh i hi
phi xc nh s hiu tin trnh ca cc tin trnh nhn
(s hiu tin trnh c cho li t mt s cc ton t,
nh fork hay vic m mt chng trnh nh mt tc
hiu tp). Gi s bn mun gi mt tn hiu 2 (cng cn
c bit nh SIGINT) cho cc tin trnh c s hiu 234
v 237. n gin hn c l nh th ny:
kill (2, 234, 237) ; # gi SIGINT cho 234 v 237

Bi tp
Xem tr li ph lc A
1. Vit mt chng trnh phn tch ci ra ca ch lnh
date thu c ngy hin ti ca tun. Nu ngy
ca tun l ngy lm vic, in ch lm vic, ngoi ra in
ch i chi.
2. Vit mt chng trnh nhn tt c cc tn thc ca
ngi dng t tp /etc/passwd, ri bin i thnh ci
ra ca ch lnh who, bng vic thay th tn ng nhp
(ct th nht) bi tn tht. (Hng dn: to ra mt
mng kt hp c kho l tn ng nhp v gi tr l

247

tn tht.) Th c hai vi ch lnh who trong trng
hp du nhy n ngc v c m nh ng
ng. Ci no d hn?
3. Sa i chng trnh trn cho ci ra t ng i ra
my in.
4. Gi s hm mkdir() b hng. Vit mt trnh con m
khng dng mkdir(), nhng thay vo gi /bin/mkdir
bng system(). (Phi chc rng n lm vic vi cc
danh mc c mt du cch trong tn.)
5. M rng trnh t bi tp trc s dng chmod()
t php s dng.



248


249


15


Bin i
d liu khc


Tm mt xu con
Tm mt xu con ph thuc vo ni bn mt n. Nu
bn ngu nhin mt n bn trong mt xu ln hn, bn
cn may mn, v index() c th gip bn tm ra. Sau y
l dng v ca n:
$x = index ($string, $substring) ;
Perl nh v ln xut hin u tin ca substring bn
trong string, cho li mt s nguyn ch v tr ca k t u
tin. Gi tr ch s ny c cho li da trn khng - tc
l nu tm c substring ch bt u ca string, bn
nhn c 0. Nu n l mt k t sau , bn nhn
c 1, v c nh th. Nu khng tm thy substring
Trong chng ny:

Tm v thay th
Trch v thay th
xu con
nh dng d liu
dng sprnt()
Sp xp nng cao
Chuyn t


250

trong string, bn nhn c -1.
xem nhng iu sau:
$where = index(hello, e); # $where nhn 1
$oerson = barney;
$where = index(fred barney, $person) ; # $where nhn
5
@rockers = (fred, barney) ;
$where = index(join( , @rockers), $person); # cng th
Ch rng c hai xu ny c tm kim v xu
c tm kim, c th l mt hng xu k hiu, mt bin
v hng c cha mt xu, hay thm ch mt biu thc
c gi tr xu v hng. Sau y l mt s th d na:
$which = index(a very long string, long); # $switch
nhn 7
$which = index(a very long string, lame); # $switch
nhn -1
Nu xu c cha xu con ti nhiu v tr, ton t
index() s cho li v tr bn tri nht. tm ra cc v tr
sau, bn c th cho index() tham bin th ba. Tham bin
ny l gi tr ti thiu m index() s cho li, cho php bn
tm ln xut hin tip ca xu con theo sau mt v tr
chn. N trng ta nh th ny:
$x = index($bigtring, $littlestring, $skip);
Sau y l mt s th d v cch tham bin th ba
lm vic:
$where = index(hello world, l); # cho li 2 (l u tin)
$where = index(hello world, l, 0); # cng th
$where = index(hello world, l, 1); # vn th
$where = index(hello world, l,3); # by gi cho li 3
# (3 l v tr u tin ln hn hay bng 3)
$where = index(hello world, o, 5); # cho li 7 (0 th

251

hai)
$where = index(hello world, o, 8); # cho li -1 (ht sau
8)
i theo li khc, bn c th qut t bn phi c
c s xut hin bn phi nht bng vic dng rindex().
Gi tr cho li vn l s cc k t gia u bn tri ca
xu v ch bt u ca xu con, nh trc, nhng bn s
nhn c s xut hin v bn phi nht thay v s xut
hin bn tri nht nu c nhiu s xut hin. Ton t
rindex() cng nhn tham bin th ba ging nh index() ,
cho bn c th c c s xut hin t hn hay bng
v tr chn. Sau y l mt s th d v iu bn nhn
c:
$w = rindex(hello world, he); # $w nhn 0
$w = rindex(hello world, l); # $w nhn 9 (l bn phi
nht)
$w = rindex(hello world, o); # $w nhn 7
$w = rindex(hello world, o ); # $w nhn 4
$w = rindex(hello world, xx); # $w nhn -1 (khng
thy)
$w = rindex(hello world, o, 6); # $w nhn 4 (u tin
trc 6)
$w = rindex(hello world,o, 3); # $w nhn -1 (khng
thy trc 3)

Trch v thay th mt xu con
Vic ly ra mt mu ca xu c th c thc hin
bng vic p dng cn thn cc biu thc chnh qui,
nhng nu mu ny bao gi cng ti mt v tr k t
bit, vic ny l khng hiu qu. Thay v vy, bn nn
dng substr(). Ton t ny nhn ba i: mt gi tr xu,
mt v tr bt u (c o ta nh n c o cho

252

index()), v mt chiu di, ging nh:
$s = substr ($string, $start, $length);
V tr bt u lm vic ging nh index; k t u
tin l khng, k t th hai l mt, v c th. Chiu di l
s cc k t cn nm ly ti im : chiu di bng
khng c ngha l khng c k t no, bng mt c ngha
l ly k t u tin, bng hai c ngha l hai k t, v
vn vn. (N dng li ti cui xu, cho nn nu bn tm
kim qu nhiu, cng khng sao c.) N trng ging th
ny:
$hello = hello, world!;
$grab = substr($hello, 3, 2); # $grap nhn lo
$grab = substr($hello, 7, 100); # 7 n cui, hay world!
Bn thm ch c th to ra ton t nng ln lu tha
mi cho cc s m nguyn nh, nh trong:
$big = substr(10000000000, 0, $power+1); #
10**$power
Nu s m cc k t l khng hay b hn khng,
mt xu rng s c cho li. Mt khc, nu v tr bt
u l b hn khng, v tr bt u c tnh theo s cc
k t t cui xu. Cho nn gi tr -1 i vi v tr bt u
v 1 (hay nhiu) i vi chiu di s cho bn k t cui.
Tng t, -2 cho v tr bt u vi k t th hai k t
cui. Ging th:
$stuff = substr(a very long string, -3, 3); # ba k t cui
$stuff = substr(a very long string, -3, 1); # k t i
Nu v tr bt u l trc ch m u ca xu
(ging nh mt s m khng l ln hn chiu di ca
xu), ch m u s l v tr bt u (dng nh bn
dng 0 lm v tr bt u). Nu v tr bt u l mt s

253

dng khng l, xu rng bao gi cng c cho li.
Ni cch khc, n c th lm iu bn trng i n phi
lm, chng no bn cn trng i, n bao gi cng cho
li mt ci g khc hn l mt li.
B i i chiu di, cng ht nh bn a mt s
khng l vo cho i - nm ly mi th t v tr
chn cho ti cui xu
*
.
Nu i th nht ca substr() l mt bin (ni cch
khc, n c th xut hin bn v tri ca ton t gn),
bn thn substr() cng c th xut hin v bn tri ca
ton t gn. iu ny trng c v k l nu bn bt
ngun t nn tng C, nhng nu bn chi vi vi d
bn ca BASIC, n hon ton l thng thng.
iu nhn c s thay i nh kt qu ca php
gn nh th l phn ca xu s c cho li, m c
substr() c dng trong mt biu thc. Ni cch khc,
substr($var, 3, 2) cho li k t th t v th nm (bt u
t 3, v s m 2), cho nn vic gn iu lm thay i
hai k t ny cho $var. Ging nh:
$hw = hello world!;
substr($hw, 0, 5) = howdy; # $hw by gi l howdy
world!
Chiu di ca vn bn thay th (ci nhn c vic
gn vo trong substr) khng phi l cng nh vn bn
c thay th, nh trong th d ny. Xu ny s t ng
tng trng hay co li khi cn iu ho vi vn bn.

*
Cc bn Perl c hn khng cho php b i i th ba, dn ti vic
nhng lp trnh vin Perl tin phong dng s khng l cho i
. Bn c th vt qua iu ny trong cuc hnh trnh kho c Perl
ca mnh.

254

Sau y l mt th d v vic xu thnh ngn hn:
substr($hw, 0, 5) = hi; # $hw by gi l hi world!
v y l mt xu thnh di hn:
substr($hw, -6, 5) = worldwide news; # thay th world
Vic co li hay dn ra, kh hiu qu, cho nn bn
ng lo lng v vic dng chng mt cch bt k, mc
du vic thay th mt xu bng mt xu chiu di tng
ng, vn nhanh hn nu bn c c hi.

Dng thc d liu bng sprintf()
Ton t printf i khi cng d s dng khi c dng
ly mt danh sch cc gi tr v to ra mt dng ra
cho hin th cc gi tr theo cch iu khin c.
Ton t sprintf() l ng nht vi printf v cc i, nhng
cho li bt k ci g c printf a ra nh mt xu
ring bit. (Ngh v iu ny nh xu printf.) Chng
hn, to ra mt xu bao gm ch X theo sau bi mt
gi tr nm ch s lp y bi khng ca $y, cng d
dng nh:
$result = sprintf(X%05d, $y);
Nu bn khng quen thuc vi xu dng thc ca
printf v sprintf, tham chiu ti liu printf hay sprintf. (Tn
sprintf, thc ra c ngun gc t trnh th vin cng tn.)

Sp xp nng cao
Trc y, bn bit rng bn c th ly mt danh
sch ri sp xp n theo th t ASCII tng dn (nh cc

255

xu), bng cch dng ton t sort c sn. iu g s xy
ra nu bn khng mun sp xp theo th t ASCII tng
dn, m thay v th l mt ci g khc, kiu nh sp
xp s? c, Perl cho bn cng c bn cn lm vic
ny. Thc ra, bn s thy rng sort ca Perl l hon ton
tng qut v c th thc hin bt k th t sp xp no.
nh ngha vic sp xp theo mu sc khc, bn
cn nh ngha mt trnh so snh m m t cho cch so
snh hai phn t. Ti sao iu ny li cn thit? Th ny,
nu bn ngh v n, sp xp l vic t mt b cc th
theo mt trt t so snh tt c chng vi nhau. V bn
khng th no so snh chng ngay mt lc nn bn cn
so snh hai phn t mi lc, cui cng dng ci bn
pht hin ra v th t cho tng cp m t ton b c l
vo hng.
Trnh so snh c nh ngha nh mt trnh thng
thng. Trnh ny s c gi i gi li, mi ln li
truyn hai phn t ca danh sch cn c sp. Trnh
ny phi xc nh liu gi tr th nht l b hn, bng
hay ln hn gi tr th hai, v cho li mt gi tr m ho
(s c m t ngay sau y). Tin trnh ny c lp li
cho ti khi danh sch c sp hon ton.
tit kim tc thc hin mt cht, hai gi tr
ny khng c truyn trong mng, m thay v th c
trao cho mt trnh con nh gi tr ca bin ton cc $a v
$b. (Bn ng lo - gi tr nguyn thu ca $a v $b c
bo v an ton.) Trnh ny nn cho li mt gi tr m no
nu $a b hn $b, bng khng nu $a bng $b, v
bt k s dng no nu $a ln hn $b. By gi nh,
b hn l tng ng vi ngha ca bn v b hn -
n c th l mt so snh s, tng ng vi k t th ba

256

ca xu, hay thm ch tng ng vi gi tr ca bt k
mng no c dng cc gi tr c truyn vo nh kho.
y mi thc s l mm do.
Sau y l mt th d v mt chng trnh con sp
xp m s sp mi th theo th t s:
sub by_number {
if ($a < $b) {
-1;
} elsif ($a == $b) {
0;
} elsif ($a > $b) {
1;
}
}
ch n tn by_number. Khng c g c bit v
ci tn ca trnh con ny, nhng bn s thy ti sao ti
li thch ci tn bt u bi by_ trong giy lt.
Nhn qua trnh con ny. Nu gi tr ca $a l b hn
(v mt s trong trng hp ny) gi tr ca $b, th cho
li gi tr -1. Nu cc gi tr l bng nhau v con s, cho
li khng, cn ngoi ra cho li 1. Vy, theo m t ca
cho trnh so snh sp xp, iu ny s lm vic.
Lm sao dng c n? Th sp xp danh sch sau.
$somelist = (1,2,4,8,16,32,64,128,256);
Nu dng sort thng thng khng sang sa li danh
sch, s c cc s sp nh chng l cc xu, v theo
trt t ASCII, ta nh:
@wronglist = sort @somelist;
# @wronglist by gi l (1,128,16,2,256,32,64,8)
Chc chn y khng phi l sp xp s. Thi c,

257

s cho sort mt trnh sp xp c nh ngha mi. Tn
ca trnh sp xp i ngay sau t kho sort, nh:
@rightlist = sort by_number @wronglist;
# @rightlist by gi l (1,2,4,8,32,64,128,256)
y qu l mo. Ch rng bn c th c sort vi
trnh con sp xp i km theo kiu con ngi: sp xp
theo s. l l do ti sao ti t tn cho trnh con vi
tin t by_.
Nu bn cng thin v nh th v mun nhn mnh
rng ci i sau sort l mt trnh con, bn c th t trc
n bng mt du v (&), khi Perl s khng bn tm
na, nhng n bit rng ci nm gia t kho sort v
danh sch phi l mt tn trnh con.
Ci loi gi tr ba ng kiu -1, 0, 1 da trn c s so
snh s thng xut hin trong trnh con so snh n
mc Perl c mt ton t c bit lm iu ny trong
mt ln. n thng c gi l ton t tu v tr, v
trng ging <=>. Dng ton t tu v tr ny, trnh con
sp xp trn y c th c thay th bng:
sub by_number {
$a <=> $b;
}
Ch n tu v tr gia hai bin ny. Qu vy, n
thc l ton t di ba k t. Tu v tr cho li cng gi tr
nh dy chuyn if/elsif trong nh ngha trc ca trnh
ny. By gi iu ny l c ngn gn, nhng bn c th
vit tt li gi sp xp thm na, bng vic thay th tn
ca trnh sp xp bng ton b trnh sp xp trong dng,
ging nh:
@rightlist = sort { $a <=> $b } @wronglist;

258

Mt s ngi bin minh rng iu ny lm gim tnh
d c. Mt s khc, li bin minh rng n loi b nhu
cu phi i u tm ra nh ngha. Perl chng quan
tm n iu . Qui tc c nhn ca ti l ch nu n
khng khp trn mt dng hay ti phi dng n nhiu
ln, n nn thnh mt trnh con.
Ton t tu v tr dnh cho so snh s, c ton t
xu so snh gi l cmp. Ton t cmp cho li mt trong ba
gi tr tu theo vic so snh xu tng i ca hai i.
Cho nn, mt cch khc vit trt t mc nh l:
@result = sort { $a cmp $b } @somelist;
C l bn cn cha h vit trnh con ch xc ny
(bt chc sp xp mc nh c sn), chng no bn cn
cha vit mt cun sch v Perl. Tuy th, ton t cmp
vn c ch li ca n, trong vic xy dng cc lc
sp th t theo tng. Chng hn, bn khng cn t cc
phn t theo th t s chng no chng khng bng
nhau v mt s, v trong trng hp chng phi c
sp theo trt t ASCII. (Theo mc nh, trnh by_number
trn s ch dng cho cc xu phi s theo mt trt t ngu
nhin no v khng c trt t s khi so snh hai gi tr
khng.) Sau y l mt cch ni cn so snh theo s,
chng no chng cha bng nhau v s, cn, so snh
theo xu:
sub by_mostly_number {
($a <=> $b) || ($a cmp $b);
}
iu ny lm vic th no? Th ny, nu kt qu ca
tu v tr l -1 hay 1, phn cn li ca biu thc b b
qua, v gi tr -1 hay 1 c cho li. Nu tu v tr tnh

259

ra gi tr khng, ton t cmp tr thnh quan trng, cho li
mt gi tr th t thch hp xem nh gi tr ca xu.
Gi tr c so snh khng nht thit l gi tr c
truyn vo. Chng hn, bn c mt mng kt hp trong
kho l tn ng nhp v cc gi tr l tn tht ca
tng ngi dng. Gi s bn mun in ra mt biu
trong tn ng nhp v tn tht c ct gi theo th
t tn tht. Bn s lm iu nh th no?
Thc ti, vic y kh d dng. Gi s cc gi tr l
trong mng %names. Tn ng nhp vy l danh sch
ca key(%names). iu mun t ti l mt danh sch
cc tn ng nhp c sp theo gi tr tng ng, vy
vi bt k kho ring $a no, cn nhn vo $names{$a}
v sp xp da trn iu . Nu bn ngh v iu ny
theo cch , n gn nh t vit ra ri, nh trong:
@sortedkeys = sort by_names keys(%names);
sub by_names {
$names{$a} cmp $names{$b};
}
foreach (@sortedkeys) {
print $_ c tn tht l $names{$_}\n;
}
Vi iu ny ti cng thm vo mt so snh. Gi
s tn tht ca hai ngi dng l trng nhau. V bn cht
cht ny ra ca trnh sort, ti c th ly mt gi tr ny
trc gi tr kia ln u tin ri cc gi tr theo th t
o li cho ln sau. iu ny khng tt nu bo co c
th c np vo chng trnh so snh cho vic bo co,
cho nn ti phi rt c gng trnh nhng th nh vy.
Vi ton t cmp, tht d dng:

260

sub by_names {
($names{$a} cmp $names{$b}) || ($a cmp $b);
}
Ti y, nu tn thc l ging nhau, ti sp xp da
trn tn ng nhp. V tn ng nhp c m bo l
duy nht (sau rt, chng l cc kho ca mng kt hp
ny, v khng c hai kho no l nh nhau), nn ti c
th m bo mt trt t duy nht v lp li c. Vic
lp trnh phng ng tt trong nhng ngy ny, tt hn l
mt c in thoi gi m ca thao tc vin hi lm
sao tt i ci bo ng.

Chuyn t
Khi bn mun ly mt xu v thay th mi th
nghim ca mt k t no bng mt k t mi, hay
xo mi th nghim ca mt k t no , bn c th
lm iu vi vic chn la cn thn ch lnh s///.
Nhng gi s bn phi thay i tt c cc a thnh b v tt
c cc b thnh a, sao? Bn khng th lm iu vi hai
ch lnh s/// v ch lnh th hai s hon tc li tt c
nhng thay i do ch lnh th nht thc hin.
Tuy nhin t v, mt php chuyn i d liu nh
vy l n gin - ch cn dng ch lnh tr chun:
tr ab ba < inda >outdata
(Nu bn khng bit g v ch lnh tr, xin xem ti
liu - l mt cng c c ch cho ti cc mo ca bn.)
Tng t, Perl cung cp mt ton t tr lm vic rt ging
nh th:
tr/ab/ba/;

261

Ton t tr nhn hai i : xu c v xu mi. Cc i
ny lm vic ging nh hai i ca s///: ni cch khc, c
mt nh bin no xut hin ngay sau t kho tr lm
tch bit v kt thc hai i (trong trng hp ny, mt
s cho, nhng gn nh k t no cng c).
Cc i cho ton t tr ging ht nh cc i ca ch
lnh tr. Ton t tr sa i ni dung ca bin $_ (ging
nh s///), tm cc k t ca xu c bn trong bin $_. Tt
c cc k t nh th c tm thy c thay th bng
k t tng ng trong xu mi. Sau y l mt s th d:
$_ = fred and barney;
tr/fb/bf/; # $_ by gi l bred and farney
tr/abcde/ABCDE/; # $_ by gi l BrED AnD fArnEy
tr/a-z/A-Z/; # $_ by gi l BRED AND FARNEY
Lu n phm vi cc k t c th c ch ra bng
hai k t c phn cch bi s cho. Nu bn cn mt
s cho hng k t trong xu, t trc n mt s cho
ngc.
Nu xu mi ngn hn xu c, k t cui cng ca
xu mi s c lp li s ln lm cho cc xu c
chiu di nh nhau, ging nh:
$_ = fred and barney;
tr/a-z/ABCDE/d; # $_ by gi l ED AD BAE
Lu n cch thc mi ch sau e bin mt v
khng c k t tng ng trong danh sch mi v rng
cc du cch khng b tc ng v chng khng xut
hin trong danh sch c. iu ny l tng t vi thao
tc ca tu chn -d ca ch lnh tr.
Nu danh sch mi l rng v nu khng c tu
chn d, danh sch mi l ging ht danh sch c. iu

262

ny c v hi ngu, v ti sao phi thay th I cho I v 2
cho 2, nhng thc t, n cng lm i iu ch li y.
Gi tr cho li ca ton t tr/// l s cc k t c snh
theo xu c, v bng vic thay i cc k t trong chnh
chng, bn c th nhn c s cc loi k t bn
trong xu. Chng hn:
$_ = fred and barney;
$count = tr/a-z//; # $_ khng thay i nhng $count l 13
$count2 = tr/a-z/A-Z/; # $_ l ch hoa cn $count2 l 13
Nu bn thm c vo cui (ging nh vit thm d),
iu c ngha l lm y xu c i vi tt c 256
k t. Bt k k t no bn lit k trong xu c b loi
b khi tp tt c cc k t c th; cc k t cn li, c
ly theo dy t thp n cao, t xu c. Vy, mt cch
m hay thay i cc k t phi s trong xu ca chng
c th l:
$_ = fred and barney;
$count = tr/a-z//c; # $_ khng i, nhng $count l 2
tr/a-z/_/c; # $_ by gi l fred_and_barney (phi ch =>
_)
tr/a-z//cd; # $_ by gi l fredandbarney (xo k t khc
ch)
Ch rng cc tu chn c th c t hp, nh
c trnh by trong th d cui, ni chng trc ht b
sung cho tp hp (danh sch cc ch tr thnh danh sch
ca tt c cc phi ch) ri dng tu chn d xo bt k
k t no trong tp .
Tu chn cui cng cho tr/// l s, m s lm cng li
nhiu bn sao lin tip ca cng ch c dch vo
mt bn sao. Xem nh mt th d nhn vo iu ny:
$_ = aaabbcccdefghi;

263

tr/defghi/abcdd/s; # $_ by gi l aaabbcccabcd
Ch rng def tr thnh abc, cn ghi (m ng tr
thnh ddd nu khng c tu chn s) li tr thnh mt d.
Bn cng rng cc ch lin tip ti phn u ca
xu, khng b ng cng li v chng khng l kt qu
ca vic dch. Sau y l thm mt s th d na:
$_ = fred and barney, wilma and betty;
tr/a-z/X/s; # $_ by gi l X X X, X X X
$_ = fred and barney, wilma and betty;
tr/a-z/_/cs; # $_ by gi l
fred_and_barney_wilma_and_betty
Trong th d th nht, mi t (ch lin tip) b
ng cng li ch mt ch X. Trong th d th hai, tt c
chm cc phi ch lin tip tr thnh du gch thp duy
nht.
Ging nh s///, ton t tr c th hng ch vo mt
xu khc bn cnh $_ bng vic dng ton t =~:
$name = fred and barney;
$name =~ tr/aeiou/X/; # $name by gi l frXd Xnd
bXrnXy

Bi tp
Xem Ph lc A v li gii
1. Vit mt chng trnh c mt danh sch tn tp,
b mi tn thnh phn u v ui. (Mi th cho ti
du s cho cui cng l u, cn mi th sau du
s cho cui cng l ui. Nu khng c s cho, n
tt c l ui.) th vi nhng th nh /fred, barney

264

v fred/barney. Kt qu c ngha g khng?
2. Vit mt chng trnh c vo mt danh sch cc
s ri sp xp chng theo th t s, in ra danh sch
kt qu theo ct thng l phi.
3. Vit mt chng trnh in ra cc tn thc v tn ng
nhp ca ngi dng trong tp /etc/passwd, c sp
theo tn cui ca tng ngi dng. Gii php ca
bn c lm vic nu hai ngi c cng tn cui
khng?
4. To ra mt tp bao gm cc cu, mi cu mt dng.
Vit mt chng trnh lm cho mi k t u cu tr
thnh ch hoa, cn phn cn li ca cu thnh ch
thng. (Liu n c lm vic c khi k t u tin
khng phi l mt ch khng? Bn lm iu ny th
no nu cu khng trn mt dng?)









265


16


Truy nhp
c s d liu h thng


Ly mt hiu v thng tin nhm
Thng tin m h thng gi v tn ngi dng v
userID l kh cng cng. Thc ra, gn mi th nhng
mt hiu mt m ri, c sn cho vic nghin cu k
hn cho bt k chng trnh no dm qut vo tp
/etc/password. Tp ny c dng thc c bit - c xc
nh trong passwd(5), c dng ging nh th ny:
name:passwd:uid:gid:gcos:dir:shell
Cc trng c nh ngha nh sau:
name Tn ng nhp ca ngi dng
passwd Mt hiu mt m ho
Trong chng ny:

Ly mt hiu v
thng tin nhm
ng v m gi
d liu nh phn
Ly thng tin
mng
Ly thng tin
khc


266

uid S hiu uerID (0 cho root, khc khng
cho ngi dng bnh thng)
gid Nhm ng nhp mc nh (nhm 0 c
th c quyn ring, nhng khng nht
thit)
gcos Trng GCOS, in hnh c cha tn y
ca ngi dng, tip theo l du
phy v thng tin no khc
dir Danh mc nh (ni bn ti khi bn g cd
khng c i, v ni phn ln cc tp
chm ca bn c lu gi
shell Lp v ng nhp ca bn, in hnh l
/bin/dh hay /bin/csh (hay c th
/usr/bin/perl nu bn l ngi qui chiu)
Phn in hnh ca tp mt hiu trng ging th ny:
fred:*:123:15:Fred Flintstone, , , :/home/fred:/bin/csh
barney:*:125:15:Barney
Rubble, , , :/home/barney:/bin/csh
By gi, Perl cng c nhn dng loi dng ny
mt cch d dng (bng vic dng split, chng hn), m
khng a ra mt trnh chuyn dng no. Nhng th
vin lp trnh UNIX li c mt tp cc trnh c bit:
getpwent, getpwuid, getpwnam, vn vn. Nhng trnh
ny l c sn trong Perl bng vic dng cng tn v i
tng t v cho li cc gi tr.
Chng hn, trnh getpwnam() tr thnh ton t
getpwnam() ca Perl. i duy nht l tn ngi dng
(nh fred hay barney) v gi tr cho li l dng
/etc/passwd chia ra thnh mt mng vi cc gi tr sau:

267

($name, $passwd, $uid, $gid, #quota, $comment, $gcos,
$dir, $shell)
Lu rng c thm vi gi tr na y so vi tp
mt hiu. Trng $quote bao gi cng trng, v trng
$comment v $gcos c hai cha ton b trng GCOS
(du sao, cng trn mi h thng UNIX ti chi). Cho
nn, vi anh bn c freud, bn c:
(fred, *, 123, 16, , Fred Flintstone,,,, Fred
Flintstone,,,, /home/fred, /bin/csh)
bng vic gi mt trong hai li gi sau:
getpwuid(123)
getpwnam(fred)
Ch rng getpwwui() nhn s hiu UID, trong khi
getpwman() nhn tn ng nhp lm i ca n.
Bn c l mun ly phn ny ra, dng mt s php
ton danh sch m chng thy trc y. Mt cch l
ly mt phn ca danh sch ny bng vic dng mt lt
ct mng, nh ly danh mc nh cho Fred, dng:
($fred_home) = (getpwnam(fred)) [7] ; # t nh ca
Fred
Bn c th qut qua ton b tp mt hiu nh th
no? c, bn c th lm iu g nh:
foreach $i (1..10000) {
@stuff = getpwui($i) ;
} ### khng khuyn co!
Nhng y c l l cch lm sai. Ch bi v c nhiu
cch lm iu khng c ngha l tt c cc cch
m chc nh nhau.
Bn c th ngh v cc ton t getpwuid() v

268

getpwnam() nh vic truy nhp ngu nhin - chng ly
mt phn t c bit theo kho, cho nn bn phi c mt
kho bt u. Mt cch khc truy nhp vo tp mt
hiu l truy nhp tun t - nm ly mi phn t theo mt
trt t ngu nhin no
Cc trnh truy nhp ngu nhin vo tp mt hiu l
cc ton t setpwent(), getpwent(), v endpwent(). Cng
nhau, ba ton t ny to thnh vic chuyn tun t tt c
cc gi tr trong tp mt hiu. Ton t setpwent() khi
u vic qut t u. Sau khi khi u, mi li gi ti
getpwent() cho li phn t tip trong tp mt hiu. Khi
khng cn d liu x l, trnh getpwent() cho li danh
sch rng. Cui cng, vic gi endpwent() gii phng ti
nguyn do ni qut s dng - iu ny c thc hin
mt cch t ng khi ra khi chng trnh.
M t ny cn th d, cho nn y l mt th d:
setpwent ; # khi u vic qut
while (@list = getpwent) { # ly phn t tip
($login, $home) = @list[0, 7] ; # ly tn ng nhp v
nh
print Danh mc nh cho $login l $home\n ;
}
endpwent; # lm xong tt
Mnh th d ny ch ra danh mc nh cho mi ngi
trong tp mt hiu. Gi s bn mun sp xp chng theo
trt t ch ci, sao? c, chng ta hc v sort trong
chng trc, cho nn dng n:
setpwent ; # khi u vic qut
while (@list = getpwent) { # ly phn t tip
($login, $home) = @list[0, 7] ; # ly tn ng nhp v
nh
$home{$login} = $home; # ct n i

269

}
endpwent ; # lm xong tt
@keys = sort { $home{$a} cmp $home{$b} } key %home;
foreach $login (@keys) { # bc qua cc tn sp xp
print nh ca $login l $home{$login}\n ;
}
on chng trnh ny, trong khi di hn cht t, li
minh ho cho mt vn quan trng v qut tun t qua
tp mt hiu - bn c th ct gi cc phn thch hp ca
d liu trong cu trc d liu bn chn. Phn th nht
ca th d ny qut qua ton b tp mt hiu, to ra mt
mng kt hp vi kho l tn ng nhp v gi tr l
danh mc nh tng ng cho tn ng nhp . Dng
sort ly kho ca mng v sp xp chng tng ng vi
xu gi tr. Chu trnh cui cng bc qua cc kho
sp xp, ln lt in ra tng gi tr.
Ni chung, bn nn dng cc trnh truy nhp ngu
nhin (getpwuid() v getpwnam() ) khi bn tm ch vi
gi tr. Vi vic tm kim vi gi tr hay thm ch tm
kim vt cn, ni chung bc truy nhp tun t (dng
setpwent(), getpwent(), v endpwent()) v trch cc gi
tr c bit m bn tm a vo mng kt hp, d
dng hn.
Tp /etc/group c truy nhp theo cch tng t.
Vic truy nhp tun t c cung cp bng cc li gi
setgrent(), getgrent() v endgrrent(). Li gi getgrent() cho
li gi tr c dng:
($name, $passwd, $gid, $member)
Bn gi tr ny tng ng ng vi bn trng ca
tp /etc/group cho nn xem cc m t trong ti liu tham
chiu v dng thc tp ny v chi tit. Cc hm truy

270

nhp ngu nhin tng ng l getgrgid() (theo ID nhm)
v getgrnam() (theo tn nhm).

Gi v m d liu nh phn
Mt hiu v thng tin nhm c biu din kh p
theo dng vn bn. Cc c s d liu h thng khc c
biu din t nhin hn di cc dng khc. Chng hn,
a ch IP ca mt giao din c qun l ni b nh mt
s bn byte. Trong khi n thng c gii m thnh
biu din vn bn bao gm bn s nguyn nh tch nhau
bi du chm, vic m ho v gii m ny li l n lc b
ph phm nu con ngi trong khi y khng din gii d
liu ny.
Bi iu ny, cc trnh mng trong Perl m c trng
i hay tr li mt a ch IP thng dng xu bn byte
c cha mt k t ch tng byte tun t trong b nh.
Trong khi vic xy dng v din gii xu byte nh vy l
kh trc tip bng vic dng sprintf() v ord() (khng
c trnh by y), Perl cung cp mt li tt c th p
dng c tng ng cho nhiu cu trc kh hn.
Ton t pack() lm vic c i cht nh sprintf(),
nhn mt xu iu khin dng thc v mt danh sch cc
gi tr, ri to ra mt xu t nhng gi tr ny. Tuy nhin
xu dng thc pack c khp vi vic to ra mt cu
trc d liu nh phn. Chng hn, ly bn s nguyn
nh v gi chng theo bn byte lin tip trong mt xu
hp thnh:
$buf = pack (CCCC, 140, 186, 65, 25) ;

271

Ti y, xu dng thc pack l bn C. Mi C biu th
cho mt gi tr tch bit c ly t danh sch sau
(tng t nh ci m mt trng % thc hin trong
sprintf). Dng thc C (tng ng vi ti liu Perl, ba
tham chiu, Sch con lc , tp texinfo, hay thm ch
cun Perl: The Motion Picture) ni ti mt byte c
tnh t mt gi tr k t khng du (mt s nguyn nh).
Xu kt qu trong $buf l xu bn k t - tng k t l
mt byte c cc gi tr 140, 186, 65 v 25.
Tng t, dng thc gi l sinh ra mt gi tr di c
du. Trn nhiu my, y l mt s bn byte, mc du
dng thc ny l ph thuc my. Trn my di bn
byte, cu lnh,
$buf = pack (1, 0x41424344) ;
sinh ra mt xu bn k t trng nh hoc ABCD
hoc DCBA, tu theo liu my kt thc u cui b
hay u cui ln (hay mt ci g hon ton khc nu
my khng ni theo ASCII). iu ny xy ra bi v
chng ang gi mt gi tr vo thnh bn k t (chiu di
ca s nguyn di), v mt gi tr ngu nhin c hp
thnh t cc byte biu th cho cc gi tr ASCII cho bn
ch ci u tin trong bng ch. Tng t:
$buf = pack ( 11, 0x41424344, 0x45464748) ;
tp ra mt xu tm byte bao gm ABCDEFGH hay
DCBAHGFE, mt ln na ty thuc vo liu my l kt
thc u cui b hay u cui ln.
Danh sch chnh xc cho cc loi dng thc gi
khc nhau c cho trong ti liu tham chiu (ti liu
ngn ng Perl, hay sch con lc , hay bt k sch no
bn ang dng hc v cc vin ngc khc ca Perl).

272

Bn s thy vi th d y, nhng ti khng nh lp
danh sch cho chng.
iu g xy ra nu bn c cho mt xu tm byte
ABCDEFGH v c bo rng n thc s l nh b nh
(mt k t l mt byte) ca hai gi tr di c du (bn
byte)? Bn s din gii n th no? No, bn cn lm
ngc li pack(), gi l unpack(). Ton t ny ly mt xu
iu khin dng thc (thng ng nht vi xu iu
khin dng thc m bn cho trong pack()) v mt xu
d liu, ri cho li mt danh sch cc gi tr to nn nh
b nh c xc nh trong xu d liu. Chng hn, ly
xu t:
($val1, $val2) = unpack (11, abcdefgh) ;
iu ny cho li ci g ta nh 0x61626364 cho
$val1 hay c th 0x64636261 (tu theo u cui ln hay
b). Thc ra, vi gi tr cho li, chng c th xc nh
liu chng trn my u cui b hay ln.
Khong trng trong xu iu khin dng thc b b
qua, v c th c dng lm tng tnh d c. Mt
s trong xu iu khin dng thc ni chung lp li c
t trc nhiu ln. Chng hn, CCCC cng c th
c vit l C4 hay C2C2 m khng lm thay i
ngha. (Mt vi c t dng s i sau nh mt phn ca
c t, v do vy khng th c xem li bi nh th
ny.)
Mt k t dng thc cng c th c php c theo
sau l du *, m s lm gp bi k t dng thc theo
s ln nut ht phn cn li ca danh sch hay phn
cn li ca xu nh nh phn (tu theo liu bn ang gi
li hay m gi). Do , mt cch khc gi bn k t

273

khng du thnh mt xu l:
$buf = pack (C*, 140, 186, 65,25) ;
Bn gi tr y c nut ht bi mt c t dng
thc. Nu bn mun hai s nguyn ngn theo sau bi
nhiu nht cc k t khng du c th c, bn c th
ni iu g nh:
$buf = pack ( s2 C*, 3241, 5826, 5, 3 , 5, 8, 9, 7, 9, 3,
2) ;
Ti y, chng ly hai gi tr u l s nguyn ngn
(c th sinh ra bn hay tm k t) v chn gi tr cn li
l cc k t khng du (sinh ra chn k t, gn nh chc
chn).
i theo chiu hng khc, unpack vi c t du sao
c th sinh ra mt danh sch cc phn t vi chiu di
khng xc nh. Chng hn, m gi vi C* to ra mt
phn t danh sch (mt s) cho tng k xu. Do , cu
lnh ny:
@values = unpack (C*, hello, world!\n) ;
cho mt danh sch 14 phn t, mi phn t l mt k
t trong xu ny.

Ly thng tin mng
Perl h tr cho vic lp trnh mng theo mt cch rt
quen thuc vi nhng ngi vit chng trnh mng
trong chng trnh C. Thc ra, phn ln cc trnh Perl
cung cp vic truy nhp mng c cng tn v cc
tham bin tng t nh chng trnh C tng ng.

274

Chng ti khng th dy mt gio trnh y v lp
trnh mng trong chng ny, nhng chng ta ly ci
nhn vo mt trong nhng on nhim v xem liu
n c thc hin nh th no trong Perl.
Mt trong nhng iu bn cn tm ra l a ch i
cng vi tn, hay ngc li. Trong C, bn dng trnh
gethostbyname() chuyn mt tn mng thnh a ch
mng. Th ri bn dng a ch ny to ra mt mi
ni t chng trnh ca bn ti chng trnh khc u
.
Trnh Perl dch mt tn my ch thnh a ch c
cng tn v cc tham bin tng t nh trnh C, v trng
nh th ny:
($name, $aliases, $addrtype, $length, @addrs) =
gethostbyname($name) ; # dng tng qut ca
gethostbyname
Tham bin cho trnh ny l tn my ch - chng hn
slate.bedrock.com. Gi tr cho li l mt danh sch bn
hay nhiu tham bin, tu thuc vo bao nhiu a ch
c lin kt vi tn ny. Nu tn my ch khng hp
l, trnh ny cho li danh sch rng.
Khi gethostbyname() thc hin thnh cng, $name l
tn chnh tc, khc vi tn ci vo nu tn ci vo l mt
bit hiu. $aliases l danh sch cc tn cch nhau bng
du cch m qua bit ti my ch. $addrtype cho li
gi tr m ho ch ra dng ca a ch. Trong trng
hp ny, vi slate.bedrock.com, chng ta c th gi thit
trc rng gi tr ny ch ra mt a ch IP, thng thng
c biu th nh bn s di 256, cch nhau bi du
chm. $length cho s cc a ch, thc t l thng tin tha

275

v du sao bn c th nhn vo chiu di ca @addrs.
Nhng phn c ch ca gi tr cho li l @addrs. Mi
phn t ca mng l mt a ch IP tch bit, c ct
gi trong mt dng thc bn trong, c gii quyt trong
Perl nh mt xu bn k t. Trong khi xu bn k t ny
ch xc l ci m cc hm mng Perl khc tm kim, gi
s mun in ra kt qu cho ngi dng xem. Trong
trng hp ny, chng ta cn chuyn i gi tr cho li
thnh mt dng thc ngi c c vi s tr gip ca
hm unpack() v vic truyn thng bo ph. Sau y l
mt on chng trnh in ra mt trong cc a ch IP ca
slate.bedrock.com:
($addr) = (gethostbyname(slate.bedrock.com) ) [4] ;
print a ch ca slate l ,
join (., unpack(C4, $addr)), \n ;
npack() nhn bn k t v cho li bn s. iu ny
xy ra theo th t bn phi join() gn cc du chm
vo gia tng cp s lm thnh dng ngi c c.

Ly cc thng tin khc
Ging nh trnh gethostbyname(), bn cng c th
ly thng tin v my ch theo a ch, v thng tin mng
theo c tn v a ch. Cng c cc trnh truy nhp
vo cc danh sch giao thc mng v danh sch dch v.
Cc trnh ny tt c lm vic tng t nh cch chng
lm vic trong chng trnh C.
Xem Ph lc B v cc th d vic dng cc trnh ny
trong ng dng thc.

276


Bi tp
Xem cu tr li Ph lc A.
1. Vit mt chng trnh to ra bng tng ng userID
v tn thc t cc mt hiu, ri dng nh x
cho hin ra danh sch cc tn thc thuc v tng
nhm trong tp nhm. (Danh sch ca bn c cha
nhng ngi dng, ngi c nhm mc nh trong
mt hiu nhng khng ni tng minh v cng nhm
trong nhm, ng khng? Nu khng, lm sao
bn hon thnh c iu ?

277


17

Thao tc
c s d liu
ngi dng


C s d liu DBM v mng DBM
Phn ln cc h thng UNIX c mt th vin
chun gi l DBM. Th vin ny cung cp mt tin nghi
qun tr c s d liu n gin cho php cc chng
trnh c ct gi mt tuyn tp cc cp kho-gi tr
trong mt cp tp a. Nhng tp ny duy tr cc gi tr
trong c s d liu gia nhng ln gi chng trnh c
dng c s d liu v nhng chng trnh ny c th b
sung cc gi tr mi, cp nht cc gi tr hin c, hay xo
cc gi tr c.
Th vin DBM, kh n gin, nhng li sn c, mt
s chng trnh h thng dng n cho nhng nhu cu
Trong chng ny:

C s d liu
DBM v mng
DBM
M v ng
mng DBM
Dng mng DBM
C s d liu
truy nhp ngu
nhin chiu di
c nh
C s d liu
(vn bn) chiu
di bin i


278

kh gin d ca chng. Chng hn, chng trnh gi th
Berkeley (v cc bin th cng suy dn ca n) ct gi
c s d liu bit hiu (nh x ca a ch th vo ni
nhn) nh mt c s d liu DBM. Phn mm tin Usenet
ph bin nht cng dng c s d liu DBM gi du
vt cc bi bo hin ti v mi xem gn y.
Perl cung cp vic truy nhp vo cng c ch DBM
ny thng qua mt phng tin cn thng minh hn:
mng kt hp c th c kt hp vi c s d liu
DBM qua mt tin trnh tng t nh m mt tp. Mng
kt hp ny (cn gi l mng DBM) vy ri c dng
truy nhp v sa i c s d liu DBM. Vic to ra
mt phn t mi trong mng ny lm thay i ngay lp
tc c s d liu DBM. Vic xo mt phn t s xo gi
tr khi c s d liu DBM. V c nh th.
Kch c, s lng v loi kho cng gi tr trong c
s d liu DBM, c hn ch, v mt mng DBM c cng
nhng hn ch . xem lidbm v chi tit. Ni chung, nu
bn gi c kho v gi tr xung khong 1000 k t bt k
hay t hn, c l l OK.

M v ng mng DBM
kt hp mt c s d liu DBM vi mt mng
DBM, dng ton t dbmopen() , trng nh th ny:
dbmopen(%ARRAYNAME, dbmfilename, $mode);
Tham bin %ARRAYNAME l mt mng kt hp
ca Perl. (Nu mng ny c gi tr, cc gi tr b b
i.) Mng kt hp ny tr thnh c ni vi c s d
liu DBM c tn dbmfilename, thng thng c ct

279

gi trn a nh mt cp tp c tn dbmfilenam.dir v
dbmfilename.pag. Bt k tn mng kt hp hp php no
cng c th dng c, mc du cc tn mng ch
ton ch hoa, c dng in hnh do s tng t vi
tc hiu tp.
Tham bin $mode l mt s kim sot cc bit cho
php ca cp tp ny nu cc tp cn c to ra. Con
s ny in hnh c xc nh theo h tm: gi tr
thng hay dng nht l 0644 cho php mi ngi ch
c, cn ring ngi ch, c php c-ghi. Nu cc tp
ny tn ti, tham bin ny khng c tc dng. Chng
hn:
dbmopen(%FRED, mydatabase, 0644); # m %FRED
ln mydatabase
Li gi ny kt hp mng kt hp %FRED vi cc
tp a mydatabase.dir v mydatabase.pag trong danh
mc hin ti. Nu cc tp ny cha tn ti, chng c
to ra vi mt 0644.
Gi tr cho li t dbmopen() l ng nu c s d
liu c th m c hay to ra c, v l sai trong
trng hp ngc li, ht nh vic gi open(). Nu bn
khng mun cc tp ny c to ra, dng gi tr $mode
ca undef. Chng hn:
dbmode (%A, /etc/xx, undef) || die khng m c
DBM /etc/xx;
Trong trng hp ny, nu tp /etc/xx.dir v
/etc/xx.pag khng th m c, li gi dbmopen() s cho
li sai, thay v c gng to ra cc tp ny.
Mng DBM vn cn m trong sut lc thc hin
chng trnh. Khi chng trnh kt thc, s kt hp s

280

kt thc. Bn cng c th ph v s kt hp theo cch
thc tng t nh vic ng tc hiu tp, bng vic
dng ton t dbmclose():
dbmclose(%A);
Ging nh close(), dbmclose() cho li sai nu iu g
i sai.

Dng mng DBM
Mt khi c s d liu c m, cc tham chiu
ti mng DBM s c nh x vo cc tham chiu c s
d liu. Vic thay i hay b sung gi tr vo mng ny
to ra cho cc mc tng ng lp tc c ghi vo tp
a. Chng hn, mt khi %FRED c m trong th d
trc, c th thm vo, xo b hay truy nhp vo c s
d liu, ging nh th ny:
$FRED{fred} = bedrok; # to ra (cp nht) mt phn
t
delete $FRED{barney); # b mt phn t ca csdl
foreach $key (keys %FRED) { # i qua mi gi tr
print $key c gi tr ca $FRED{$key}\n;
}
Chu trnh cui phi qut qua ton b tp a hai ln:
mt ln truy nhp vo kho, v ln th hai tra cu
cc gi tr t kho. Nu chng ta qut qua mt mng
DBM, ni chung s hiu qu v a hn l dng ton t
each(), ch qua mt bc:
while ( ($key, $value) = each (%FRED)) {
print $key c gi tr ca $value\n;
}
Nu bn ang truy nhp vo c s d liu DBM h

281

thng, nh cc c s d liu c to ra bi sendmail
hay tin Usenet, bn phi bit rng cc chng trnh ni
chung gn thm ci ui k t NUL (\0) vo cui
ca cc xu ny. Cc trnh th vin DBM khng cn ci
NUL ny (chng gii quyt d liu nh phn bng cch
m byte ch khng phi l xu kt thc bng NUL), v
do vy NUL c ct gi nh mt phn ca d liu. Do
bn phi gn k t NUL vo cui d liu ca mnh v
b NUL khi cui ca gi tr cho li cho d liu c
ngha. Chng hn, tra cu merlyn trong c s d liu
bit hiu, th mt iu g kiu:
dbmopen(%ALI, /etc/aliases, undef) || die Khng bit
hiu?;
$value = $ALI{merlyb\0}; # lu NUL c thmvo
chop($value); #loi b NUL c thm vo
print Th ca Randal c gn u cho: $value\n; # in
kt qu
Bn UNIX ca bn c th a c s d liu bit
hiu vo /usr/lib thay v /etc. Bn phi lc li tm ra.

C s d liu truy nhp ngu nhin chiu di c nh
Mt dng khc ca d liu bn vng l cc tp a
hng bn ghi vi chiu di c nh. Trong lc ny,
d liu bao gm mt s cc bn ghi vi chiu di nh
nhau. Vic nh s cho cc bn ghi, khng quan trng
hay c xc nh bi mt lc nh ch s no .
Chng hn, chng ta c th c mt lot cc bn ghi
m trong d liu c 40 k t ca h, mt k t tn
m, 40 k t tn, v ri mt s nguyn hai byte cho tui.
Mi bn ghi vy l c chiu di 83 byte. Nu c tt c

282

d liu trong c s d liu, phi c tng chm 83 byte
cho ti khi n cui. Nu mun i ti bn ghi th nm,
phi nhy qua 4 ln 83 byte (332 byte) v c trc tip
bn ghi th nm.
Perl h tr cho cc chng trnh dng kiu tp a
nh th. C i iu cn bit thm bn cnh nhng iu
bn bit:
1. M tp a cho c c v ghi
2. Chuyn quanh tp ny ti mt v tr bt k
3. Ly d liu theo di thay v theo dng mi tip
4. Ghi d liu ln theo cc khi chiu di c nh
Ton t open() nhn mt du cng b sung trc c
t hng vo/ra ch ra rng tp thc s c m cho
c c v ghi. Chng hn:
open(A, +<b); # m tp b c/ghi (li nu khng c tp)
open(C, +>d); # to ra tp d, vi truy nhp c/ghi
open(E, +>>f); # m hay to tp f vi vic truy nhp
c/ghi
Lu rng tt c nhng iu lm mi ch l b
sung thm du cng vo hng vo/ra.
Mt khi thu c vic m tp, cn di chuyn
quanh n. Bn lm iu ny vi ton t seek(), cng
nhn cng ba tham bin nh trnh th vin fseek(). Tham
bin th nht l tc hiu tp; tham bin th hai l cho
khong chnh, c din gii i km vi tham bin th
ba. Thng thng, bn mun tham bin th ba l khng
cho tham bin th hai chn c v tr tuyt i cho
ln c tip hay ghi tip ln tp. Chng hn, i ti bn

283

ghi th nm trn tc hiu tp NAMES (nh c m t
trn), bn c th lm iu ny:
seek(NAMES, 4*83, 0);
Mt khi con tr tp c nh v li, vic a vo
hay a ra tip s bt u t . Vi vic a ra, dng
ton t print. nhng phi chc chn rng d liu bn vit
l ng chiu di. thu c ng chiu di, chng ta
c th gi ti ton t pack():
print NAMES pack(A4040s, $first, $middle, $last,
$age);
B xc nh pack() cho 49 k t i vi $first, mt
k t cho $middle, 40 k t na cho $last v s nguyn
ngn (2 byte) cho $age. iu ny tnh thnh 83 byte
chiu di, v s ghi ti v tr tp hin ti .
Cui cng, chng ta cn ly ra mt bn ghi c bit.
Mc du ton t <NAMES> cho li tt c d liu t v tr
hin ti cho ti dng mi tip, iu li khng ng;
d liu c gi thit l ch tri trn 83 k t v c th li
khng c dng mi ng ch. Thay v th, dng ton
t read(), trng v cch lm vic, ht nh li gi h thng
UNIX tng ng:
$count = read(NAMES, $buf, 83);
Tham bin th nht ca read() l tc hiu tp.
Tham bin th hai l bin v hng gi d liu s c
c. Tham bin th ba cho s byte cn c. Gi tr cho
li t read() l s byte thc t c - in hnh l cng
s byte c yu cu tr phi tc hiu tp khng c
m hay bn qu gn ti cui tp.
Mt khi bn c d liu 83 k t, ch cn cht n

284

ra thnh cc thnh phn bng ton t unpac():
($first, $middle, $last, $age) = unpack(A40A40s, $buf);
L rng cc xu dng thc cho pack v unpack l
nh nhau. Phn ln cc chng trnh ct gi xu ny
trong mt bin t u trong chng trnh, v thm ch
cn tnh chiu di ca bn ghi bng vic dng pack() thay
v b ri rc cc hng 83 mi ni:
$names = A40AA40s;
$names_length = length(pack($names)) ; # c th l 83

C s d liu (vn bn) chiu di thay i
Nhiu c s d liu h thng (v c l phn ln c
s d liu do ngi dng to ra) l cc chui dng
vn bn con ngi c c,vi mt bn ghi trn mi
dng. Chng hn, tp mt hiu cha mt dng cho mi
ngi trn h thng, v tp my ch cha mt dng cho
mi tn my ch.
Rt thng l nhng c s d liu ny c cp
nht bng cc trnh son tho vn bn n gin. Vic cp
nht mt c s d liu nh vy bao gm vic c n tt
c vo mt vng trung gian (hoc trong b nh hoc trn
a khc), thc hin nhng thay i cn thit, ri hoc
ghi kt qu ngc tr li tp nguyn thu hoc to ra
mt tp mi vi cng tn sau khi xo hay i tn bn
c. Bn c th coi vic ny nh bc sao chp - d liu
c sao t c s d liu nguyn gc sang mt bn mi
ca c s d liu y, tin hnh thay i trong khi sao
chp.
Perl h tr cho vic son tho kiu sao chp ny trn

285

cc c s d liu hng dng bng cch dng vic son
tho ti ch. Son tho ti ch l vic sa i cch thc
ton t hnh thoi (<>) c d liu t mt danh sch cc
tp c xc nh trong dng lnh. Thng thng nht,
mt son tho ny c truy nhp ti bng vic t i
dng lnh -i, nhng chng ta cng c th t ly cho mt
son tho ti ch t bn trong mt chng trnh, nh
c biu th trong th d sau y.
t ly cho mt son tho ti ch, t mt gi tr
vo trong bin v hng $^I. Gi tr ca bin ny l quan
trng, v s c tho lun ngay y.
Khi ton t hnh thoi c s dng v $^I c mt gi
tr (thay v undef), cc bc c nh du ##INPLACE##
trong on m sau y s c thm vo danh sch cc
hnh ng ngm nh m ton t hnh thoi nhn:
$ARGV = shift @ARGV;
open(ARGV, <$ARGV);
rename($ARGV, $ARGV$^I); ## INLACE ##
unlink($ARGV); ## INPLACE ##
open(ARGVOUT, >$ARGV); ## INPLACE ##
select(ARGVOUT) ; ## INPLACE ##
Hiu qu l ch vic c t ton t hnh thoi ly t
tp c, cn vic ghi ln tc hiu tp ngm nh, li
chuyn sang mt bn sao mi ca tp ny. Tp c vn
cn trong tp d phng, m chnh l tc hiu tp vi
phn hu t bng gi tr ca bin $^I. (Cng c mt cht
o thut sao chp cc bit ngi ch v php dng t
tp c sang tp mi.) Nhng bc ny c lp li mi
ln mt tp mi c rt ra t mng @ARGV.
Cc gi tr in hnh cho $^I l nhng ci nh .bak
hay ~, to ra cc tp d phng rt ging vi trnh son

286

tho to ra. Mt gi tr k l nhng c ch cho $^I l xu
rng, , ci gy ra vic tp c b xo sch sau khi vic
son tho hon tt. iu khng may l nu h thng hay
chng trnh b hng trong khi thc hin chng trnh
bn, bn s mt tt c d liu c, cho nn chng ti ch
khuyn co iu ny cho nhng ngi bo dn, di dt
hay tin cy.
Sau y l cch thay i vic ng nhp ca ai
vo /bin/sh bng cch sa i tp mt hiu:
@ARGV = (/etc/passwd); # nhi vo ton t hnh thoi
$^I = .bak; # ghi /etc/passwd.bak an ton
while (<>) { # chu trnh chnh, mi ln cho mt dng ca
/etc/passwd
s#L[^;]*$#:/bin/sh#; # i v thnh /bin/sh
print; # gi ra ARGVOUT: bn mi /etc/passwd
}
Nh bn c th thy, chng trnh ny kh n gin.
Thc ra, cng chng trnh ny c th c sinh ra ton
b vi mt vi i dng lnh nh
perl -p -i.bak -e s#:[^:] *$#:/bin/sh# /etc/passwd
Chuyn mch -p ng ngoc nhn chng trnh bn
vi chu trnh while c cha mt cu lnh print. Chuyn
mch -i t mt gi tr vo trong bin $^I. Chuyn mch -
e xc nh ra i sau y nh mt phn ca chng trnh
Perl i vi thn chu trnh; v i cui cng cho gi tr
khi u cho @ARGV.
Cc i dng lnh c tho lun rt chi tit trong
sch con lc v Perl.


287

Bi tp
Xem Ph lc A v li gii
1. To ra mt chng trnh m c s d liu
sendmail v in ra tt c cc mc.
2. To ra hai chng trnh: mt c d liu hnh thoi,
cht n ra thnh cc t, ri cp nht mt tp DBM c
ghi s ln xut hin ca tng t; v chng trnh kia,
m tp DBN v cho hin th kt qu c sp xp
theo s m gim dn. Chy chng trnh th nht
trn vi tp ri xem liu chng trnh th hai c nht
ra s m ng khng.


288




289


18

Chuyn i
cc ngn ng khc
sang Perl


Chuyn chng trnh awk sang Perl
Mt trong nhiu iu d chu v Perl l ch n l
(t nht) siu tp ng ngha ca awk. Theo ngn ng thc
hnh, iu ny c ngha l nu bn c th lm iu g
trong awk, bn cng c th lm iu bng cch no
trong Perl. Tuy nhin, Perl khng tng thch v c
php vi awk. Chng hn, bin NR (s bn ghi vo) ca
awk c biu din l $. trong Perl.
Nu bn c mt chng trnh awk c sn v mun
n chy vi Perl, bn c th thc hin vic phin dch
my mc bng vic dng tin ch a2p c cung cp
cng vi Perl. Tin ch ny chuyn c php awk thnh c
php Perl, v vi i a s chng trnh awk, n cho
Trong chng ny:
Chuyn i
chng trnh awk
sang Perl
Chuyn i
chng trnh sed
sang Perl
Chuyn i
chng trnh
Shell sang Perl

290

ra mt bn Perl c th chy c trc tip.
dng tin ch a2p, t chng trnh awk ca bn
vo mt tp tch bit, v gi a2p vi tn ca tp ny nh
i ca n, hay hng li ci vo chun ca a2p cho tp
ny. Ci ra chun kt qu s l mt chng trnh Perl
hp l. Chng hn:
$ cat myawkprog
BEGIN { sum = 0 }
/ llama / { sum += $2 }
END { print The llama count is sum }
$ a2p < myawkprog > myperlprog
$ perl myperlprog somefile
The llama count is 15
$
Bn cng c th np ci ra chun ca a2p trc tip
vo trong Perl, bi v trnh thng dch Perl c th chp
nhn mt chng trnh trn ci vo chun nu c ch
th:
$ a2p < myawkprog | perl - somefile
The llama count is 15
$
Mt bn awk c chuyn sang Perl ni chung s
thc hin chc nng ng nht, thng vi vic tng
thm v tc , v chc chn khng c gii hn c sn
no ca awk v chiu di dng hay s m tham bin
hay bt k ci g. Mt vi chng trnh Perl chuyn
i thc t c th chy chm hn - hnh ng tng
ng trong Perl i vi mt thao tc awk cho c th
khng nht thit l chng trnh Perl hiu qu nht nu
so vi vic lp trnh t u.
Bn c th chn ti u th cng cho chng trnh

291

Perl chuyn i, hay thm chc nng mi vo bn
Perl ca chng trnh ny. iu ny kh d dng, bi v
chng trnh Perl, d c hn (xem xt rng vic dch l
t ng, iu ny hon ton thc hin c.)
Mt vi bn dch, vn khng c gii ho. Chng
hn, php so snh b hn cho c hai s v xu trong awk
c biu din bng ton t <. Trong Perl, bn c lt
cho xu v < cho s. awk ni chung d on c l v tnh
cht s hay xu ca hai gi tr c so snh, cn tin ch
a2p ch on n gin. Tuy nhin, c th l khng bit
v hai gi tr xc nh liu php so snh s hay xu
c m bo, cho nn a2p a ra ton t c th nht v
nh du kh nng dng li bng #?? (ch thch ca
Perl) v mt gii thch. Phi chc duyt qua ci ra cho
nhng li ch thch nh vy sau khi chuyn i kim
chng li vic on c ng khng.
V chi tit hot ng ca a2p, xin xem ti liu.
Nu a2p khng c trong cng danh mc m bn ly
Perl, hi ngi ci t Perl ca bn.

Chuyn i chng trnh sed sang Perl
c, iu ny c th bt u c v nh s lp li,
nhng th on xem ci g... Perl l mt siu tp ng
ngha ca sed cng nh awk.
V i km vi Perl l trnh dch sed sang Perl gi l
s2p. Nh vi a2p, s2p nhn mt bn vit ca sed trn ci
vo chun v ghi ra mt chng trnh Perl trn ci ra
chun. Khng ging a2p, chng trnh c chuyn
i him khi hnh x sai, cho nn bn c th tin cy hn

292

vo vic n lm vic, chn li trong s2p hay Perl.
Chng trnh sed chuyn i c th lm vic
nhanh hn hay chm hn bn gc, nhng ni chung l
nhanh hn nhiu (nh c cc trnh biu thc chnh qui
ti u ca Perl).
Bn ghi sed chuyn i c th lm vic vi hay
khng c tu chn -n, mang cng ngha nh kho
tng ng cho sed. lm iu ny, bn ghi chuyn
i phi t np n vo trong b tin x l C, v iu ny
lm chm li vic bt u mt cht t. Nu bn bit rng
bn bao gi cng s gi ti bn ghi sed chuyn i d
c hay khng tu chn -n (nh khi bn ang chuyn bn
ghi sed c dng trong chng trnh v ln hn vi cc
i bit), bn c th thng bo s2p (qua cc kho -s
v -p), v n s ti u bn ghi cho vic thit t kho .
Xem nh mt th d v vic Perl linh hot v mnh
m n u, trnh dch s2p c vit trong Perl. Nu bn
mun thy cch Larry lp trnh trong Perl (cho d l
vic lp trnh rt c in gn nh khng thay i t bn
Perl 2), nhn vo trnh dch ny. Phi chc l bn ang
ngi xung xem.

Chuyn i chng trnh Shell sang Perl
No. Bn c ngh l c b dch shell sang Perl
khng?
Khng. Nhiu ngi hi iu nh th, nhng vn
thc li l ch phn ln nhng iu m bn ghi lp
v shell thc hin, li khng c shell thc hin. Phn
ln cc bn ghi shell thc ra dnh tt c thi gian

293

trong vic gi cc chng trnh tch bit trch ra cc
mu ca xu, so snh s, ni cc tp, xo danh mc, c
nh vy. Vic chuyn i mt bn ghi nh vy sang Perl
hoc s i hi vic hiu v s vn hnh ca tng tin
ch c gi, hoc b li cho Perl gi tng tin ch ny,
m chng thu c g.
Cho nn, cch tt nht m bn c th lm l nhn
vo bn ghi lp v, hnh dung ra n lm g, v bt u t
u vi Perl. Tt nhin, bn c th lm vic chuyn t
nhanh v bn, bng vic t nhng phn chnh ca bn
ghi gc vo bn trong cc li gi system() hoc du nhy
n ngc. Bn cng c th thay th mt s trong cc
php ton ny bng Perl t nhin: chng hn, thay th
system(rm fred) bng unlink(fred), hay mt chu trnh for
ca lp v bng chu trnh for ca Perl. Nhng ni chung,
bn s thy n c mt cht ging vic chuyn chng
trnh COBOL vo C (vi cng vic gim bt s k t v
tng tnh kh c).

Bi tp
Xem tr li Ph lc A.
1. Chuyn bn ghi lp v sau y thnh chng trnh
Perl:
cat /etc/passwd |
awk -F : {print $1, $6 } |
while read user home
do
newsrc=$home/ .newsrc
if [ -r $newsrc ]
then

294

if grep -s ^comp\.lang\.perl: $newsrc
then
echo $user is a good person, and read
comp.lang.perl!
fi
fi
done


295


Ph lc A

Tr li cc bi tp

Ph lc ny nu cu tr li cho cc bi tp c cho
cui mi chng.

Chng 2, D liu v hng
1. Sau y l mt cch thc hin n:
$pi = 3.141592654;
$result = 2 * $pi * 12.5;
print radius 12.5 is circumference $resultn ;
Trc ht cho mt gi tr hng () cho bin v
hng $pi. Tip tnh chu vi bng vic dng gi tr ny
ca $pi trong biu thc. Cui cng in ra kt qu bng
cch dng mt xu c cha mt tham chiu ti kt qu

2. Sau y l mt cch thc hin n:
print What is the radius: ;
chop ($radius = <STDIN>) ;
$pi = 3.141592654;

296

$result = 2 * $pi * $radius ;
print radius $radius is circumference $resultn ;
iu ny tng t vi bi tp trc, nhng y
chng ta hi ngi cho chy chng trnh ny v mt gi
tr, dng cu lnh print nhc, ri dng ton t
<STDIN> c mt dng t thit b cui.
Nu chng ta b chop() i, c du dng mi
gia xu hin th ti cui. iu quan trng l phi b du
dng mi sm nht c th c.

3. Sau y l mt cch thc hin n:
print First number: ; chop ($a = <STDIN>) ;
print Second number: ; chop ($b = <STDIN>) ;
$c = $a * $b ; print answer is $c.\n ;
Dng th nht lm ba vic: nhc bn bng mt
thng bo, c mt dng t ci vo chun, ri b i du
dng mi khng trnh khi ti cui xu. Lu rng v
chng ta ang dng bin ca $a hon ton l s nn c
th b chop() y, v 45\n l 45 khi c dng theo kiu
s. Tuy nhin, vic lp trnh bt cn nh th c th quay
li m nh chng ta v sau (chng hn, nu chng ta a
$a vo trong thng bo).
Dng th hai lm cng iu cho s th hai v t n
vo trong bin v hng $b.
Dng th ba nhn hai s vi nhau v in ra kt qu.
Lu du dng mi ti cui xu y, tng phn vi
vic thiu n hai dng u. Hai thng bo u l li
nhc, m vi n ci vo ca ngi dng cn c t
trn cng dng. Thng bo cui ny l cu lnh y ;

297

nu chng ta b du dng mi ra khi xu, li nhc ca
lp v s xut hin ngay sau thng bo ny. Khng hay
lm.

3. Sau y l mt cch thc hin n:
print String: ; $a = <STDIN> ;
print Number of times: ; chop ($b = <STDIN>) ;
$c = $a * $b ; print The result is: \n$c ;
Ging nh th d trc, hai dng u hi, v nhn,
cc gi tr cho hai bin. Khng ging bi tp trc,
chng ta khng vt du dng mi ti cui xu, bi v cn
n! Dng th ba ly hai gi tr a vo v thc hin vic
lp li xu trn chng, ri hin th cu tr li. Lu rng
vic xen ln $c l khng cho php du dng mi, bi v
chng ta tin rng $c bao gi cng s kt thc trong mt
du dng mi theo bt k cch no.

Chng 3, Mng v d liu danh sch
1. Mt cch thc hin iu ny l:
print Enter the list of strings:\n ;
@list = <STDIN> ;
@reverselist = reverse (@list) ;
print @reverselist ;
Dng u tin nhc cc xu. Dng th hai c xu
vo mt bin mng. Dng th ba tnh danh sch theo th
t ngc, ct gi n vo trong mt bin khc, v dng
cui cng hin th kt qu.
Thc t chng ta c th t hp ba dng cui, kt qu
l:

298

print Enter the list of strings:\n ;
print reverse (<STDIN>) ;
iu ny lm vic bi v php ton print trng i
mt danh sch, cn reverse() cho li mt danh sch - cho
nn chng ho hp. V reverse() cn mt danh sch cc
gi tr o ngc, cn <STDIN> trong hon cnh
mng, cho li mt danh sch cc dng, cho nn chng
cng hp na!

2. Mt cch thc hin iu ny l:
print Enter the line number: ; chop ($a = <STDIN>) ;
print Enter the lines, end with ^D:\n; $b = <STDIN> ;
print Answer: $b[$a-1] ;
Dng th nht nhc mt s, c n t ci vo chun,
v b du dng mi phin phc. Dng th hai hi mt
danh dch cc xu, ri dng ton t <STDIN> trong
hon cnh mng c tt c cc dng cho ti cui tp
vo trong mt bin mng. Cu lnh cui cng in ra cu
tr li, bng vic dng mt tham chiu mng chn ra
ng dng. Lu rng chng ta khng phi thm du
dng mi vo cui xu ny, bi v dng ny c chn
t mng @b vn c kt thc l du dng mi.
Nu bn th iu ny t mt thit b cui c lp
cu hnh theo cch thng thng nht, bn s cn g
Control-D ti bn phm ch ra cui tp.

3. Mt cch thc hin iu ny l:
srand;
print List of strings: ; $b = <STDIN> ;

299

print Answer: $b[rand(@b)] ;
Dng th nht khi u cho b sinh s ngu nhin.
Dng th hai c mt lot cc xu. Dng th ba chn
mt phn t ngu nhin t lot cc xu v in n ra.

Chng 4, Cu trc iu khin
1. Sau y l mt cch thc hin n:
print What temperature is it? ;
chop ($temperature = <STDIN>) ;
if ($temperature > 72) {
print Too hot!\n ;
} else {
print Too cold!\n ;
}
Dng u tin nhc bn v nhit . Dng th hai
chp nhn nhit lm ci vo. Cu lnh if trn dng th
5 chn mt trong hai thng bo in ra, tu theo gi tr
ca $temperature.

2. Sau y l mt cch thc hin n:
print What temperature is it? ;
chop ($temperature = <STDIN>) ;
if ($temperature > 75) {
print Too hot!\n ;
} elsif ($temperature < 68) {
print Too cold!\n ;
} else {
print Just right!\n ;
}
Ti y chng ta sa chng trnh ny bao

300

gm vic chn la ba ng. Trc ht, nhit c so
snh vi 75, ri 68. Lu rng ch mt trong ba s chn
la ny s c thc hin mi ln qua chng trnh ny.

3. Sau y l mt cch thc hin n:
print Enter a number (999 to quit): ;
chop ($n = <STDIN>) ;
while ($n != 999) {
$sum += $n ;
print Enter another number (999 to quit): ;
chop ($n = <STDIN>) ;
}
print The sum is $sum\n ;
Dng th nht nhc cho s th nht. Dng th hai
c s t thit b cui. Chu trnh while tip tc thc hin
chng no m s ny cha ln hn 999.
Ton t += tch lu cc s vo trong bin $sum. Lu
rng gi tr khi u ca $sum l undef, mt gi tr hay
cho b tch lu bi v gi tr th nht c cng vo s l
cng vi 0 (nh rng undef c dng nh s l khng.)
Bn trong chu trnh ny, chng ta phi nhc v nhn
mt s khc, cho php kim th ti nh ca chu trnh
li l mt s mi c a vo.
Khi chu trnh c i ra, chng trnh s in kt qu
tch lu.
Lu rng nu bn a vo 999 ngay, gi tr ca
$sum s khc khng, nhng l mt xu rng - gi tr ca
undef khi c dng nh mt xu. Nu bn mun m
bo rng chng trnh in ra khng trong trng hp ny,
bn nn khi u gi tr ca $sum u chng trnh vi

301

$sum = 0.

4. Sau y l mt cch thc hin n:
print Enter some strings, end with ^D:\n;
$strings = <STDIN> ;
while ($strings) {
print pop(@strings) ;
}
Trc ht chng trnh ny yu cu cc xu. Cc
xu ny c ct gi trong bin mng @strings, mi xu
mt phn t.
Biu thc iu khin ca chu trnh while l @strings.
Biu thc iu khin ang tm mt gi tr (true hay
false), v do tnh biu thc ny trong hon cnh v
hng. Tn ca mng (nh @strings) khi c dng
trong hon cnh v hng l s cc phn t hin ang
trong mng. Chng no m mng cn khng rng, s
ny l khc khng, v do ng. iu ny l rt thng
dng trong khu ng Perl lm iu ny khi mng khc
rng.
Thn ca chu trnh in ra mt gi tr, thu c bi
vic ly ra phn t bn phi nht ca mng. Do vy, mi
ln qua chu trnh, mng li ngn bt i mt phn t, bi
v phn t c in ra.
Bn c th xt vic dng ch s cho vn ny. Nh
chng ti ni, c nhiu cch thc hin n. Tuy nhin,
bn him khi thy ch s trong cc chng trnh Perl
thc s bi v gn nh bao gi cng c cch khc tt
hn.

302


5. Sau y l mt cch thc hin n khng dng danh
sch:
for ($number = 0 ; $number <= 32 ; $number++) {
$square = $number * $number ;
print %5g %8g\n , $number, $square;
}
V y l cch thc hin n dng danh sch
foreach $number (0..32) {
$square = $number * $number;
printf %5g %8g\n, $number, $square ;
Cc gii php ny c hai cha chu trnh, bng
vic dng cc cu lnh for v foreach. Thn ca cc chu
trnh ny l nh nhau, bi v vi c hai gii php, gi tr
ca $number t 0 ti 32 cho mi ln lp.
Gii php th nht dng cu lnh for kiu C truyn
thng. Ba biu thc tng ng: t $number l 0, kim
tra xem liu $number c b hn 32 hay khng, v tng
$number sau mi ln lp.
Gii php th hai dng cu lnh foreach ta lp v
C. Danh sch 33 phn t (0 ti 32) c to ra, bng
vic dng cu t danh sch. Bin $number vy c t
ln lt cho mi phn t.

Chng 5, Mng kt hp
1. Sau y l mt cch thc hin n:
%map = (red, apple, green, leaves, blue, ocean) ;
print A string please: ; chop ($some_string =
<STDIN>) ;

303

print The value for $some_string
$map{$some_string}\n;
Dng th nht to ra mng kt hp, cho n cp
kho-gi tr mong mun. Dng th hai ly mt xu, loi
b du dng mi phin phc. Dng th ba in ra gi tr
a vo v gi tr c nh x ca n.
Bn cng c th to ra mng kt hp qua mt lot
cc php gn tch bit, kiu nh:
$map {red} = apple ;
$map {green} = leaves ;
$map {blue} = ocean ;

2. Sau y l mt cch thc hin n:
@words = <STDIN> ; # read the words
foreach $word (@words) {
chop ($words) ; # remove that pesky newline
$count {$word} = $count {$word} + 1 ; # or $count
{$word}++
}
foreach $word (keys %count) {
print $word was seen $count {$word} times\n ;
}
Dng u tin c cc dng vo mng @words. nh
rng iu ny s lm cho tng dng kt thc nh mt
phn t tch bit ca mng, vi k t dng mi vn
khng b ng n.
Bn dng tip bc qua mng, t $word ln lt
bng mi dng. Du dng mi c b i bng chop(),
v ri iu o thut xy ra. Mi t c dng nh mt
kho trong mng kt hp. Gi tr ca phn t c chn
bi kho ny (word) l s m s ln chng ta thy t

304

cho ti lc . Khi u, khng c phn t no trong
mng c, cho nn nu t wild c thy ln u tin,
chng ta c $count {wild}, vn l undef. Gi tr undef
cng vi mt tr thnh khng cng mt, hay mt. (Nh
rng undef trng ging nh khng nu c dng nh
s.) Ln tip chy qua, chng ta cng thm mt, hay hai
vn vn.
Mt cch thng thng khc vit vic tng ln
c cho trong phn ch thch. Ngi lp trnh Perl
thnh tho c khuynh hng li nhc (chng ta gi
iu l c ng), v s khng bao gi i vit tham
chiu cng mng kt hp c hai v ca php gn khi
mt php t tng n gin cng lm c iu .
Sau khi cc t c m xong, vi dng cui
bc qua mng kt hp bng cch nhn vo tng kho
ca n mi lc. Kho v gi tr tng ng c in ra sau
khi c xen ln vo trong xu.
Cu tr li thch thc ph thm trng nh cu tr li
ny, vi ton t sort c chn ngay trc t keys trn
dng th ba k t cui. Khng sp xp, ci ra kt qu
dng nh l ngu nhin v khng th on ni. Tuy
nhin, mt khi c sp xp, ci ra l d on c
v nht qun. (Ring c nhn ti, ti th dng ton t
keys m khng thm sp xp vo ngay lp tc trc n -
iu ny m bo rng vic cho chy li trn cng d
liu hay d liu tng t s sinh ra kt qu so snh
c.)


305

Chng 6, Vo/ra c s
1. Sau y l mt cch thc hin n:
print reverse <> ;
Bn c th ngc nhin s vn tt ca cu tr li
ny, nhng iu ny s lm cho mi vic c thc hin.
y l iu vn xy ra, t bn trong ra:
Trc ht, ton t reverse tm danh sch cc i ca
n. iu ny c ngha l ton t hnh thoi (<>) c tnh
trong hon cnh mng. Vy, tt c cc dng ca cc tp
c tn trong i dng lnh (hoc ci vo chun, nu
khng tp no c nu tn) c c vo, v c
nho nn thnh danh sch vi mi dng mt phn t.
Tip ton t reverse o ngc danh sch t u
n sang u kia.
Cui cng ton t print to ra danh sch kt qu, v
hin th n.

2. Sau y l mt cch thc hin n:
print List of strings:\n ;
chop (@strings = <STDIN>) ;
foreach (@strings) {
printf %20s\n, $_ ;
}
Dng u tin nhc danh sch cc xu.
Dng tip c tt c cc xu vo mt mng, v b
du dng mi ti cui mi dng.
Chu trnh foreach bc qua mng ny, cho $_ gi tr
ca mi dng.

306

Ton t printf nhn hai i: i th nht xc nh
dng thc - %20s\n c ngha l ct dn phi 20 k t,
tip sau l dng mi.

3. Sau y l mt cch thc hin n:
print Chiu rng trng: ;
chop ($width = <STDIN>) ;
print List of strings:\n ;
chop(@strings = <STDIN>) ;
foreach (@strings) {
prnt %$ {width}s\n, $_ ;
}
T li gii ca bi tp trc, chng ta thm li
nhc v p ng cho chiu rng trng.
Vic thay i khc l ch xu dng thc cho printf
by gi c cha mt tham chiu bin. Gi tr ca $width
c a vo bn trong xu trc khi printf xem xt dng
thc ny. Lu rng chng ta khng th vit xu ny
nh:
printf %$width\n, $_ ; # sai
v th, Perl s tm mt bin c tn l $widths, khng
phi l bin c tn $width m gn cho s. Cch khc
vit iu ny l:
printf %$width.s\n, $_ ; # ng
bi v vic kt thc ca xu ny cng s kt thc tn
bin, bo v k t sau khi b ht ht vo tn.


307

Chng 7, Biu thc chnh qui
1. Sau y l mt s cu tr li c th
(a) /a+b*/
(b) /\\*\**/ (Nh rng du s cho ngc ph nh
ngha ca k t c bit i sau.)
(c) / ($whatver) {3} / (Bn phi c du ngoc trn,
hoc nu khng, php nhn s p dng vo k t
cui ca $whatever; iu ny cng sai nu
$whatever c k t c bit.)
(d) / [\000-\377] {5} / hay / (.| \n) {5} / (Bn khng th
dng chm mt mnh y, bi v chm khng
snh vi du dng mi.)
(e) / (^| \s) (\S+) (\s+\2)+/ (\S l khng khong trng,
cn \2 l tham chiu ti bt k ci g m t c
th l; du m hay thay th khong trng m
bo rng \S+ bt u ti bin khong trng.)

2. (a) Mt cch thc hin iu ny l:
while (<STDIN>) {
if (/a/i && /e/i && /i/i && /o/i && /u/i) {
print ;
}
}
Ti y, chng ta c mt biu thc bao gm nm
ton t i snh. Cc ton t ny tt c nhm vo ni
dung ca bin $_, m l ni biu thc iu khin ca chu
trnh while t vo tng dng. Ton t i snh s ng
ch khi tm thy tt c nm nguyn m.

308

Lu rng ngay khi khng tm thy bt k mt trong
nm nguyn m ny, phn cn li ca biu thc ny b
b qua, bi v ton t && khng tnh i dng ca n
nu i bn tri sai.
(b) Mt cch lm iu ny l:
while (<STDIN>) {
if (/a,*e.*i.*o.*u/i) {
print ;
}
}
Cu tr li ny tr nn d dng hn phn khc ca
bi tp ny. Ti y chng ta c mt biu thc chnh qui
n gin, tm nm nguyn m tun t, tc nhau bi mt
s du cch.

3. Mt cch thc hin iu ny l:
while (<STDIN>) {
($user, $pass, $uid, $gid, $gcos) = split(/:/) ;
($real) = split (/,/,$gcos);
print $user is $real\n ;
}
Chu trnh while ngoi c mt dng mi lc t tp
dng thc mt hiu, vo trong bin $_, kt thc khi
khng cn dng no c c vo.
Dng th nht ca thn chu trnh while chia phn
dng ny ra theo du hai chm, ct gi nm gi tr u
vo cc bin v hng ring vi tn c ngha.
Trng GCOS (trng th nm) c cht ra theo
du phy, vi danh sch kt qu c gn cho mt bin
v hng n c bao trong ngoc trn. Cc ngoc trn

309

ny l quan trng: chng ta lm cho php gn ny thnh
php gn mng, thay v l php gn logic. Bin v hng
$real nhn phn t u ca danh sch v cc phn t cn
li l c b qua.

4. Mt cch thc hin iu ny l:
while (<STDIN>) {
($user, $pass, $uid, $gid, $gcos) = split(/:/) ;
($real) = split (/,/,$gcos);
($first) = split(/\s+/, $real) ;
$seen {$first}++;
}
foreach (key %seen) {
if ($seen {$_} > 1) {
print $_ was seen $seen {$_} times\n ;
}
}
Chu trnh while lm vic kh ging vi cho trnh
while trong bi tp trc. Bn cnh vic cht dng ny ra
thnh cc trng v trng GCOS thnh tn thc (v cc
phn khc), chu trnh ny cng cht tn thc thnh tn
u (v phn cn li). Mt khi tn u c bit ti,
phn t mng kt hp trong %seen c tng ln, lu
rng chng thy mt tn u tin c bit. Lu rng
chu trnh ny khng lm vic in no.
Chu trnh foreach bc qua tt c cc kho
ca %seen (cc tn u ly t tp mt hiu), gn cho mi
kho ln lt vo trong $_. Nu gi tr ny c ct gi
trong %seen ti mt kho cho m ln hn mt, chng
ta thy ci tn u ny nhiu ln. Cu lnh if kim th
iu ny, v in ra thng bo nu cn.

310


5. Mt cch thc hin iu ny l:
while (<STDIN>) {
($user, $pass, $uid, $gid, $gcos) = split(/:/) ;
($real) = split (/,/,$gcos);
($first) = split(/\s+/, $real) ;
$name {$first} .= $user ;
}
foreach (key %seen) {
if ($seen {$_} =~ /. /) {
print $_ is used by: $seen {$_} times\n ;
}
}
Chng trnh ny ging nh cu tr li bi tp
trc, nhng thay v n thun ct gi s m, chng ta
gn thm tn ng nhp ca ngi dng vo phn
t %names m c kho cho tn u. Vy vi Fred Rogers
(ng nhp mrrogers), $names {Fred} tr thnh
mrrogers, v khi Fred Flintstone (ng nhp fred) ti,
c $names {Fred} l mrrogers fred. Sau khi chu
trnh ny hon tt, chng ta c mt bng tng ng tt c
cc tn u cho tt c nhng ngi dng c chng ta.
Chu trnh foreach, ging nh cu tr li ca bi tp
trc, s bc qua mng kt hp kt qu. Tuy nhin,
thay v kim th mt gi tr phn t mng kt hp vi
mt s ln hn mt, by gi chng ta phi xem liu c
nhiu tn ng nhp theo gi tr ny khng. Chng ta
lm iu ny bi vic ct gi gi tr ny vo trong bin
v hng $names (ly tn ging %names cho tin) v
xem liu gi tr ny c du cch theo sau bt k k t no
khng. Nu c, tn u s c dng chung, v thng
bo kt qu cho bit ng nhp no s dng chung tn

311

.

Chng 8, Hm
1. Sau y l mt cch thc hin n
sub card {
@card_map =
(0, one, two, three, four,
five, six, seven, eight, nine) ;
local ($num) = @_ ;
if ($card_map[$num]) {
$card_map[$num] ; # return value
} else {
$num ; # return value
}
}
# driver routine:
while (<>) {
chop ;
print card of $_ is , &card($_), \n ;
}
Trnh &card (tn nh vy v n cho li mt tn s
lng vi mt gi tr cho) bt u bng vic khi u
mt mng hng gi l @card_map. Mng ny c cc gi
tr sao cho $card_map[6] l six, lm cho n kh d thc
hin nh x ny.
Cu lnh if xc nh liu gi tr ny c trong phm vi
hay khng bng vic nhn vo s trong mng - nu c
mt phn t mng tng ng, php th l ng, sao cho
phn t mng c cho li. Nu khng c phn t no
tng ng (nh khi $num l 11 hay -4, gi tr cho li t
vic tra bng l undef , cho nn nhnh else ca cu lnh if
c thc hin, cho li s gc. Bn cng c th thay th

312

ton b cu lnh if vi mt biu thc:
$card_map {$num} || $num ;
Nu gi tr v bn tri ca || l ng, n l gi tr ca
ton b biu thc, m s c cho li. Nu n l sai (nh
khi $num ngoi phm vi), v phi ca ton t || c
tnh, cho li $num xem nh gi tr cho li.
Trnh iu khin nhn cc dng lin tip, ct b du
dng mi ca chng ta v mi lc trao chng cho trnh
&card, in ra kt qu.

2. Sau y l mt cch thc hin n:
sub card { ... ; } # from previous problem
print Enter first number: ;
chop ($first = <STDIN>) ;
print Enter second number: ;
chop ($second = <STDIN>) ;
$message = &card($first) . plus .
&card($second) . equals .
&card($first+$second) . .\n ;
$message =~ s/^./\u$&/ ;
print $message ;
Hai cu lnh print th nht nhc a vo hai s, tip
ngay sau l hai cu lnh c cc gi tr vo $first v
$second.
Mt xu c tn $message c xy dng nn bng
vic gi &card ba ln, mi ln cho mt gi tr, v mt ln
cho tng.
Khi thng bo ny c xy dng, k t th nht
ca n c vit hoa ln bng ton t s cho ngc \u.
Thng bo ny tip c in ra. Bn c th t hp hai

313

cu lnh cui l:
print \u$message ;
Nhng khng may l bn khng th t hp cch xy
dng thng bo ny vi vic lm thnh ch hoa cho k t
u tin mt cch d dng.

3. Sau y l mt cch thc hin n:
sub card {
@card_map =
(0, one, two, three, four,
five, six, seven, eight, nine) ;
local ($num) = @_ ;
if ($num < 0) {
$negative = negative ;
$num = - $num ;
}
if ($card_map[$num]) {
$negative . $card_map[$num] ; #
return value
} else {
$negative . $num ; # return value
}
}
Ti y chng ta cho mng @card_map mt tn cho
s khng.
Hai cu lnh if u tin i du ca $num, v t
$negative thnh t ph nh, nu s tm c l b hn
khng. Sau cu lnh if ny, gi tr ca $num, bao gi
cng khc khng, nhng chng ta s c mt xu tin t
thch hp trong $negative.
Cu lnh if th hai xc nh liu $num (by gi

314

dng) c bn trong mng hay khng. Nu c, mng kt
qu c gn thm phn tin t vi $negative, v c
cho li. Nu khng, gi tr bn trong $negative c gn
vi s gc.
Cu lnh if th ba c th c thay th bng biu
thc:
$negative . ($card_map[$num] || $num) ;

Chng 9, Cc cu trc iu khin khc
1. Sau y l mt cch thc hin n
sub card { } # from previous exercise
while ( ) { ## NEW ##
print Enter first number: ;
chop ($first = <STDIN>) ;
last if $first eq end ; ## NEW ##

print Enter second number: ;
chop ($second = <STDIN>) ;
last if $second eq end ; ## NEW ##

$message = &card($first) . plus .
&card($second) . equals .
&card($first+$second) . .\n ;
$message =~ s/^./\u$&/ ;
print $message ;
} ## NEW $$
Ch ti vic b sung thm chu trnh while v hai
ton t last. Vy y!


315

Chng 10, Tc hiu tp v kim th tp
1. Sau y l mt cch thc hin n
print What file? ;
chop ($filename = <STDIN>) ;
open (THAFILE, $filename) || die cannot open
$filename ;
while (<THAFILE>) {
print $filename: $_ ; # presume $_ ends in \n
}
Hai dng u tin nhc tn tp, ri tn c m
vi tc hiu THAFILE. Ni dung ca tp ny c c
bng vic dng tc hiu ny, v c in ra STDOUT.

2. Sau y l mt cch thc hin n
print Input file name: ;
chop ($inputfilename = <STDIN>) ;
print Output file name: ;
chop ($outputfilename = <STDIN>) ;
print Search string: ;
chop ($search = <STDIN>) ;
print Replacement string: ;
chop ($replace = <STDIN>) ;
open (IN, $infilename) || die cannot open $infilename
for reading;
## kim th tu chn cho khi ghi ...
die will not overwrite $outputfilename if -e
$outpufilename ;
open (OUT, $outfilename) || die cannot create
$outfilename;
while (<IN>) { # read a line from file $a into $_
s/$search/$replace/g ; # change the lines
print OUT $_; # print that line to file $b
}

316

close (IN);
close (OUT);
Chng trnh ny da trn chng trnh sao tp
trnh by trc y trong chng ny. Cc tnh nng mi
a vo y nhc cho cc xu, v ch lnh thay th
gia chu trnh while, cng nh php kim tra cho vic
ghi tp.

3. Sau y l mt cch thc hin n
while (<>) {
chop ; # eliminate the newline
print $_ is readable\n if -r ;
print $_ is writable\n if -w _ ;
print $_ is executable\n if -x _;
print $_ does not exist\n unless -e ;
}
Chu trnh while ny c mt tc hiu tp mi ln.
Sau khi b i du dng mi, lot cc cu lnh kim tra
tp theo cc php khc nhau. Lu rng php kim tra
th hai v tip sau dng tc hiu _ khi phi hi
lp i lp li h iu hnh v cng mt tp.

4. Sau y l mt cch thc hin n
while (<>) {
chop ;
$age = -M ;
if ($oldest_age < $age) {
$oldest_name = $_ ;
$oldest_age = $age ;
}
}

317

print The oldest file $oldest_name ,
and is $oldest_age days old.\n ;
Trc ht, chng ta lp trn tng tn tp c c
vo. Du dng mi b b i, v th ri tui tnh theo
ngy c tnh bng ton t -M. Nu tui cho tp ny
vt qu tp c nht m thy cho ti gi, chng ta
nh tn tp ny v tui tng ng ca n. Khi u,
$oldest_age s l 0, cho nn chng ta m t nht
mt tp khc 0 ngy c.
Cu lnh print cui cng sinh ra bo co khi chng ta
hon thnh.

Chng 11, Dng thc
1. Sau y l mt cch thc hin n
open (PW, /etc/passwd) || die How did you get logged
in?
while (<PW>) {
($user, $passwd, $uid, $gid, $gcos) = split(/:/) ;
($real) = split(/,/, $gcos) ;
write;
}
format STDOUT =
@<<<<<<< @>>>>>>> @<<<<<<<<<<<<<<<<<<<<<<<
$user, $uid, $real
.
Dng u tin m tp mt hiu. Chu trnh while x
l tp mt hiu theo tng dng. Mi dng c x ra (vi
nh bin hai chm). Np vo bin v hng. Tn thc
ca ngi dng c ly ra trng GCOS. Cu lnh cui
cng ca chu trnh while gi ti vic ghi ra thit b hin
th tt c cc d liu ny.

318

Dng thc cho tc hiu tp STDOUT xc nh ra
mt dng n gin vi ba trng. Cc gi tr bt ngun
t ba bin v hng c cho gi tr trong chu trnh
while.

2. Sau y l mt cch thc hin n
# append to program from the first problem...
format STDOUT_TOP =
Username User ID Real Name
======== ====== =========
@<<<<<< @>>>>> @<<<<<<<<
.
Tt c mi vic lm tiu cho chng trnh
trc l thm vo dng thc u trang. Ti y chng ta
t tiu ct vo cc ct.
cho cc ct thng hng, ti sao vn bn ca
dng thc STDOUT v dng mt ghi trong trnh son
tho vn bn ca ti thay th cc trng @<<< bng
===. l iu hay v tng ng mt-mt gia cc k t
trong dng thc v kt qu hin th.

3. Sau y l mt cch thc hin n
# append to program from the first problem...
format STDOUT_TOP =
Page @<<<
$%

Username User ID Real Name
======== ====== =========
.

319

c ri, ln na y li c cht liu u
trang. Ti thm vo dng thc u trang. Dng thc
ny cng cha mt tham chiu ti $%, s cho vic nh
s trang.

Chng 12, Truy nhp danh mc
1. Sau y l mt cch thc hin n
print Where to? ;
chop ($newdir = <STDIN>) ;
chdir ($newdir) || die Cannot chdir to $newdir ;
foreach (<*>) {
print $_\n;
}
Hai dng u nhc v c tn ca danh mc.
Dng th ba c gng thay i danh mc sang tn
cho, b ra nu iu ny l khng th c.
Chu trnh foreach i qua danh sch. Nhng danh
sch l g? l vic d qua trong hon cnh mng, m
rng ti mt danh sch tt c cc tn tp m snh ng
vi mu ny ( y l *).

2. Sau y l mt cch thc hin n
print Where to? ;
chop ($newdir = <STDIN>) ;
chdir ($newdir) || die Cannot chdir to $newdir ;
opendir (DOT, .) || die Cannot opendir . (serious
dainbramage) ;
foreach (sort readdir(DOT)) {
print $_\n;
}

320

close (DOT) ;
Ging nh chng trnh trc, chng ta nhc v c
danh mc mi. Mt khi chng ta i danh mc chdir
, chng ta m danh mc bng vic to ra mt tc
hiu danh mc c tn DOT. Trong chu trnh foreach,
danh sch c cho li bi readdir (trong hon cnh
mng) c sp xpm v ri c duyt qua, bng vic
gn tng phn t ln lt cho $_.
V y l cch thc hin n vi glob:
print Where to? ;
chop ($newdir = <STDIN>) ;
chdir ($newdir) || die Cannot chdir to $newdir ;
foreach (sort <* .*>) {
print $_\n;
}
Vng, v c bn n l chng trnh khc vi bi tp
trc y, nhng ti thm ton t sort vo pha trc
ca glob, v cng thm .* vo glob ly ra cc tp bt
u vi du chm. Vhng cn sort bi v mt tp c
tn !fred i trc tp chm, nhng barney i sau chng,
v khng c glob d dng c th lm cho tt c chng
theo trnh t ng.

Chng 13, Thao tc tp v danh mc
1. Sau y l mt cch thc hin n
unlink(@ARGV) ;
y, c vy thi. Mng @ARGV l mt danh sch
cc tn cn phi loi b. Ton t unlink nhn mt danh
sch cc tn, cho nn chng ch ly hai tn l xong.

321

Tt nhin, iu ny khng gii quyt vic bo co
li, hay cc tu chn -f hay -i, hay bt k ci g ging th,
nhng ch l ci li bt ng. Nu bn lm th, tt!

2. Sau y l mt cch thc hin n
($old, $new) = @ARGV; # name them
if (-d $new) { # new name is a directory, need to patch it
up
($basename = $old) =~ s#.*/## ; # get basename of
$old
$new .= /$basename ; and append it to new name
}
rename ($old, $new) ;
Ton b cng vic trong chng trnh ny l dng
cui, nhng phn cn li ca chng trnh ny l cn
thit cho trng hp khi tn chng ta ang nhm i l
mt danh mc.
Trc ht, chng ta t tn d hiu cho hai phn t
ca @ARGV. Th ri, nu tn $new l mt danh mc,
chng ta cn v thm cho n bng vic thm tn mi vo
tn c s ca tn $old cui. iu ny c ngha l i
tn /usr/src/fred thnh /etc s gy ra vic i tn
/usr/src/fred thnh /etc/fred
Cui cng, mt khi tn c s c v thm, chng
v gc, vi li gi rename.

3. Sau y l mt cch thc hin n
($old, $new) = @ARGV; # name them
if (-d $new) { # new name is a directory, need to patch it
up

322

($basename = $old) =~ s#.*/## ; # get basename of
$old
$new .= /$basename ; and append it to new name
}
link ($old, $new) ;
Chng trnh ny ging nh chng trnh trc
ngoi tr dng cui cng, bi v chng mc ni ch
khng i tn.

4. Sau y l mt cch thc hin n
if ($ARGV[0] eq -s) { # want a symlink
$symlink++ ; # remember that
shift (@ARGV) ; # and toss the -s flag
}
($old, $new) = @ARGV; # name them
if (-d $new) { # new name is a directory, need to patch it
up
($basename = $old) =~ s#.*/## ; # get basename of
$old
$new .= /$basename ; and append it to new name
}
if ($symlink) { # want a symlink
$symlink($old, $new) ;
} else { # want a hard link
link ($old, $new) ;
}
Phn gia ca chng trnh ny cng ging nh hai
bi tp trc. Ci mi l vi dng u v vi dng
cui.
Vi dng u nhn vo i th nht ca chng
trnh. Nu i ny l -s, bin v hng $symlink c
tng ln, lm sinh ra gi tr 1 cho bin ny. Mng

323

@ARGV c dch i, b c -s. Nu nh c -s khng c
, chng phi lm g, v $symlink s vn cn l undef.
Vic dch chuyn mng @ARGV xut hin thng
xuyn n mc mng @ARGV l i ngm nh cho
shift - tc l chng ta c th ni:
shift;
thay cho
shift (@ARGV);
Vi dng cui nhn vo gi tr ca $symlink. N hoc
l 1 hoc l undef, v da trn , s symlink cc tp hay
link chng.

5. Sau y l mt cch thc hin n
foreach $f (<*>) {
print $f -> $where\n if $where = readlink($f) ;
}
Bin v hng $f c bt cho tng tn tp trong
danh mc hin ti. Vi mi tn, $where ly tp cc tn
t readlink(). Nu tn ny khng phi l mt symlink,
ton t readlink cho li undef, cho li mt gi tr sai cho
php kim tra if , v print b nhy qua. Nhng khi ton t
readlink cho li mt gi tr, print hin th cc gi tr ngun
v nhn symlink.

Chng 14, Qun l tin trnh
1. Sau y l mt cch thc hin n
if (`date` =~ /^S/) {
print Go play~\n ;

324

} else {
print Get to work!\n ;
}
iu hay xy ra l k t ra u tin ca ch lnh date
ch l mt S vo cui tun (Sat hay Sun), lm cho
chng trnh thnh tm thng. Chng ta gi date, ri
dng biu thc chnh qui xem liu k t u tin c l
S hay khng. Da trn iu ny, chng ta in ra thng bo
ny hay khc.

2. Sau y l mt cch thc hin n
open (PW, /etc/passwd) ;
while (<PW>) {
chop;
($user, $pw, $uid, $gid, $gcos) = split(/:/) ;
($real) = split(/,/.$gcos) ;
$real {$user} = $real ;
}
close (PW) ;

open(WHO, who|) || die cannot open who pipe;
while (<WHO>) {
($login, $rest) = /^(\S+)\s+(.*)/;
$login = $real{$login} if $real{$login} ;
printf %-30s %s\n, $login, $rest ;
}
Chu trnh th nht to ra mt mng kt hp %real
ly cc tn ng nhp lm kho v cc tn thc tng
ng lm gi tr. Mng ny c dng trong chu trnh tip
sau thay i tn ng nhp thnh tn thc.
Chu trnh th hai duyt qua ci ra kt qu t vic m
ch lnh who xem nh tc hiu tp. Mi dng ci ra ca

325

who li c b ra bng vic dng vic snh biu thc
chnh qui trong hon cnh mng. T u tin ca dng
ny (tn ng nhp) c thay th bng tn tht trong
mng ny, nhng ch nu n tn ti. Khi tt c nhng
iu c thc hin, printf a kt qu ra
STDOUT.
Bn c th thay th vic m tc hiu tp v vic
bt u chu trnh ch bng:
foreach $_ (`who`) {
hon thnh cng kt qu. S khc bit duy nht l
ch bn vi tc hiu tp c th bt u lm vic ngay
khi who bt u ch cc k t, trong khi bn vi who
trong du nhy n ngc phi i who kt thc.

3. Sau y l mt cch thc hin n
open (PW, /etc/passwd) ;
while (<PW>) {
chop;
($user, $pw, $uid, $gid, $gcos) = split(/:/) ;
($real) = split(/,/.$gcos) ;
$real {$user} = $real ;
}
close (PW) ;

open(LPR, |lpt) || die cannot open LPR pipe;
open(WHO, who|) || die cannot open who pipe;
while (<WHO>) {
# or replace previous two lines with: foreach $_
(`who`) {
($login, $rest) = /^(\S+)\s+(.*)/;
$login = $real{$login} if $real{$login} ;
printf LPR %-30s %s\n, $login, $rest ;
}

326

S khc bit gia chng trnh ny v chng trnh
trong bi tp trc l ch chng ta b sung thm
mt tc hiu tp LPR c m i vi tin trnh lpr, v
sa i cu lnh printf gi d liu ra thay v ra
STDOUT.

4. Sau y l mt cch thc hin n
sub mkdir {
!system /bin/mkdir, @_ ;
}
Ti y, ch lnh mkdir c cho cc i trc tip t
cc i ca chng trnh con. Tuy nhin, gi tr cho li
phi c ph nh v mt logic bi v mt trng thi ra
khc khng t system phi dch thnh gi tr sai cho ni
gi Perl.

5. Sau y l mt cch thc hin n
sub mkdir {
local($dir, $mode) = @_;
(!system /bin/mkdir, $dir) && chmod ($mode, $dir) ;
}
u tin, cc i cho trnh ny c t tn l $dir
v $mode. Tip , chng ta gi mkdir trn danh mc
c $dir ch tn. Nu iu thnh cng, ton t chmod
cho li mt ng cho danh mc ny.

Chng 15, Bin i d liu khc
1. Sau y l mt cch thc hin n

327

while (<>) {
chop;
$slash = rindex($_, /) ;
$head = substr($_,0,$slash) ;
$tail = substr($_, $slash+1) ;
print head = $head, tail = $tail\n ;
}
Mi dng c c bi ton t hnh thoi c
cht b (du dng mi phin phc) trc ht. Tip
chng ta tm du s cho bn phi nht trong dng ny,
bng vic dng rindex(). Hai dng tip b xu ny ra bng
vic dng substr(). Lu rng cc biu thc ny lm
ng vic cho d khi kt qu ca rindex l -1 (khng c
du s cho trong xu). Dng cui cng bn trong chu
trnh in ra kt qu.

2. Sau y l mt cch thc hin n
chop(@nums = <STDIN>) ; # note special use of chop
@nums = sort { $a <=> $b } @nums;
foreach (@nums) {
printf %30g\n, $_ ;
}
Dng th nht nm ly tt c cc s trong mng
@nums. Dng th hai sp xp mng theo s, bng cch
dng mt nh ngha trong dng cho th t sp xp. Chu
trnh foreach in ra kt qu.

3. Sau y l mt cch thc hin n
open (PW, /etc/passwd) || die How did you get logged
in?
while (<PM>) {

328

chop ;
($user, $pm, $uid, $gid, $gcos) = split(/:/) ;
($real) = split(/,/,$gcos) ;
$real {$user} = $real ;
($last = $real) =~ s/^(.*[^a-z]) ? ([^a-z]+.*).*/$2/i ;
$last =~ tr/A-Z/a-z/;
$last {$user} = $last;
}
close (PW) ;

for (sort by_last keys %last) {
printf %30s %8s\n, $real{$_}, $_ ;
}

sub by_last { $last{$a} cmp $;ast{$b}) || ($a cmp $b)}
Chu trnh u tin to ra mng %last, bao gm tn
ng nhp lm kho, v tn cui ca ngi dng l gi
tr tng ng, v mng %real , cha cc tn thc y .
Chu trnh th hai in ra %real c sp th t theo
cc gi tr ca %last , dng nh ngha sp xp c trnh
by trong chng trnh con by_last.

4. Sau y l mt cch thc hin n
while (<>) {
substr($_,0,1) =~ tr/a-z/A-Z/;
substr($_,1) =~ tr/A-Z/a-z/;
print ;
}
Vi mi dng c ton t hnh thoi c vo, dng
hai php ton tr, mi php ton trn mt phn khc nhau
ca xu ny. Ton t tr th nht bin k t u tin ca
dng thnh ch hoa, cn ton t tr th hai, bin phn cn
li thnh ch thng. Kt qu c in ra.

329

Mt cch khc thc hin vic ny, bng cch
dng ton t xu nhy kp, l:
while (<>) {
print \u\L$_;
}
cho mnh nm im ph nu bn ngh ti iu
.

Chng 16, Truy nhp c s d liu h thng
1. Sau y l mt cch thc hin n
$: = ;
while (@pw = getpwent) {
($user, $gid, $gcos) = @pw[0,3,6];
($real) = split(/,/,$gcos) ;
$real { $user} = $real ;
$member {$gid} .= $user ;
($last = $real) =~ s/^(.*[^a-z]) ? ([a-z]+.*).*/$2/i;
$last =~ tr/A-Z/a-z/;
$last {$user} = $last;
}

while (@gr = getgrent) {
($gname, $Gid, $members) = @gr[0,2,3];
$members {$gid} .= $members;
$gname {$grid} = $gname ;
}

for $gid (sort by_gname keys %gname) {
%all = () ;
for (split (/\s+/, $members {$gid} )) {
$all {$_} ++ if length $_ ;
}
@members = () ;
foreach (sort by_last key %all) {

330

push(@members, $real {$_} ($_)) ;
}
$members = join(, , @members);
write;
}

sub by_gname { $gname {$a} cmp $gname {$b};}
sub by_last { ($last {a} cmp $last {$b}) || ($a cmp $b) ; }

format STDOUT =
@<<<<<<<< @<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<
$gname {$gid}, ($gid), $memberlist
~~ ^<<<<<<<<<<<<<<<<<<<<<
$memberlist
.

Chng 17, Thao tc c s d liu ngi dng
1. Sau y l mt cch thc hin n
dbmopen(ALIAS, /etc/aliases, undef) || die No
aliases!;
while ($key, $value) = each (%ALIAS)) {
chop ($key, $value) ;
print $key $value\n ;
}
Dng th nht m cc bit hiu DBM. (H thng
ca bn c th gi cc bit hiu DBM trong
/usr/lib/aliases - th iu nu iu ny khng lm
vic.) Chu trnh while duyt qua mng DBM. Dng th
nht bn trong cho trnh s ct b i k t NUL ti cui
kho v gi tr. Dng cui cng ca chu trnh ny in ra
kt qu.


331

2. Sau y l mt cch thc hin n
# program 1:
dbmopen(%WORDS, words, 0644) ;
while (<>) {
foreach $word (split(/\W+/)) {
$WORDS {$word}++;
}
}
dbmclose (%WORDS);
Chng trnh th nht (ngi vit) m mt DBM
trong danh mc hin ti c gi l words, to ra cc tp
c tn words.dir v words.pag. Chu trnh while ly tng
dng bng vic dng ton t hnh thoi. Dng ny c
ch ra tng phn bng vic dng ton t split, vi nh
bin /\W+/, c ngha l k t khng l t. Mi t tip
c m trong mng DBM, bng vic dng cu lnh
foreach i qua cc t.
# program 2:
dbmopen(%WORDS, words, undef) ;
foreach $word (sort { $WORDS {$b} <=> $WORDS {$a} }
keys %WORDS)
{
print $word $WORDS {$word}\n ;
}
dbmclose (%WORDS);
Chng trnh th hai m mt DBM trong danh mc
hin ti c tn l words. Dng foreach trng phc tp,
lm hu ht cc cng vic bn thu. Gi tr ca $word
mi ln qua chu trnh ny s l phn t tip ca danh
sch. Danh sch ny c sp th t theo kho trong
mng %WORDS, sp theo gi tr ca chng (s m)
theo th t gim dn. Vi mi t trong danh sch, chng
ta in ra t v s ln t xut hin.

332


Chng 18, Chuyn cc ngn ng khc sang Perl
1. Sau y l mt cch thc hin n
for ( ; ; ) {
($user, $home) = (getpwent) [0,7];
last unless $user;
next unless open (N, $home/.newsrc) ;
while (<N>) {
if (/^comp\.lang\.perl:/) {
print $user a good person, ,
and reads comp.lang.perl!\n) ;
last;
}
}
}
Chu trnh bn ngoi nht l chu trnh for m c chy
mi - tuy nhin chu trnh ny ra bng ton t last bn
trong. Mi ln qua chu trnh, mt gi tr mi cho $user
(tn ngi dng) v $home (danh mc nh ca h) c
ly ra bng vic dng ton t getpwent.
Nu gi tr ca $user l rng, chu trnh for thot ra.
Hai dng tip tm tp .newsrc mi y trong danh mc
ny ca ngi dng. Nu khng th m c tp ny,
hay thi gian sa i cho tp ny l qu xa, vic lp tip
cho chu trnh for s c bt ly.
Chu trnh while c mt dng mi lc t
tp .newsrc. Nu dng ny bt u vi comp.lang.perl:,
cu lnh print ni th, v cho trnh while ra sm.


333


Ph lc B

C s v ni mng


Mi ngi bao gi cng ti gp ti trn ph, hng
chc ln mt ngy, v hi, Ny, Randal, lm sao ti lm
cho Perl gii quyt khe cm vo/ra?
c, ti mun dy v TCP/IP, nhng khng may
l l ca trang ny qu hp. Cho nn, bn phi gii quyt
mt th d lm vic tht, v c l phi i
OReilly&Associates a ra mt cun sch Perl nng
cao.

M hnh khe cm
Vn i loi l th ny:
1. Tin trnh phc v to ra mt khe cm tng qut
bng socket().
2. B phc v kt ghp khe cm ny vi mt a ch
tho thun qua bind().

334

3. B phc v lu h thng rng n ni qua listen().
4. B phc v ngi sau v i ln ni ghp u tin qua
accept().
5. Tin trnh khch to ra mt khe cm tng qut bng
socket().
6. Khch kt ghp khe cm ny vi bt k a ch no
do h thng chn qua bind(). (Vic kt ghp c th
xy ra trong bc tip nu khch khng cu k v a
ch.)
7. Mt khi c kt ghp, khch ni khe cm ca
mnh vi khe cm ca b phc v qua connect(), bng
vic dng a ch tho thun. iu ny thit lp
ln mt ghp ni.
8. B phc v n ghp ni mi. Cc b phc v
in hnh phn nhnh cho mt b phc v con
gii quyt vic ghp ni c bit, vi b phc v b
m gii quyt cho ghp ni tip. (B phc v mu
ca chng khng phn nhnh v sau, bi v n ch
lm mt vic ngn v tho b ghp ni ny. iu ny
s l vn nu 20 yu cu ti mt lc.)
9. B phc v con c d liu t khe cm c
khch gi. B phc v con cng ghi d liu ln khe
cm, m do khch c sn. Trong Perl, vo/ra c
thc hin dng nh n l mt tc hiu tp bnh
thng.
10. Khi b phc v con v khch kt thc ni chuyn,
chng ng tc hiu tp, do vy kt thc vic ghp
ni.

335


Mt khch mu
V l mt khch n gin. Khch lm vic thc t
ny ni ti mt a ch xc nh (trong trng hp
ny, daytime chun) trn mt my ch c bit (my
ch cc b), v in ra bt k ci ra no m cng sinh ra.
require sys/socket.ph;
$sockaddr = S n a4 x8;
chop ($hostname = `hostname`) ;
($name, $aliases, $proto) = getprotobyname(tcp);
($name, $aliases, $port) = getservbyname(daytime,
tcp);
($name, $aliases, $type, $len, $thisaddr) =
gethostbyname ($hostname);
$thisport = pack($socaddr, &AF_INET, 0, $thisaddr);
$thatport = pack($socaddr, &AF_INET, $port, $thisaddr);

socket(S, &PF_INET, &SOCK_STREAM, $proto) ||
die cannot create socket\n ;
bind (S, $thisport) || die cannot bind socket\n; # optional
connect (S, $thatport) || die cannot connect socket\n ;
while (<S>) {
print;
}
exit 0;

B phc v mu
V l mt b phc v n gin. B phc v ny t
khe cm ti a ch 4242 trn my hin ti. Bt k ai ni
vi cng ny ly c bnh may mn a tuyn. Mi
bnh may mn c dng mt ln (ngu nhin) cho
ti khi tt c cc bnh c n ht. Vy c s bnh
c khi ng li t u.

336

Bn c th dng chng trnh ny vi khch mu
bng vic thay th ng tnh $port bi cu lnh n
$port = 43242;. Hay bn c th ni telnet localhost 4242
quan st ci ra - s chn la ca bn.
require sys/socket.ph;
$sockaddr = S n a4 x8;
chop ($hostname = `hostname`) ;
($name, $aliases, $proto) = getprotobyname(tcp);
$port = 4242; # some big number
$thisport = pack($socaddr, &AF_INET, $port, \0\0\0\0);
#wildcard addr
socket(S, &PF_INET, &SOCK_STREAM, $proto) ||
die cannot create socket\n ;
bind (S, $thisport) || die cannot bind socket\n;
listen(S,5) || die cannot listen socket\n;
for (; ;) {
accept(NS,S) || die cannot accept socket\n;
print NS &fortune;
close NC;
}

sub fortune {
@fortunes = split(/\n%%\n/, <<END) unless
@fortunes;
A fool and hs money are soon parted.
%%
A penny saved is a penny earned.
%%
Ask not what your country can do for you;
ask what you can do for your country.
%%
END
splice(@fortunes, int(rand(@fortunes)), 1). \n
}

337


Ph lc C

Cc ch cn cha
ni ti


Vng, iu ny ng ngc nhin. Cun sch ny qu
di, th m vn cn ci g n vn cha bao qut ht.
Cc ch thch cui trang cha thm thng tin ph.
Mc ch ca mc ny khng phi l dy cho bn
v nhng iu c lit k ra y, m n gin a
ra mt danh sch. Bn s cn ti Sch con lc hay ti
liu dng Perl (trn nhm h tr Usenet) c thm
thng tin.

Trnh g li
Perl c trnh g li mc ngun tuyt vi.


338

Dng lnh
B thng dch Perl c qu tha thi cc kho dng
lnh.

Cc ton t khc
Ton t phy l mt. V c cch din t do { block; }
khc c trong tay khi bn cn mt khi cu lnh ni
i hi biu thc.
V c mt s bin th v cc php ton, ging nh
vic dng b sa i g cho vic i snh.

Nhiu, nhiu hm na
Vng, Perl c tht nhiu hm, ti khng nh lit k
chng ra y, bi v cch nhanh nht tm ra chng l
c qua mc cc hm trong cun Lp trnh Perl hay ti
liu v perl v nhn vo bt k ci g bn nhn ra khng
ng quan tm.

Nhiu, nhiu bin nh ngha sn
Bn thy vi bin xc nh trc, nh $_.
c, cn nhiu na c.

Xu y
Bn cnh cc xu nhy n v nhy kp, bn cng
c th c cc xu y, ging nh ti liu y trong
lp v:

339

$a = <<HEAD . \n . $body;
To: merlyn@ora.com
From: $username
Subject: What, do you think?
Date: $now
HEAD
Chng thc s l khng cn thit, bi v bn c th
ch vit ra mt xu nhy kp di thay th, nhng vi
ngi thy chng r rng. V cch bn c th ni C
nhiu cch trch dn n!

Tr v (t trnh con)
C cu lnh return ra ngay lp tc khi chng
trnh con, ko theo mt gi tr cng n. Nhng trong Perl
4.0 n c hi khng hiu qu, cho nn ti b li n ra
khi m t ny. Tuy th bn c thoo mi m dng n.

Ton t eval (v s///e)
Vng, bn c th xy dng mt mu chng trnh
vo lc chy ri tnh eval n, nh bn c th lm vi lp
v. N thc t c ch, bi v bn c th thu c nhng
ti u v thi gian dch (nh biu thc chnh qui c
dch) vo lc chy. Bn cng c th dng n by cc
li nh mnh khc trong mt on chng trnh: li
nh mnh bn trong eval n gin ra khi eval v cho
bn trng thi li.
Chng hn, sau y l mt chng trnh c mt
dng chng trnh Perl t ngi dng v ri thc hin
n dng nh n l mt phn ca chng trnh Perl:

340

print code line: ;
chop ($code = <STDIN>) ;
eval $code; die eval: $@ if $@ ;
Bn c th t chng trnh Perl bn trong xu thay
th ca ton t th vi c e. iu ny lm th cng nu
bn mun xy dng ci g phc tp cho xu thay th,
nh gi trnh con cho li kt qu ca vic tra c s d
liu. Sau y l mt chu trnh lm tng gi tr ca ct th
nht ca mt lot dng:
while (<>) {
s/^(S+)/$1+1/e; # $1+1 is Perl code, not a string
print ;
}

Thao tc bng k hiu bng *FRED
Bn c th lm b thnh mt bit hiu cho a qua *b =
*a. iu ny c ngha l $a v $b tham chiu ti cng
mt bin, nh @a v @b, v thm ch cc tc hiu tp
v dng thc a v b. Bn cng c th nh v *b bn trong
mt khi vi local(*b), v iu cho bn c tc hiu
tp cc b v dng thc v cc th khc. Mt cht liu
kh ng bng nhng c ch khi bn cn n. Perl 5.0
thm ch cn c cch t bit hiu phc tp hn (ging
nhiu hn vi con tr ca C) nhng khi vit iu ny, ti
cha t liu v n.

Ton t goto
Vng, c, Perl c ton t goto. Nhng n khng
hiu qu khng khip, v n tn ti ch h tr cho b
dch sed sang Perl. Cho nn ng dng n. Bn thc s

341

khng cn n. V chng trnh Perl c th tr thnh
kh hiu cho d khng c mt ng cc goto.

Ton t require
Ton t require l dng ca include ca Perl. Cc
phn ca chng trnh Perl c th b mc kt vo trong
mt tp tch bit (hay tp cc tp) v ri c a vo
trong bt k chng trnh Perl no cn chng. Chng
hn:
require fred.pl ;
a vo trong vn bn ca tp fred.pl dng nh n
l mt phn ca tp ny, cho php nhiu chng trnh
dng chung m Perl.

Th vin
Ni v chm cc chng trnh Perl c bao hm,
nhiu ngi tho (v ti) ng gp nhiu chng
trnh lm nhng vic c ch. tm ra th vin Perl
u, yu cu Perl in ra phn t u tin ca mng @INC.
(Nu khng c g trong danh mc , Perl ca bn
c ci t khng ng.) Gn nh tt c cc trnh ny
c li ch thch trong chng m t cch s dng.

Tin vui v Perl 5.0
V thm ch cn c c chm nhng cht liu m
khng ai (ngoi tr Larry Wall) bit ti, v bn mi nht
ca Perl khng c a ra vo lc ti g nhng iu

342

ny. Bi th, bn phi kim tra trong ti liu xem Larry
tin hnh nhng n lc ln m bo rng s khc
bit gia bn bn ang chy v sch in c lm ti
liu tt. Cm n, Larry.

You might also like