Vous êtes sur la page 1sur 1124

Teach Yourself Perl 5 in 21 days

David Till
Table of Contents:
I ntroduction
G Who Shoul d Read This Book?
G Special Feat ur es of This Book
G Pr ogr amming Exampl es
G End-of -Day Q& A and Wor kshop
G Convent ions Used in This Book
G What You'l l Lear n in 21 Days
Week 1 Week at a Glance
G Wher e You'r e Going
Day 1 Getting Started
G What Is Per l ?
G How Do I Find Per l ?
H Wher e Do I Get Per l ?
H Ot her Pl aces t o Get Per l
G A Sampl e Per l Pr ogr am
G Running a Per l Pr ogr am
H If Somet hing Goes Wr ong
G The Fir st Line of Your Per l Pr ogr am: How Comment s Wor k
H Comment s
G Line 2: St at ement s, Tokens, and <STDIN>
H St at ement s and Tokens
H Tokens and Whit e Space
H What t he Tokens Do: Reading f r om St andar d Input
G Line 3: Wr it ing t o St andar d Out put
H Funct ion Invocat ions and Ar gument s
G Er r or Messages
G Int er pr et ive Languages Ver sus Compil ed Languages
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 2 Basic Operators and Control Flow
G St or ing in Scal ar Var iabl es Assignment
H The Def init ion of a Scal ar Var iabl e
H Scal ar Var iabl e Synt ax
H Assigning a Val ue t o a Scal ar Var iabl e
G Per f or ming Ar it hmet ic
H Exampl e of Mil es-t o-Kil omet er s Conver sion
H The chop Libr ar y Funct ion
G Expr essions
H Assignment s and Expr essions
G Ot her Per l Oper at or s
G Int r oduct ion t o Condit ional St at ement s
G The if St at ement
H The Condit ional Expr ession
H The St at ement Bl ock
H Test ing f or Equal it y Using ==
H Ot her Compar ison Oper at or s
G Two-Way Br anching Using if and else
G Mul t i-Way Br anching Using elsif
G Wr it ing Loops Using t he while St at ement
G Nest ing Condit ional St at ement s
G Looping Using t he until St at ement
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 3 Understanding Scalar Values
G What Is a Scal ar Val ue?
G Int eger Scal ar Val ues
H Int eger Scal ar Val ue Limit at ions
G Fl oat ing-Point Scal ar Val ues
H Fl oat ing-Point Ar it hmet ic and Round-Of f Er r or
G Using Oct al and Hexadecimal Not at ion
H Decimal Not at ion
H Oct al Not at ion
H Hexadecimal Not at ion
H Why Bot her ?
G Char act er St r ings
H Using Doubl e-Quot ed St r ings
H Escape Sequences
H Singl e-Quot ed St r ings
G Int er changeabil it y of St r ings and Numer ic Val ues
H Init ial Val ues of Scal ar Var iabl es
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 4 More Operators
G Using t he Ar it hmet ic Oper at or s
H Exponent iat ion
H The Remainder Oper at or
H Unar y Negat ion
G Using Compar ison Oper at or s
H Int eger -Compar ison Oper at or s
H St r ing-Compar ison Oper at or s
H St r ing Compar ison Ver sus Int eger Compar ison
H Compar ison and Fl oat ing-Point Number s
G Using Logical Oper at or s
H Eval uat ion Wit hin Logical Oper at or s
H Logical Oper at or s as Subexpr essions
G Using Bit -Manipul at ion Oper at or s
H What Bit s Ar e and How They Ar e Used
H The Bit -Manipul at ion Oper at or s
G Using t he Assignment Oper at or s
H Assignment Oper at or s as Subexpr essions
G Using Aut oincr ement and Aut odecr ement
H The Aut oincr ement Oper at or Pr e-Incr ement
H The Aut oincr ement Oper at or Post -Incr ement
H The Aut odecr ement Oper at or
H Using Aut oincr ement Wit h St r ings
G The St r ing Concat enat ion and Repet it ion Oper at or s
H The St r ing-Concat enat ion Oper at or
H The St r ing-Repet it ion Oper at or
H Concat enat ion and Assignment
G Ot her Per l Oper at or s
H The Comma Oper at or
H The Condit ional Oper at or
G The Or der of Oper at ions
H Pr ecedence
H Associat ivit y
H For cing Pr ecedence Using Par ent heses
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 5 Lists and Array Variables
G Int r oducing List s
G Scal ar Var iabl es and List s
H List s and St r ing Subst it ut ion
G St or ing List s in Ar r ay Var iabl es
G Accessing an El ement of an Ar r ay Var iabl e
H Mor e Det ail s on Ar r ay El ement Names
G Using List s and Ar r ays in Per l Pr ogr ams
H Using Br acket s and Subst it ut ing f or Var iabl es
G Using List Ranges
H Expr essions and List Ranges
G Mor e on Assignment and Ar r ay Var iabl es
H Copying f r om One Ar r ay Var iabl e t o Anot her
H Using Ar r ay Var iabl es in List s
H Subst it ut ing f or Ar r ay Var iabl es in St r ings
H Assigning t o Scal ar Var iabl es f r om Ar r ay Var iabl es
G Ret r ieving t he Lengt h of a List
G Using Ar r ay Sl ices
H Using List Ranges in Ar r ay-Sl ice Subscr ipt s
H Using Var iabl es in Ar r ay-Sl ice Subscr ipt s
H Assigning t o Ar r ay Sl ices
H Over l apping Ar r ay Sl ices
H Using t he Ar r ay-Sl ice Not at ion as a Shor t hand
G Reading an Ar r ay f r om t he St andar d Input Fil e
G Ar r ay Libr ar y Funct ions
H Sor t ing a List or Ar r ay Var iabl e
H Rever sing a List or Ar r ay Var iabl e
H Using chop on Ar r ay Var iabl es
H Cr eat ing a Singl e St r ing f r om a List
H Spl it t ing a St r ing int o a List
H Ot her List -Manipul at ion Funct ions
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 6 Reading from and Writing to Files
G Opening a Fil e
H The Fil e Var iabl e
H The Fil ename
H The Fil e Mode
H Checking Whet her t he Open Succeeded
G Reading f r om a Fil e
H Fil e Var iabl es and t he St andar d Input Fil e
H Ter minat ing a Pr ogr am Using die
H Reading int o Ar r ay Var iabl es
G Wr it ing t o a Fil e
H The St andar d Out put Fil e Var iabl e
H Mer ging Two Fil es int o One
G Redir ect ing St andar d Input and St andar d Out put
G The St andar d Er r or Fil e
G Cl osing a Fil e
G Det er mining t he St at us of a Fil e
H Fil e-Test Oper at or Synt ax
H Avail abl e Fil e-Test Oper at or s
H Mor e on t he -e Oper at or
H Test ing f or Read Per mission-t he -r Oper at or
H Checking f or Ot her Per missions
H Checking f or Empt y Fil es
H Using Fil e-Test Oper at or s wit h Fil e Var iabl es
G Reading f r om a Sequence of Fil es
H Reading int o an Ar r ay Var iabl e
G Using Command-Line Ar gument s as Val ues
H ARGV and t he <> Oper at or
G Opening Pipes
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 7 Pattern Matching
G Int r oduct ion
G The Mat ch Oper at or s
H Mat ch-Oper at or Pr ecedence
G Special Char act er s in Pat t er ns
H The + Char act er
H The [] Special Char act er s
H The * and ? Special Char act er s
H Escape Sequences f or Special Char act er s
H Mat ching Any Let t er or Number
H Anchor ing Pat t er ns
H Var iabl e Subst it ut ion in Pat t er ns
H Excl uding Al t er nat ives
H Char act er -Range Escape Sequences
H Mat ching Any Char act er
H Mat ching a Specif ied Number of Occur r ences
H Specif ying Choices
H Reusing Por t ions of Pat t er ns
H Pat t er n-Sequence Scal ar Var iabl es
H Special -Char act er Pr ecedence
H Specif ying a Dif f er ent Pat t er n Del imit er
G Pat t er n-Mat ching Opt ions
H Mat ching Al l Possibl e Pat t er ns
H Ignor ing Case
H Tr eat ing t he St r ing as Mul t ipl e Lines
H Eval uat ing a Pat t er n Onl y Once
H Tr eat ing t he St r ing as a Singl e Line
H Using Whit e Space in Pat t er ns
G The Subst it ut ion Oper at or
H Using Pat t er n-Sequence Var iabl es in Subst it ut ions
H Opt ions f or t he Subst it ut ion Oper at or
H Eval uat ing a Pat t er n Onl y Once
H Tr eat ing t he St r ing as Singl e or Mul t ipl e Lines
H Using Whit e Space in Pat t er ns
H Specif ying a Dif f er ent Del imit er
G The Tr ansl at ion Oper at or
H Opt ions f or t he Tr ansl at ion Oper at or
G Ext ended Pat t er n-Mat ching
H Par ent hesizing Wit hout Saving in Memor y
H Embedding Pat t er n Opt ions
H Posit ive and Negat ive Look-Ahead
H Pat t er n Comment s
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Week 1 Week 1 in Review
Week 2 Week 2 at a Glance
G Wher e You'r e Going
Day 8 More Control Structures
G Using Singl e-Line Condit ional St at ement s
H Pr obl ems wit h Singl e-Line Condit ional St at ement s
G Looping Using t he for St at ement
H Using t he Comma Oper at or in a for St at ement
G Looping Thr ough a List : The foreach St at ement
H The foreach Local Var iabl e
H Changing t he Val ue of t he Local Var iabl e
H Using Ret ur ned List s in t he foreach St at ement
G The do St at ement
G Exit ing a Loop Using t he last St at ement
G Using next t o St ar t t he Next It er at ion of a Loop
G The redo St at ement
G Using Label ed Bl ocks f or Mul t il evel Jumps
H Using next and redo wit h Label s
G The continue Bl ock
G The goto St at ement
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 9 Using Subroutines
G What Is a Subr out ine?
G Def ining and Invoking a Subr out ine
H For war d Ref er ences t o Subr out ines
G Ret ur ning a Val ue f r om a Subr out ine
H Ret ur n Val ues and Condit ional Expr essions
G The return St at ement
G Using Local Var iabl es in Subr out ines
H Init ial izing Local Var iabl es
G Passing Val ues t o a Subr out ine
H Passing a List t o a Subr out ine
G Cal l ing Subr out ines f r om Ot her Subr out ines
G Recur sive Subr out ines
G Passing Ar r ays by Name Using Al iases
G Using t he do St at ement wit h Subr out ines
G Specif ying t he Sor t Or der
G Pr edef ined Subr out ines
H Cr eat ing St ar t up Code Using BEGIN
H Cr eat ing Ter minat ion Code Using END
H Handl ing Non-Exist ent Subr out ines Using AUTOLOAD
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 10 Associative Arrays
G Limit at ions of Ar r ay Var iabl es
G Def init ion
G Ref er r ing t o Associat ive Ar r ay El ement s
G Adding El ement s t o an Associat ive Ar r ay
G Cr eat ing Associat ive Ar r ays
G Copying Associat ive Ar r ays f r om Ar r ay Var iabl es
G Adding and Del et ing Ar r ay El ement s
G List ing Ar r ay Indexes and Val ues
G Looping Using an Associat ive Ar r ay
G Cr eat ing Dat a St r uct ur es Using Associat ive Ar r ays
H Linked List s
H St r uct ur es
H Tr ees
H Dat abases
H Exampl e: A Cal cul at or Pr ogr am
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 11 Formatting Your Output
G Def ining a Pr int For mat
G Displ aying a Pr int For mat
G Displ aying Val ues in a Pr int For mat
H Cr eat ing a Gener al -Pur pose Pr int For mat
H Choosing a Val ue-Fiel d For mat
H Pr int ing Val ue-Fiel d Char act er s
H Using t he Mul t il ine Fiel d For mat
G Wr it ing t o Ot her Out put Fil es
H Saving t he Def aul t Fil e Var iabl e
G Specif ying a Page Header
H Changing t he Header Pr int For mat
G Set t ing t he Page Lengt h
H Using print wit h Paginat ion
G For mat t ing Long Char act er St r ings
H El iminat ing Bl ank Lines When For mat t ing
H Suppl ying an Indef init e Number of Lines
G For mat t ing Out put Using printf
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 12 Working with the File System
G Fil e Input and Out put Funct ions
H Basic Input and Out put Funct ions
H Skipping and Rer eading Dat a
H Syst em Read and Wr it e Funct ions
H Reading Char act er s Using getc
H Reading a Binar y Fil e Using binmode
G Dir ect or y-Manipul at ion Funct ions
H The mkdir Funct ion
H The chdir Funct ion
H The opendir Funct ion
H The closedir Funct ion
H The readdir Funct ion
H The telldir and seekdir Funct ions
H The rewinddir Funct ion
H The rmdir Funct ion
G Fil e-At t r ibut e Funct ions
H Fil e-Rel ocat ion Funct ions
H Link and Symbol ic Link Funct ions
H Fil e-Per mission Funct ions
H Miscel l aneous At t r ibut e Funct ions
G Using DBM Fil es
H The dbmopen Funct ion
H The dbmclose Funct ion
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 13 Process, String, and Mathematical Functions
G Pr ocess- and Pr ogr am-Manipul at ion Funct ions
H St ar t ing a Pr ocess
H Ter minat ing a Pr ogr am or Pr ocess
H Execut ion Cont r ol Funct ions
H Miscel l aneous Cont r ol Funct ions
G Mat hemat ical Funct ions
H The sin and cos Funct ions
H The atan2 Funct ion
H The sqrt Funct ion
H The exp Funct ion
H The log Funct ion
H The abs Funct ion
H The rand and srand Funct ions
G St r ing-Manipul at ion Funct ions
H The index Funct ion
H The rindex Funct ion
H The length Funct ion
H Ret r ieving St r ing Lengt h Using tr
H The pos Funct ion
H The substr Funct ion
H The study Funct ion
H Case Conver sion Funct ions
H The quotemeta Funct ion
H The join Funct ion
H The sprintf Funct ion
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 14 Scalar-Conversion and List-Manipulation Functions
G The chop Funct ion
G The chomp Funct ion
G The crypt Funct ion
G The hex Funct ion
G The int Funct ion
G The oct Funct ion
H The oct Funct ion and Hexadecimal Int eger s
G The ord and chr Funct ions
G The scalar Funct ion
G The pack Funct ion
H The pack Funct ion and C Dat a Types
G The unpack Funct ion
H Unpacking St r ings
H Skipping Char act er s When Unpacking
H The unpack Funct ion and uuencode
G The vec Funct ion
G The defined Funct ion
G The undef Funct ion
G Ar r ay and List Funct ions
H The grep Funct ion
H The splice Funct ion
H The shift Funct ion
H The unshift Funct ion
H The push Funct ion
H The pop Funct ion
H Cr eat ing St acks and Queues
H The split Funct ion
H The sort and reverse Funct ions
H The map Funct ion
H The wantarray Funct ion
G Associat ive Ar r ay Funct ions
H The keys Funct ion
H The values Funct ion
H The each Funct ion
H The delete Funct ion
H The exists Funct ion
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Week 2 Week 2 in Review
Week 3 Week 3 at a Glance
G Wher e You'r e Going
Day 15 System Functions
G Syst em Libr ar y Emul at ion Funct ions
H The getgrent Funct ion
H The setgrent and endgrent Funct ions
H The getgrnam Funct ion
H The getgrid Funct ion
H The getnetent Funct ion
H The getnetbyaddr Funct ion
H The getnetbyname Funct ion
H The setnetent and endnetent Funct ions
H The gethostbyaddr Funct ion
H The gethostbyname Funct ion
H The gethostent, sethostent, and endhostent Funct ions
H The getlogin Funct ion
H The getpgrp and setpgrp Funct ions
H The getppid Funct ion
H The getpwnam Funct ion
H The getpwuid Funct ion
H The getpwent Funct ion
H The setpwent and endpwent Funct ions
H The getpriority and setpriority Funct ions
H The getprotoent Funct ion
H The getprotobyname and getprotobynumber Funct ions
H The setprotoent and endprotoent Funct ions
H The getservent Funct ion
H The getservbyname and getservbyport Funct ions
H The setservent and endservent Funct ions
H The chroot Funct ion
H The ioctl Funct ion
H The alarm Funct ion
H Cal l ing t he Syst em select Funct ion
H The dump Funct ion
G Socket -Manipul at ion Funct ions
H The socket Funct ion
H The bind Funct ion
H The listen Funct ion
H The accept Funct ion
H The connect Funct ion
H The shutdown Funct ion
H The socketpair Funct ion
H The getsockopt and setsockopt Funct ions
H The getsockname and getpeername Funct ions
G The UNIX Syst em V IPC Funct ions
H IPC Funct ions and t he require St at ement
H The msgget Funct ion
H The msgsnd Funct ion
H The msgrcv Funct ion
H The msgctl Funct ion
H The shmget Funct ion
H The shmwrite Funct ion
H The shmread Funct ion
H The shmctl Funct ion
H The semget Funct ion
H The semop Funct ion
H The semctl Funct ion
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 16 Command-Line Options
G Specif ying Opt ions
H Specif ying Opt ions on t he Command Line
H Specif ying an Opt ion in t he Pr ogr am
G The -v Opt ion: Pr int ing t he Per l Ver sion Number
G The -c Opt ion: Checking Your Synt ax
G The -w Opt ion: Pr int ing War nings
H Checking f or Possibl e Typos
H Checking f or Redef ined Subr out ines
H Checking f or Incor r ect Compar ison Oper at or s
G The -e Opt ion: Execut ing a Singl e-Line Pr ogr am
G The -s Opt ion: Suppl ying Your Own Command-Line Opt ions
H The -s Opt ion and Ot her Command-Line Ar gument s
G The -P Opt ion: Using t he C Pr epr ocessor
H The C Pr epr ocessor : A Quick Over view
G The -I Opt ion: Sear ching f or C Incl ude Fil es
G The -n Opt ion: Oper at ing on Mul t ipl e Fil es
G The -p Opt ion: Oper at ing on Fil es and Pr int ing
G The -i Opt ion: Edit ing Fil es
H Backing Up Input Fil es Using t he -i Opt ion
G The -a Opt ion: Spl it t ing Lines
G The -F Opt ion: Specif ying t he Spl it Pat t er n
G The -0 Opt ion: Specif ying Input End-of -Line
G The -l Opt ion: Specif ying Out put End-of -Line
G The -x Opt ion: Ext r act ing a Pr ogr am f r om a Message
G Miscel l aneous Opt ions
H The -u Opt ion
H The -U Opt ion
H The -S Opt ion
H The -D Opt ion
H The -T Opt ion: Wr it ing Secur e Pr ogr ams
G The -d Opt ion: Using t he Per l Debugger
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 17 System Variables
G Gl obal Scal ar Var iabl es
H The Def aul t Scal ar Var iabl e: $_
H The Pr ogr am Name: $0
H The User ID: $< and $>
H The Gr oup ID: $( and $)
H The Ver sion Number : $]
H The Input Line Separ at or : $/
H The Out put Line Separ at or : $
H The Out put Fiel d Separ at or : $,
H The Ar r ay El ement Separ at or : $"
H The Number Out put For mat : $#
H The eval Er r or Message: $@
H The Syst em Er r or Code: $?
H The Syst em Er r or Message: $!
H The Cur r ent Line Number : $.
H Mul t il ine Mat ching: $*
H The Fir st Ar r ay Subscr ipt : $[
H Mul t idimensional Associat ive Ar r ays and t he $; Var iabl e
H The Wor d-Br eak Specif ier : $:
H The Per l Pr ocess ID: $$
H The Cur r ent Fil ename: $ARGV
H The Wr it e Accumul at or : $^A
H The Int er nal Debugging Val ue: $^D
H The Syst em Fil e Fl ag: $^F
H Cont r ol l ing Fil e Edit ing Using $^I
H The For mat For m-Feed Char act er : $^L
H Cont r ol l ing Debugging: $^P
H The Pr ogr am St ar t Time: $^T
H Suppr essing War ning Messages: $^W
H The $^X Var iabl e
G Pat t er n Syst em Var iabl es
H Ret r ieving Mat ched Subpat t er ns
H Ret r ieving t he Ent ir e Pat t er n: $&
H Ret r ieving t he Unmat ched Text : t he $` and $' Var iabl es
H The $+ Var iabl e
G Fil e Syst em Var iabl es
H The Def aul t Pr int For mat : $~
H Specif ying Page Lengt h: $=
H Lines Remaining on t he Page: $-
H The Page Header Pr int For mat : $^
H Buf f er ing Out put : $|
H The Cur r ent Page Number : $%
G Ar r ay Syst em Var iabl es
H The @_ Var iabl e
H The @ARGV Var iabl e
H The @F Var iabl e
H The @INC Var iabl e
H The %INC Var iabl e
H The %ENV Var iabl e
H The %SIG Var iabl e
G Buil t -In Fil e Var iabl es
H STDIN, STDOUT, and STDERR
H ARGV
H DATA
H The Under scor e Fil e Var iabl e
G Specif ying Syst em Var iabl e Names as Wor ds
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 18 References in Perl 5
G Int r oduct ion t o Ref er ences
G Using Ref er ences
G Using t he Backsl ash Oper at or
G Ref er ences and Ar r ays
G Mul t idimensional Ar r ays
G Ref er ences t o Subr out ines
H Using Subr out ine Templ at es
G Using Subr out ines t o Wor k wit h Mul t ipl e Ar r ays
H Pass By Val ue or By Ref er ence?
G Ref er ences t o Fil e Handl es
H What Does t he *variable Oper at or Do?
G Using Symbol ic Ref er ences Again
H Decl ar ing Var iabl es wit h Cur l y Br aces
G Mor e on Har d Ver sus Symbol ic Ref er ences
G For Mor e Inf or mat ion
G Summar y
G Q&A
G Wor kshop
H Quiz
G Exer cises
Day 19 Object-Oriented Programming in Perl
G An Int r oduct ion t o Modul es
H The Thr ee Impor t ant Rul es
G Cl asses in Per l
G Cr eat ing a Cl ass
G Bl essing a Const r uct or
H Inst ance Var iabl es
G Met hods
G Expor t ing Met hods
G Invoking Met hods
G Over r ides
G Dest r uct or s
G Inher it ance
G Over r iding Met hods
G A Few Comment s About Cl asses and Object s in Per l
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 20 Miscellaneous Features of Perl
G The require Funct ion
H The require Funct ion and Subr out ine Libr ar ies
H Using require t o Specif y a Per l Ver sion
G The $#array Var iabl es
H Cont r ol l ing Ar r ay Lengt h Using $#array
G Al t er nat ive St r ing Del imit er s
H Def ining St r ings Using <<
G Special Int er nal Val ues
G Using Back Quot es t o Invoke Syst em Commands
G Pat t er n Mat ching Using ?? and t he reset Funct ion
H Using reset wit h Var iabl es
G Ot her Feat ur es of t he <> Oper at or
H Scal ar Var iabl e Subst it ut ion and <>
H Cr eat ing a List of Fil enames
G Gl obal Indir ect Ref er ences and Al iases
G Packages
H Def ining a Package
H Swit ching Bet ween Packages
H The main Package
H Ref er r ing t o One Package f r om Anot her
H Specif ying No Cur r ent Package
H Packages and Subr out ines
H Def ining Pr ivat e Dat a Using Packages
H Packages and Syst em Var iabl es
H Accessing Symbol Tabl es
G Modul es
H Cr eat ing a Modul e
H Impor t ing Modul es Int o Your Pr ogr am
H Using Pr edef ined Modul es
G Using Per l in C Pr ogr ams
G Per l and CGI Scr ipt s
G Tr ansl at or s and Ot her Suppl ied Code
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Day 21 The Perl Debugger
G Ent er ing and Exit ing t he Per l Debugger
H Ent er ing t he Debugger
H Exit ing t he Debugger
G List ing Your Pr ogr am
H The l command
H The - Command
H The w Command
H The // and ?? Commands
H The S Command
G St epping Thr ough Pr ogr ams
H The s Command
H The n Command
H The f command
H The Car r iage-Ret ur n Command
H The r Command
G Displ aying Var iabl e Val ues
H The X Command
H The V Command
G Br eakpoint s
H The b Command
H The c Command
H The L Command and Br eakpoint s
H The d and D Commands
G Tr acing Pr ogr am Execut ion
G Line Act ions
H The a Command
H The A Command
H The < and > Commands
H Displ aying Line Act ions Using t he L Command
G Ot her Debugging Commands
H Execut ing Ot her Per l St at ement s
H The H Command: List ing Pr eceding Commands
H The ! Command: Execut ing Pr evious Commands
H The T Command: St ack Tr acing
H The p Command: Pr int ing an Expr ession
H The = Command: Def ining Al iases
H Pr edef ining Al iases
H The h Command: Debugger Hel p
G Summar y
G Q&A
G Wor kshop
H Quiz
Week 3 Week 3 in Review
Appendix A Answers
G Answer s f or Day 1, "Get t ing St ar t ed"
H Quiz
H Exer cises
G Answer s f or Day 2, "Basic Oper at or s and Cont r ol Fl ow"
H Quiz
H Exer cises
G Answer s f or Day 3, "Under st anding Scal ar Val ues"
H Quiz
H Exer cises
G Answer s f or Day 4, "Mor e Oper at or s"
H Quiz
H Exer cises
G Answer s f or Day 5, "List s and Ar r ay Var iabl es"
H Quiz
H Exer cises
G Answer s f or Day 6, "Reading f r om and Wr it ing t o Fil es"
H Quiz
H Exer cises
G Answer s f or Day 7, "Pat t er n Mat ching"
H Quiz
H Exer cises
G Answer s f or Day 8, "Mor e Cont r ol St r uct ur es"
H Quiz
H Exer cises
G Answer s f or Day 9, "Using Subr out ines"
H Quiz
H Exer cises
G Answer s f or Day 10, "Associat ive Ar r ays"
H Quiz
H Exer cises
G Answer s f or Day 11, "For mat t ing Your Out put "
H Quiz
H Exer cises
G Answer s f or Day 12, "Wor king wit h t he Fil e Syst em"
H Quiz
H Exer cises
G Answer s f or Day 13, "Pr ocess, St r ing, and Mat hemat ical Funct ions"
H Quiz
H Exer cises
G Answer s f or Day 14, "Scal ar -Conver sion and List -Manipul at ion Funct ions"
H Quiz
H Exer cises
G Answer s f or Day 15, "Syst em Funct ions"
H Quiz
H Exer cises
G Answer s f or Day 16, "Command-Line Opt ions"
H Quiz
H Exer cises
G Answer s f or Day 17, "Syst em Var iabl es"
H Quiz
H Exer cises
G Answer s f or Day 18, "Ref er ences in
Per l 5"
H Quiz
H Exer cises
G Answer s f or Day 19, "Object -Or ient ed Pr ogr amming in Per l "
H Quiz
H Exer cises
G Answer s f or Day 20, "Miscel l aneous Feat ur es of Per l "
H Quiz
H Exer cises
G Answer s f or Day 21, "The Per l Debugger "
H Quiz
Appendix B ASCI I Character Set
Credits
Copyr ight 1996 by Sams Publ ishing
SECOND EDITION
Al l r ight s r eser ved. No par t of t his book shal l be r epr oduced, st or ed in a r et r ieval
syst em, or t r ansmit t ed by any means, el ect r onic, mechanical , phot ocopying, r ecor ding, or
ot her wise, wit hout wr it t en per mission f r om t he publ isher . No pat ent l iabil it y is assumed
wit h r espect t o t he use of t he inf or mat ion cont ained her ein. Al t hough ever y pr ecaut ion
has been t aken in t he pr epar at ion of t his book, t he publ isher and aut hor assume no
r esponsibil it y f or er r or s or omissions. Neit her is any l iabil it y assumed f or damages
r esul t ing f r om t he use of t he inf or mat ion cont ained her ein. For inf or mat ion, addr ess
Sams Publ ishing, 201 W. 103r d St ., Indianapol is, IN 46290.
Int er nat ional St andar d Book Number : 0-672-30894-0 HTML conver sion by :
M/s. Leaf Wr it er s (India) Pvt . Lt d.
Website : ht t p://l eaf .st pn.sof t .net
e-mail : l eaf wr it er s@l eaf .st pn.sof t .net
Publ isher and
Pr esident
Richard K. Swadley Acquisit ions
Manager
Greg Wiegand
Devel opment
Manager
Dean Miller Managing Edit or Cindy Morrow
Mar ket ing Manager John Pierce Assist ant
Mar ket ing Manager
Kristina Perry
Acquisit ions Edit or Chris Denny Devel opment
Edit or s
Angelique Brittingham,
Keith Davenport
Sof t war e
Devel opment
Special ist
Steve Straiger Pr oduct ion Edit or Tonya R. Simpson
Copy Edit or Kimberly K. Hannel Technical Reviewer Elliotte Rusty Harold
Edit or ial
Coor dinat or
Bill Whitmer Technical Edit
Coor dinat or
Lynette Quinn
For mat t er Frank Sinclair Edit or ial
Assist ant s
Carol Ackerman, Andi
Richter Rhonda, Tinch-
Mize
Cover Designer Tim Amrhein Book Designer Gary Adair
Copy Wr it er Peter Fuller Pr oduct ion Team
Super visor
Brad Chinn
Pr oduct ion Michael Brumitt, Charlotte Clapp, Jason Hand, Sonja Hart, Louisa
Klucznik, Ayanna Lacey, Clint Lahnen, Paula Lowell, Laura Robbins,
Bobbi Satterfield, Carol Sheehan, Chris Wilcox
Acknowledgments
I woul d l ike t o t hank t he f ol l owing peopl e f or t heir hel p:
G David Mackl em at Siet ec Open Syst ems f or al l owing me t o t ake t he t ime of f t o
wor k on t he f ir st edit ion of t his book
G Ever yone at Sams Publ ishing, f or t heir ef f or t s and encour agement
G Jim Gar dner , f or t el l ing t he peopl e at Sams Publ ishing about me
I'd al so l ike t o t hank al l t hose f r iends of mine (you know who you ar e) who t ol er at ed
my going st ir -cr azy as my deadl ines appr oached.
About the Authors
David Till
David Til l is a t echnical wr it er wor king in Tor ont o, Ont ar io, Canada. He hol ds a
mast er 's degr ee in comput er science f r om t he Univer sit y of Wat er l oo; pr ogr amming
l anguages was his major f iel d of st udy. He al so has wor ked in compil er devel opment and
on ver sion-cont r ol sof t war e. He l ist s his hobbies as "wr it ing, comedy, wal king, dupl icat e
br idge, and f anat ical suppor t of t he Tor ont o Bl ue Jays."
He can be r eached via e-mail at am671@freenet.toronto.on.ca or davet@klg.com, or on
t he Wor l d Wide Web at http://www.interlog.com/~davet/.
Kamran Husain
Kamr an Husain is a sof t war e consul t ant wit h exper ience in UNIX syst em pr ogr amming.
He has dabbl ed in al l sor t s of sof t war e f or r eal -t ime syst ems appl icat ions,
t el ecommunicat ions, seismic dat a acquisit ion and navigat ion, X Window/Mot if and
Micr osof t Windows appl icat ions. He r ef uses t o divul ge any mor e of his qual if icat ions.
Kamr an of f er s consul t ing ser vices and t r aining cl asses t hr ough his company, MPS Inc., in
Houst on, Texas. He is an al umnus of t he Univer sit y of Texas at Aust in.
You can r each Kamr an t hr ough Sams Publ ishing or via e-mail at khusain@neosoft.com or
mpsi@aol.com.
Introduction
This book is designed t o t each you t he Per l pr ogr amming l anguage in just 21 days. When
you f inish r eading t his book, you wil l have l ear ned why Per l is gr owing r apidl y in
popul ar it y: It is power f ul enough t o per f or m many usef ul , sophist icat ed pr ogr amming
t asks, yet it is easy t o l ear n and use.
Who Should Read This Book?
No pr evious pr ogr amming exper ience is r equir ed f or you t o l ear n ever yt hing you need t o
know about pr ogr amming wit h Per l f r om t his book. In par t icul ar , no knowl edge of t he C
pr ogr amming l anguage is r equir ed. If you ar e f amil iar wit h ot her pr ogr amming
l anguages, l ear ning Per l wil l be a snap. The onl y assumpt ion t his book does make is t hat
you ar e f amil iar wit h t he basics of using t he UNIX oper at ing syst em.
Special Features of This Book
This book cont ains some special el ement s t hat hel p you under st and Per l f eat ur es and
concept s as t hey ar e int r oduced:
G Synt ax boxes
G DO/DON'T boxes
G Not es
G War nings
G Tips
Syntax boxes expl ain some of t he mor e compl icat ed f eat ur es of Per l , such as t he cont r ol
st r uct ur es. Each synt ax box consist s of a f or mal def init ion of t he f eat ur e f ol l owed by
an expl anat ion of t he el ement s of t he f eat ur e. Her e is an exampl e of a synt ax box:
The synt ax of t he for st at ement is
for (expr1; expr2; expr3) {
statement_block
}
expr1 is t he l oop init ial izer . It is eval uat ed onl y once, bef or e t he st ar t of t he l oop.
expr2 is t he condit ional expr ession t hat t er minat es t he l oop. The condit ional expr ession
in expr2 behaves just l ike t he ones in while and if st at ement s: If it s val ue is zer o, t he
l oop is t er minat ed, and if it s val ue is nonzer o, t he l oop is execut ed.
statement_block is t he col l ect ion of st at ement s t hat is execut ed if (and when) expr2 has
a nonzer o val ue.
expr3 is execut ed once per it er at ion of t he l oop, and is execut ed af t er t he l ast
st at ement in statement_block is execut ed.
Don't t r y t o under st and t his def init ion yet !
DO/DON'T boxes pr esent t he do's and don't s f or a par t icul ar t ask or f eat ur e. Her e is an
exampl e of such a box:
DON' T conf use t he | oper at or (bit wise OR) wit h t he ||
oper at or (l ogical OR).
DO make sur e you ar e using t he pr oper bit wise oper at or .
It 's easy t o sl ip and assume you want bit wise OR when
you r eal l y want bit wise AND. (Tr ust me.
Notes ar e expl anat ions of int er est ing pr oper t ies of a par t icul ar pr ogr am f eat ur e. Her e is
an exampl e of a not e:
NOTE
In l ef t -just if ied out put , t he val ue being displ ayed
appear s at t he l ef t end of t he val ue f iel d. In r ight -
just if ied out put , t he val ue being displ ayed appear s at t he
r ight end of t he val ue f iel d.
Warnings war n you of pr ogr amming pit f al l s t o avoid. Her e is a t ypical war ning:
You cannot use t he last st at ement inside t he do
st at ement . The do st at ement , al t hough it behaves l ike
t he ot her cont r ol st r uct ur es, is act ual l y impl ement ed
dif f er ent l y.
Tips ar e hint s on how t o wr it e your Per l pr ogr ams bet t er . Her e is an exampl e of a t ip:
TIP
It is a good idea t o use al l upper case l et t er s f or your
f il e var iabl e names. This makes it easier t o dist inguish
f il e var iabl e names f r om ot her var iabl e names and f r om
r eser ved wor ds.
Programming Examples
Each f eat ur e of Per l is il l ust r at ed by exampl es of it s use. In addit ion, each chapt er of
t his book cont ains many usef ul pr ogr amming exampl es compl et e wit h expl anat ions; t hese
exampl es show you how you can use Per l f eat ur es in your own pr ogr ams.
Each exampl e cont ains a l ist ing of t he pr ogr am, t he input r equir ed by and t he out put
gener at ed by t he pr ogr am, and an anal ysis of how t he pr ogr am wor ks. Special icons ar e
used t o point out each par t of t he exampl e: Type, Input -Out put , and Anal ysis.
In t he Input -Out put exampl e f ol l owing List ing IN.1, t her e ar e some special t ypogr aphic
convent ions. The input you ent er is shown in bold monospace t ype, and t he out put
gener at ed by t he syst em or t he pr ogr am is shown in plain monospace t ype. The syst em
pr ompt ($ in t he exampl es in t his book) is shown so t hat you know when a command is t o
be ent er ed on t he command l ine.
List ing IN.1. A simpl e Per l pr ogr am wit h comment s.
1: #!/usr/local/bin/perl
2: # this program reads a line of input, and writes the line
3: # back out
4: $inputline = <STDIN>; # read a line of input
5: print( $inputline ); # write the line out
$ programIN_1
This is a line of input.
This is a line of input.
$
Line 1 is t he header comment . Lines 2 and 3 ar e comment s, not execut abl e l ines
of code. Line 4 r eads a l ine of input . Line 5 wr it es t he l ine of input on your scr een.
End-of-Day Q& A and Workshop
Each day ends wit h a Q&A sect ion cont aining answer s t o common quest ions r el at ing t o
t hat day's mat er ial . Ther e al so is a Wor kshop at t he end of each day t hat consist s of
quiz quest ions and pr ogr amming exer cises. The exer cises of t en incl ude BUG BUSTER
exer cises t hat hel p you spot some of t he common bugs t hat cr op up in Per l pr ogr ams. The
answer s t o t hese quiz quest ions as wel l as sampl e sol ut ions f or t he exer cises ar e
pr esent ed in Appendix A, "Answer s."
Conventions Used in This Book
This book uses dif f er ent t ypef aces t o hel p you dif f er ent iat e bet ween Per l code and
r egul ar Engl ish, and al so t o hel p you ident if y impor t ant concept s.
G Act ual Per l code is t ypeset in a special monospace f ont . You'l l see t his f ont used in
l ist ings and t he Input -Out put exampl es, as wel l as in code snippet s. In t he
expl anat ions of Per l f eat ur es, commands, f il enames, st at ement s, var iabl es, and
any t ext you see on t he scr een al so ar e t ypeset in t his f ont .
G Command input and anyt hing t hat you ar e supposed t o ent er appear s in a bold
monospace f ont . You'l l see t his mainl y in t he Input -Out put exampl es.
G Pl acehol der s in synt ax descr ipt ions appear in an italic monospace f ont . Repl ace
t he pl acehol der wit h t he act ual f il ename, par amet er , or what ever el ement it
r epr esent s.
G Italics highl ight t echnical t er ms when t hey f ir st appear in t he t ext and ar e
somet imes used t o emphasize impor t ant point s.
What You'll Learn in 21 Days
In your f ir st week of l ear ning Per l , you'l l l ear n enough of t he basics of Per l t o wr it e
many usef ul Per l pr ogr ams. Her e's a summar y of what you'l l l ear n in Week 1:
Day 1, " Get t ing St ar t ed," t el l s you how t o get Per l , how t o r un Per l
pr ogr ams, and how t o r ead f r om your keyboar d and wr it e t o your scr een.
Day 2, " Basic Oper at or s and Cont r ol Fl ow," t eaches you about simpl e
ar it hmet ic, how t o assign a val ue t o a scal ar var iabl e, and how t o cont r ol
execut ion using condit ional st at ement s.
Day 3, " Under st anding Scal ar Val ues," t eaches you about int eger s,
f l oat ing-point number s, and char act er st r ings. It al so shows you t hat al l
t hr ee ar e int er changeabl e in Per l .
Day 4, " Mor e Oper at or s," t el l s you al l about oper at or s and expr essions in
Per l and t al ks about oper at or associat ivit y and pr ecedence.
Day 5, " List s and Ar r ay Var iabl es," int r oduces you t o l ist s, which ar e
col l ect ions of val ues, and t o ar r ay var iabl es, which st or e l ist s.
Day 6, " Reading f r om and Wr it ing t o Fil es," t el l s you how t o int er act
wit h your f il e syst em by r eading f r om input f il es, wr it ing t o out put f il es,
and t est ing f or par t icul ar f il e at t r ibut es.
Day 7, " Pat t er n Mat ching," descr ibes pat t er n-mat ching in Per l and shows
how you can subst it ut e val ues and t r ansl at e set s of char act er s in t ext
st r ings.
By t he end of Week 2, you'l l have mast er ed al most al l t he f eat ur es of Per l ; you'l l al so
have l ear ned about many of t he l ibr ar y f unct ions suppl ied wit h t he l anguage. Her e's a
summar y of what you'l l l ear n:
Day 8, " Mor e Cont r ol St r uct ur es," discusses t he cont r ol f l ow
st at ement s not pr eviousl y cover ed.
Day 9, " Using Subr out ines," shows how you can br eak your pr ogr am int o
smal l er , mor e manageabl e, chunks.
Day 10, " Associat ive Ar r ays," int r oduces one of t he most power f ul and
usef ul const r uct s in Per l -ar r ays-and it shows how you can use t hese ar r ays
t o simul at e ot her dat a st r uct ur es.
Day 11, " For mat t ing Your Out put ," shows how you can use Per l t o
pr oduce t idy r epor t s.
Day 12, " Wor king wit h t he Fil e Syst em," shows how you can int er act wit h
your syst em's dir ect or y st r uct ur e.
Day 13, " Pr ocess, St r ing, and Mat hemat ical Funct ions," descr ibes t he
l ibr ar y f unct ions t hat int er act wit h pr ocesses r unning on t he syst em. It
al so descr ibes t he f unct ions t hat per f or m t r igonomet r ic and ot her
mat hemat ical oper at ions, and t he f unct ions t hat oper at e on st r ings.
Day 14, " Scal ar -Conver sion and List -Manipul at ion Funct ions," descr ibes
t he l ibr ar y f unct ions t hat conver t val ues f r om one f or m t o anot her and
t he f unct ions t hat wor k wit h l ist s and ar r ay var iabl es.
By t he end of Week 3, you'l l know al l t he f eat ur es and capabil it ies of Per l . It cover s
t he r est of t he Per l l ibr ar y f unct ions and descr ibes some of t he mor e esot er ic concept s
of t he l anguage. Her e's a summar y of what you'l l l ear n:
Day 15, " Syst em Funct ions," descr ibes t he f unct ions t hat manipul at e t he
Ber kel ey UNIX and UNIX Syst em V envir onment s.
Day 16, " Command-Line Opt ions," descr ibes t he opt ions you can suppl y wit h
Per l t o cont r ol how your pr ogr am r uns.
Day 17, " Syst em Var iabl es," descr ibes t he buil t -in var iabl es t hat ar e
incl uded aut omat ical l y as par t of ever y Per l pr ogr am.
Day 18, " Ref er ences in Per l 5," descr ibes t he point er and r ef er ence
f eat ur es of Per l 5, incl uding mul t i-dimensional ar r ays.
Day 19, " Obj ect -Or ient ed Pr ogr amming in Per l ," descr ibes t he object -
or ient ed capabil it ies added t o Per l 5. These enabl e you t o hide inf or mat ion
and divide your pr ogr am int o individual f il e modul es.
Day 20, " Miscel l aneous Feat ur es of Per l ," cover s some of t he mor e exot ic
or obscur e f eat ur es of t he l anguage.
Day 21, " The Per l Debugger ," shows you how t o use t he Per l debugger t o
discover er r or s quickl y.

Week
1
Week at a Glance
CONTENTS
G Wher e You'r e Going
In your f ir st week of t eaching your sel f Per l , you'l l l ear n enough of t he basics t o wr it e
many usef ul Per l pr ogr ams. Al t hough some exper ience in using a pr ogr amming l anguage
wil l be an advant age as you r ead t his book, it is not r equir ed. In par t icul ar , you don't
need t o know t he C pr ogr amming l anguage bef or e you r ead t his book.
To use t his book ef f ect ivel y, you shoul d be abl e t o t r y out some of t he f eat ur es of Per l
as you l ear n t hem. To do t his, you shoul d have Per l r unning on your syst em. If you don't
have Per l , Day 1, "Get t ing St ar t ed," t el l s how you can get it f or f r ee.
Each chapt er of t his book cont ains quiz and exer cise quest ions t hat t est you on t he
mat er ial cover ed in t he day's l esson. These quest ions ar e answer ed in Appendix A,
"Answer s."
Where You're Going
The f ir st week cover s t he essent ial s of Per l . Her e's a summar y of what you'l l l ear n.
Day 1, "Get t ing St ar t ed," t el l s you how t o get Per l , how t o r un Per l pr ogr ams, and how
t o r ead input f r om your keyboar d and wr it e out put t o your scr een.
Day 2, "Basic Oper at or s and Cont r ol Fl ow," t eaches you about simpl e ar it hmet ic, how t o
assign a val ue t o a scal ar var iabl e, and how t o cont r ol execut ion using condit ional
st at ement s.
Day 3, "Under st anding Scal ar Val ues," t eaches you about int eger s, f l oat ing-point
number s, and char act er st r ings. It al so shows you t hat al l t hr ee ar e int er changeabl e in
Per l .
Day 4, "Mor e Oper at or s," t el l s you al l about oper at or s and expr essions in Per l and t al ks
about oper at or associat ivit y and pr ecedence.
Day 5, "List s and Ar r ay Var iabl es," int r oduces you t o l ist s, which ar e col l ect ions of
val ues, and t o ar r ay var iabl es, which st or e l ist s.
Day 6, "Reading f r om and Wr it ing t o Fil es," t el l s you how t o int er act wit h your f il e
syst em by r eading f r om input f il es, wr it ing t o out put f il es, and t est ing f or par t icul ar
f il e at t r ibut es.
Final l y, Day 7, "Pat t er n Mat ching," descr ibes pat t er n mat ching in Per l and shows how
you can subst it ut e val ues and t r ansl at e set s of char act er s in t ext st r ings.
This is quit e a bit of mat er ial t o l ear n in one week; however , by t he end of t he week
you'l l know most of t he essent ial s of Per l and wil l be abl e t o wr it e many usef ul
pr ogr ams.

Chapter 1
Getting Started
CONTENTS
G What Is Per l ?
G How Do I Find Per l ?
H Wher e Do I Get Per l ?
H Ot her Pl aces t o Get Per l
G A Sampl e Per l Pr ogr am
G Running a Per l Pr ogr am
H If Somet hing Goes Wr ong
G The Fir st Line of Your Per l Pr ogr am: How Comment s Wor k
H Comment s
G Line 2: St at ement s, Tokens, and <STDIN>
H St at ement s and Tokens
H Tokens and Whit e Space
H What t he Tokens Do: Reading f r om St andar d Input
G Line 3: Wr it ing t o St andar d Out put
H Funct ion Invocat ions and Ar gument s
G Er r or Messages
G Int er pr et ive Languages Ver sus Compil ed Languages
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Wel come t o Teach Yourself Perl 5 in 21 Days. Today you'l l l ear n about t he f ol l owing:
G What Per l is and why Per l is usef ul
G How t o get Per l if you do not al r eady have it
G How t o r un Per l pr ogr ams
G How t o wr it e a ver y simpl e Per l pr ogr am
G The dif f er ence bet ween int er pr et ive and compil ed pr ogr amming l anguages
G What an al gor it hm is and how t o devel op one
What Is Perl?
Per l is an acr onym, shor t f or Pr act ical Ext r act ion and Repor t Language. It was designed
by Lar r y Wal l as a t ool f or wr it ing pr ogr ams in t he UNIX envir onment and is
cont inual l y being updat ed and maint ained by him.
For it s many f ans, Per l pr ovides t he best of sever al wor l ds. For inst ance:
G Per l has t he power and f l exibil it y of a high-l evel pr ogr amming l anguage such as
C. In f act , as you wil l see, many of t he f eat ur es of t he l anguage ar e bor r owed
f r om C.
G Like shel l scr ipt l anguages, Per l does not r equir e a special compil er and l inker t o
t ur n t he pr ogr ams you wr it e int o wor king code. Inst ead, al l you have t o do is
wr it e t he pr ogr am and t el l Per l t o r un it . This means t hat Per l is ideal f or
pr oducing quick sol ut ions t o smal l pr ogr amming pr obl ems, or f or cr eat ing
pr ot ot ypes t o t est pot ent ial sol ut ions t o l ar ger pr obl ems.
G Per l pr ovides al l t he f eat ur es of t he scr ipt l anguages sed and awk, pl us f eat ur es
not f ound in eit her of t hese t wo l anguages. Per l al so suppor t s a sed-t o-Per l
t r ansl at or and an awk-t o-Per l t r ansl at or .
In shor t , Per l is as power f ul as C but as convenient as awk, sed, and shel l scr ipt s.
NOTE
This book assumes t hat you ar e f amil iar wit h t he basics
of using t he UNIX oper at ing syst em
As you'l l see, Per l is ver y easy t o l ear n. Indeed, if you ar e f amil iar wit h ot her
pr ogr amming l anguages, l ear ning Per l is a snap. Even if you have ver y l it t l e
pr ogr amming exper ience, Per l can have you wr it ing usef ul pr ogr ams in a ver y shor t t ime.
By t he end of Day 2, "Basic Oper at or s and Cont r ol Fl ow," you'l l know enough about
Per l t o be abl e t o sol ve many pr obl ems.
How Do I Find Perl?
To f ind out whet her Per l al r eady is avail abl e on your syst em, do t he f ol l owing:
G If you ar e cur r ent l y wor king in a UNIX pr ogr amming envir onment , check t o see
whet her t he f il e /usr/local/bin/perl exist s.
G If you ar e wor king in any ot her envir onment , check t he pl ace wher e you
nor mal l y keep your execut abl e pr ogr ams, or check t he dir ect or ies accessibl e f r om
your PATH envir onment var iabl e.
If you do not f ind Per l in t his way, t al k t o your syst em administ r at or and ask whet her
she or he has Per l r unning somewher e el se. If you don't have Per l r unning in your
envir onment , don't despair -r ead on!
Where Do I Get Perl?
One of t he r easons Per l is becoming so popul ar is t hat it is avail abl e f r ee of char ge t o
anyone who want s it . If you ar e on t he Int er net , you can obt ain a copy of Per l wit h f il e-
t r ansf er pr ot ocol (FTP). The f ol l owing is a sampl e FTP session t hat t r ansf er s a copy of
t he Per l dist r ibut ion. The it ems shown in bol df ace t ype ar e what you woul d ent er
dur ing t he session.
$ ftp prep.ai.mit.edu
Connected to prep.ai.mit.edu.
220 aeneas FTP server (Version wu-2.4(1) Thu Apr 14 20:21:35 EDT 1994)
ready.
Name (prep.ai.mit.edu:dave): anonymous
331 Guest login ok, send your complete e-mail address as password.
Password:
230-Welcome, archive user!
230-
230-If you have problems downloading and are seeing "Access denied" or
230-"Permission denied", please make sure that you started your FTP
230-client in a directory to which you have write permission.
230-
230-If you have any problems with the GNU software or its
downloading,
230-please refer your questions to <gnu@PREP.AI.MIT.EDU>. If you have
any
230-other unusual problems, please report them to
<root@aeneas.MIT.EDU>.
230-
230-If you do have problems, please try using a dash (-) as the first
230-character of your password - this will turn off the continuation
230-messages that may be confusing your FTP client.
230-
230 Guest login ok, access restrictions apply.
ftp> cd pub/gnu
250-If you have problems downloading and are seeing "Access denied" or
250-"Permission denied", please make sure that you started your FTP
250-client in a directory to which you have write permission.
250-
250-Please note that all files ending in '.gz' are compressed with
250-'gzip', not with the unix 'compress' program. Get the file README
250- and read it for more information.
250-
250-Please read the file README
250- it was last modified on Thu Feb 1 15:00:50 1996 - 32 days ago
250-Please read the file README-about-.diff-files
250- it was last modified on Fri Feb 2 12:57:14 1996 - 31 days ago
250-Please read the file README-about-.gz-files
250- it was last modified on Wed Jun 14 16:59:43 1995 - 264 days ago
250 CWD command successful.
ftp> binary
200 Type set to I.
ftp> get perl-5.001.tar.gz
200 PORT command successful.
150 Opening ASCII mode data connection for perl-5.001.tar.gz (1130765
bytes).
226 Transfer complete.
1130765 bytes received in 9454 seconds (1.20 Kbytes/s)
ftp> quit
221 Goodbye.
$
The commands ent er ed in t his session ar e expl ained in t he f ol l owing st eps. If some of
t hese st eps ar e not f amil iar t o you, ask your syst em administ r at or f or hel p.
1. The command
$ ftp prep.ai.mit.edu
connect s you t o t he main Fr ee Sof t war e Foundat ion sour ce deposit or y at MIT.
2. The user ID anonymous t el l s FTP t hat you want t o per f or m an anonymous FTP
oper at ion.
3. When FTP asks f or a passwor d, ent er your user ID and net wor k addr ess. This l et s
t he MIT syst em administ r at or know who is using t he MIT ar chives. (For secur it y
r easons, t he passwor d is not act ual l y displ ayed when you t ype it .)
4. The command cd pub/gnu set s your cur r ent wor king dir ect or y t o be t he dir ect or y
cont aining t he Per l sour ce.
5. The binary command t el l s FTP t hat t he f il e you'l l be r eceiving is a f il e t hat
cont ains unr eadabl e (non-t ext ) char act er s.
6. The get command copies t he f il e perl-5.001.tar.gz f r om t he MIT sour ce
deposit or y t o your own sit e. (It 's usual l y best t o do t his in of f -peak hour s t o make
t hings easier f or ot her Int er net user s-it t akes awhil e.) This f il e is quit e l ar ge
because it cont ains al l t he sour ce f il es f or Per l bundl ed t oget her int o a singl e
f il e.
7. The quit command disconnect s f r om t he MIT sour ce r eposit or y and r et ur ns you t o
your own syst em.
Once you've r et r ieved t he Per l dist r ibut ion, do t he f ol l owing:
1. Cr eat e a dir ect or y and move t he f il e you just r eceived, perl-5.001.tar.gz, t o t his
dir ect or y. (Or , al t er nat ivel y, move it t o a dir ect or y al r eady r eser ved f or t his
pur pose.)
2. The perl-5.001.tar.gz f il e is compr essed t o save space. To uncompr ess it , ent er t he
command
$ gunzip perl-5.001.tar.gz
gunzipis t he GNU uncompr ess pr ogr am. If it 's not avail abl e on your syst em, see
your syst em administ r at or . (You can, in f act , r et r ieve it f r om
prep.ai.mit.eduusing anonymous FTP wit h t he same commands you used t o
r et r ieve t he Per l dist r ibut ion.)
When you r un gunzip, t he f il e perl-5.001.tar.gzwil l be r epl aced by perl-
5.001.tar, which is t he uncompr essed ver sion of t he Per l dist r ibut ion f il e.
3. The next st ep is t o unpack t he Per l dist r ibut ion. In ot her wor ds, use t he
inf or mat ion in t he Per l dist r ibut ion t o cr eat e t he Per l sour ce f il es. To do t his,
ent er t he f ol l owing command:
$ tar xvf - <perl-5.001.tar
As t his command execut es, it cr eat es each sour ce f il e in t ur n and displ ays t he
name and size of each f il e as it is cr eat ed. The tarcommand al so cr eat es
subdir ect or ies wher e appr opr iat e; t his ensur es t hat t he Per l sour ce f il es ar e
or ganized in a l ogical way.
4. Using your f avor it e C compil er , compil e t he Per l sour ce code using t he makef il e
pr ovided. (This makef il e shoul d have been cr eat ed when t he sour ce f il es wer e
unpacked in t he l ast st ep.)
5. Pl ace t he compil ed Per l execut abl e int o t he dir ect or y wher e you nor mal l y keep
your execut abl es. On UNIX syst ems, t his dir ect or y usual l y is cal l ed
/usr/local/bin, and Per l usual l y is named /usr/local/bin/perl.
You might need your syst em administ r at or 's hel p t o do t his because you might not have
t he necessar y per missions.
Other Places to Get Perl
If you cannot access t he MIT sit e f r om wher e you ar e, you can get Per l f r om t he
f ol l owing sit es using anonymous FTP:
Nor t h Amer ica
Site Location
ftp.netlabs.com
Int er net addr ess 192.94.48.152
Directory /pub/outgoing/perl5.0
ftp.cis.ufl.edu
Int er net addr ess 128.227.100.198
Directory /pub/perl/src/5.0
ftp.uu.net
Int er net addr ess 192.48.96.9
Directory /languages/perl
ftp.khoros.unm.edu
Int er net addr ess 198.59.155.28
Directory /pub/perl
ftp.cbi.tamucc.edu
Int er net addr ess 165.95.1.3
Directory /pub/duff/Perl
ftp.metronet.com
Int er net addr ess 192.245.137.1
Directory /pub/perl/sources
genetics.upenn.edu
Int er net addr ess 128.91.200.37
Directory /perl5
Eur ope
Site Location
ftp.cs.ruu.nl
Int er net addr ess 131.211.80.17
Directory /pub/PERL/perl5.0/src
ftp.funet.fi
Int er net addr ess 128.214.248.6
Directory
/pub/languages/perl/ports/perl5
ftp.zrz.tu-
berlin.de
Int er net addr ess 130.149.4.40
Directory /pub/unix/perl
src.doc.ic.ac.uk
Int er net addr ess 146.169.17.5
Directory /packages/perl5
Aust r al ia
Site Location
sungear.mame.mu.oz.au
Int er net addr ess 128.250.209.2
Directory /pub/perl/src/5.0
Sout h Amer ica
Site Location
ftp.inf.utfsm.cl
Int er net addr ess 146.83.198.3
Directory /pub/gnu
You al so can obt ain Per l f r om most sit es t hat st or e GNU sour ce code, or f r om any sit e
t hat ar chives t he Usenet newsgr oup comp.sources.unix.
A Sample Perl Program
Now t hat Per l is avail abl e on your syst em, it 's t ime t o show you a simpl e pr ogr am t hat
il l ust r at es how easy it is t o use Per l . List ing 1.1 is a simpl e pr ogr am t hat asks f or a l ine
of input and wr it es it out .

List ing 1.1. A simpl e Per l pr ogr am t hat r eads and wr it es a l ine of input .
1: #!/usr/local/bin/perl
2: $inputline = <STDIN>;
3: print( $inputline );

$program1_1
This is my line of input.
This is my line of input.
$

Line 1 is t he header comment . Line 2 r eads a l ine of input . Line 3 wr it es t he l ine of input
back t o your scr een.
The f ol l owing sect ions descr ibe how t o cr eat e and r un t his pr ogr am, and t hey descr ibe it
in mor e det ail .
Running a Perl Program
To r un t he pr ogr am shown in List ing 1.1, do t he f ol l owing:
1. Using your f avor it e edit or , t ype t he pr evious pr ogr am and save it in a f il e cal l ed
program1_1.
2. Tel l t he syst em t hat t his f il e cont ains execut abl e st at ement s. To do t his in t he
UNIX envir onment , ent er t he command
$ chmod +x program1_1
3. Run t he pr ogr am by ent er ing t he command
$ program1_1
When you r un program1_1, it wait s f or you t o ent er a l ine of input . Af t er you ent er t he
l ine of input , program1_1 pr int s what you ent er ed, as f ol l ows:
$ program1_1
This is my line of input.
This is my line of input.
$
If Something Goes Wrong
If List ing 1.1 is st or ed in t he f il e program1_1 and r un accor ding t o t he pr eceding st eps,
t he pr ogr am shoul d r un successf ul l y. If t he pr ogr am doesn't r un, one of t wo t hings has
l ikel y happened:
G The syst em can't f ind t he f il e program1_1.
G The syst em can't f ind Per l .
If you r eceive t he er r or message
program1_1 not found
or somet hing simil ar , your syst em coul dn't f ind t he f il e program1_1. To t el l t he syst em
wher e program1_1 is l ocat ed, you can do one of t wo t hings in a UNIX envir onment :
G Ent er t he command ./program1_1, which gives t he syst em t he pat hname of
program1_1 r el at ive t o t he cur r ent dir ect or y.
G Add t he cur r ent dir ect or y . t o your PATH envir onment var iabl e. This t el l s t he
syst em t o sear ch in t he cur r ent dir ect or y when l ooking f or execut abl e pr ogr ams
such as program1_1.
If you r eceive t he message
/usr/local/bin/perl not found
or somet hing simil ar , t his means t hat Per l is not inst al l ed pr oper l y on your machine. See
t he sect ion "How Do I Find Per l ?" ear l ier t oday, f or mor e det ail s.
If you don't under st and t hese inst r uct ions or ar e st il l having t r oubl e r unning List ing
1.1, t al k t o your syst em administ r at or .
The First Line of Your Perl Program: How Comments
Work
Now t hat you've r un your f ir st Per l pr ogr am, l et 's l ook at each l ine of List ing 1.1 and
f igur e out what it does.
Line 1 of t his pr ogr am is a special l ine t hat t el l s t he syst em t hat t his is a Per l pr ogr am:
#!/usr/local/bin/perl
Let 's br eak t his l ine down, one par t at a t ime:
G The f ir st char act er in t he l ine, t he # char act er , is t he Per l comment character. It
t el l s t he syst em t hat t his l ine is not an execut abl e inst r uct ion.
G The ! char act er is a special char act er ; it indicat es what t ype of pr ogr am t his is.
(You don't need t o wor r y about t he det ail s of what t he ! char act er does. Al l you
have t o do is r emember t o incl ude it .)
G The pat h /usr/local/bin/perl is t he l ocat ion of t he Per l execut abl e on your
syst em. This execut abl e interprets your pr ogr am; in ot her wor ds, it f igur es out what
you want t o do and t hen does it . Because t he Per l execut abl e has t he job of
int er pr et ing Per l inst r uct ions, it usual l y is cal l ed t he Perl interpreter.
If , af t er r eading t his, you st il l don't under st and t he meaning of t he l ine
#!/usr/local/bin/perl don't wor r y. The act ual specif ics of what it does ar e not
impor t ant f or our pur poses in t his book. Just r emember t o incl ude it as t he f ir st l ine of
your pr ogr am, and Per l wil l t ake it f r om t her e.
NOTE
If you ar e r unning Per l on a syst em ot her t han UNIX,
you might need t o r epl ace t he l ine
#!/usr/local/bin/perl wit h some ot her l ine indi-cat ing
t he l ocat ion of t he Per l int er pr et er on your syst em. Ask
your syst em administ r at or f or det ail s on what you need
t o incl ude her e.
Af t er you have f ound out what t he pr oper f ir st l ine is in
your envir onment , incl ude t hat l ine as t he f ir st l ine of
ever y Per l pr ogr am you wr it e, and you'r e al l set
Comments
As you have just seen, t he f ir st char act er of t he l ine
#!/usr/local/bin/perl
is t he comment character, #. When t he Per l int er pr et er sees t he #, it ignor es t he r est of
t hat l ine.
Comment s can be appended t o l ines cont aining code, or t hey can be l ines of t heir own:
$inputline = <STDIN>; # this line contains an appended comment
# this entire line is a comment
You can-and shoul d-use comment s t o make your pr ogr ams easier t o under st and. List ing
1.2 is t he simpl e pr ogr am you saw ear l ier , but it has been modif ied t o incl ude comment s
expl aining what t he pr ogr am does.
NOTE
As you wor k t hr ough t he l essons in t his book and cr eat e
your own pr ogr ams-such as t he one in List ing 1.2-you
can, of cour se, name t hem anyt hing you want . For
il l ust r at ion and discussion pur poses, I've adopt ed t he
convent ion of using a name t hat cor r esponds t o t he
l ist ing number . For exampl e, t he pr ogr am in List ing 1.2 is
cal l ed program1_2.
The pr ogr am name is used in t he Input -Out put exampl es
such as t he one f ol l owing t his l ist ing, as wel l as in t he
Anal ysis sect ion wher e t he l ist ing is discussed in det ail .
When you f ol l ow t he Input -Out put exampl e, just
r emember t o subst it ut e your pr ogr am's name f or t he one
shown in t he exampl e

List ing 1.2. A simpl e Per l pr ogr am wit h comment s.
1: #!/usr/local/bin/perl
2: # this program reads a line of input, and writes the line
3: # back out
4: $inputline = <STDIN>; # read a line of input
5: print( $inputline ); # write the line out

$ program1_2
This is a line of input.
This is a line of input.
$

The behavior of t he pr ogr am in List ing 1.2 is ident ical t o t hat of List ing 1.1 because t he
act ual code is t he same. The onl y dif f er ence is t hat List ing 1.2 has comment s in it
Not e t hat in an act ual pr ogr am, comment s nor mal l y ar e used onl y t o expl ain
compl icat ed code or t o indicat e t hat t he f ol l owing l ines of code per f or m a specif ic t ask.
Because Per l inst r uct ions usual l y ar e pr et t y st r aight f or war d, Per l pr ogr ams don't need
t o have a l ot of comment s.
DO use comment s whenever you t hink t hat a l ine of code
is not easy t o under st and.
DON' T cl ut t er up your code wit h unnecessar y comment s.
The goal is r eadabil it y. If a comment makes a pr ogr am
easier t o r ead, incl ude it . Ot her wise, don't bot her .
DON' T put anyt hing el se af t er /usr/local/bin/perl in
t he f ir st l ine:
#!/usr/local/bin/perl
This l ine is a special comment l ine, and it is not t r eat ed
l ike t he ot her s.
Line 2: Statements, Tokens, and <STDIN>
Now t hat you've l ear ned what t he f ir st l ine of List ing 1.1 does, l et 's t ake a l ook at l ine
2:
$inputline = <STDIN>;
This is t he f ir st l ine of code t hat act ual l y does any wor k. To under st and what t his l ine
does, you need t o know what a Per l st at ement is and what it s component s ar e.
Statements and Tokens
The l ine of code you have just seen is an exampl e of a Per l statement. Basical l y, a
st at ement is one t ask f or t he Per l int er pr et er t o per f or m. A Per l pr ogr am can be
t hought of as a col l ect ion of st at ement s per f or med one at a t ime.
When t he Per l int er pr et er sees a st at ement , it br eaks t he st at ement down int o smal l er
unit s of inf or mat ion. In t his exampl e, t he smal l er unit s of inf or mat ion ar e $inputline, =,
<STDIN>, and ;. Each of t hese smal l er unit s of inf or mat ion is cal l ed a token.
Tokens and White Space
Tokens can nor mal l y be separ at ed by as many spaces and t abs as you l ike. For exampl e,
t he f ol l owing st at ement s ar e ident ical in Per l :
$inputline = <STDIN>;
$inputline=<STDIN>;
$inputline = <STDIN>;
Your st at ement s can t ake up as many l ines of code as you l ike. For exampl e, t he
f ol l owing st at ement is equival ent t o t he ones above:
$inputline
=
<STDIN>
;
The col l ect ion of spaces, t abs, and new l ines separ at ing one t oken f r om anot her is
known as white space.
When pr ogr amming in Per l , you shoul d use whit e space t o make your pr ogr ams mor e
r eadabl e. The exampl es in t his book use whit e space in t he f ol l owing ways:
G New st at ement s al ways st ar t on a new l ine.
G One bl ank space is used t o separ at e one t oken f r om anot her (except in special
cases, some of which you'l l see t oday).
What the Tokens Do: Reading from Standard Input
As you've seen al r eady, t he st at ement
$inputline = <STDIN>;
consist s of f our t okens: $inputline, =, <STDIN>, and ;. The f ol l owing subsect ions expl ain
what each of t hese t okens does.
The $inputline and = Tokens
The f ir st t oken in l ine 1, $inputline (at t he l ef t of t he st at ement ), is an exampl e of a
scalar variable. In Per l , a scal ar var iabl e can st or e one piece of inf or mat ion.
The = t oken, cal l ed t he assignment operator, t el l s t he Per l int er pr et er t o st or e t he it em
specif ied by t he t oken t o t he r ight of t he = in t he pl ace specif ied by t he t oken t o t he l ef t
of t he =. In t his exampl e, t he it em on t he r ight of t he assignment oper at or is t he <STDIN>
t oken, and t he it em t o t he l ef t of t he assignment oper at or is t he $inputline t oken.
Thus, <STDIN> is st or ed in t he scal ar var iabl e $inputline.
Scal ar var iabl es and assignment oper at or s ar e cover ed in mor e det ail on Day 2, "Basic
Oper at or s and Cont r ol Fl ow."
The <STDIN> Token and the Standard Input File
The next t oken, <STDIN>, r epr esent s a l ine of input f r om t he standard input file. The
st andar d input f il e, or STDIN f or shor t , t ypical l y cont ains ever yt hing you ent er when
r unning a pr ogr am.
For exampl e, when you r un program1_1 and ent er
This is a line of input.
t he l ine you ent er is st or ed in t he st andar d input f il e.
The <STDIN> t oken t el l s t he Per l int er pr et er t o r ead one l ine f r om t he st andar d input
f il e, wher e a line is def ined t o be a set of char act er s t er minat ed by a new l ine. In t his
exampl e, when t he Per l int er pr et er sees <STDIN>, it r eads in
This is a line of input.
If t he Per l int er pr et er t hen sees anot her <STDIN> in a dif f er ent st at ement , it r eads
anot her l ine of dat a f r om t he st andar d input f il e. The l ine of dat a you r ead ear l ier is
dest r oyed unl ess it has been copied somewher e el se.
NOTE
If t her e ar e mor e l ines of input t han t her e ar e <STDIN>
t okens, t he ext r a l ines of input ar e ignor ed
Because t he <STDIN> t oken is t o t he r ight of t he assignment oper at or =, t he l ine
This is a line of input.
is assigned t o t he scal ar var iabl e $inputline.
The ; Token
The ; t oken at t he end of t he st at ement is a special t oken t hat t el l s Per l t he st at ement
is compl et e. You can t hink of it as a punct uat ion mar k t hat is l ike a per iod in Engl ish.
Line 3: Writing to Standard Output
Now t hat you under st and what st at ement s and t okens ar e, consider l ine 3 of List ing 1.1,
which is
print ($inputline);
This st at ement r ef er s t o t he library function t hat is cal l ed print. Libr ar y f unct ions, such
as print, ar e pr ovided as par t of t he Per l int er pr et er ; each l ibr ar y f unct ion per f or ms a
usef ul t ask.
The print f unct ion's t ask is t o send dat a t o t he standard output file. The st andar d out put
f il e st or es dat a t hat is t o be wr it t en t o your scr een. The st andar d out put f il e somet imes
appear s in Per l pr ogr ams under t he name STDOUT.
In t his exampl e, print sends $inputline t o t he st andar d out put f il e. Because t he second
l ine of t he Per l pr ogr am assigns t he l ine
This is a line of input.
t o $inputline, t his is what print sends t o t he st andar d out put f il e and what appear s on
your scr een.
Function Invocations and Arguments
When a r ef er ence t o print appear s in a Per l pr ogr am, t he Per l int er pr et er calls, or
invokes, t he print l ibr ar y f unct ion. This function invocation is simil ar t o a f unct ion
invocat ion in C, a GOSUB st at ement in BASIC, or a PERFORM st at ement in COBOL. When
t he Per l int er pr et er sees t he print f unct ion invocat ion, it execut es t he code cont ained
in print and r et ur ns t o t he pr ogr am when print is f inished.
Most l ibr ar y f unct ions r equir e inf or mat ion t o t el l t hem what t o do. For exampl e, t he
print f unct ion needs t o know what you want t o pr int . In Per l , t his inf or mat ion is
suppl ied as a sequence of comma-separ at ed it ems l ocat ed bet ween t he par ent heses of t he
f unct ion invocat ion. For exampl e, t he st at ement you've just seen:
print ($inputline);
suppl ies one piece of inf or mat ion t hat is passed t o print: t he var iabl e $inputline. This
piece of inf or mat ion commonl y is cal l ed an argument.
The f ol l owing cal l t o print suppl ies t wo ar gument s:
print ($inputline, $inputline);
You can suppl y print wit h as many ar gument s as you l ike; it pr int s each ar gument
st ar t ing wit h t he f ir st one (t he one on t he l ef t ). In t his case, print wr it es t wo copies of
$inputline t o t he st andar d out put f il e.
You al so can t el l print t o wr it e t o any ot her specif ied f il e. You'l l l ear n mor e about
t his on Day 6, "Reading Fr om and Wr it ing To Fil es."
Error Messages
If you incor r ect l y t ype a st at ement when cr eat ing a Per l pr ogr am, t he Per l int er pr et er
wil l det ect t he er r or and t el l you wher e t he er r or is l ocat ed.
For exampl e, l ook at List ing 1.3. This pr ogr am is ident ical t o t he pr ogr am you've been
seeing al l al ong, except t hat it cont ains one smal l er r or . Can you spot it ?

List ing 1.3. A pr ogr am cont aining an er r or .
1: #!/usr/local/bin/perl
2: $inputline = <STDIN>
3: print ($inputline);

$ program1_3
Syntax error in file program1_3 at line3, next char (
Execution of program1_3 aborted due to compilation errors.
$

When you t r y t o r un t his pr ogr am, an er r or message appear s. The Per l int er pr et er has
det ect ed t hat l ine 2 of t he pr ogr am is missing it s cl osing ; char act er . The er r or message
f r om t he int er pr et er t el l s you what t he pr obl em is and ident if ies t he l ine on which t he
pr obl em is l ocat ed
TIP
You shoul d f ix er r or s st ar t ing f r om t he beginning of
your pr ogr am and wor king down.
When t he Per l int er pr et er det ect s an er r or , it t r ies t o
f igur e out what you meant t o say and car r ies on f r om
t her e; t his f eat ur e is known as error recovery. Er r or
r ecover y enabl es t he int er pr et er t o det ect as many
er r or s as possibl e at one t ime, which speeds up t he
devel opment pr ocess.
Somet imes, however , t he Per l int er pr et er can get
conf used and t hink you meant t o do one t hing when you
r eal l y meant t o do anot her . In t his sit uat ion, t he
int er pr et er might st ar t t r ying t o det ect er r or s t hat
don't r eal l y exist . This pr obl em is known as error
cascading.
It 's usual l y pr et t y easy t o spot er r or cascading. If t he
int er pr et er is t el l ing you t hat er r or s exist on sever al
consecut ive l ines, it usual l y means t hat t he int er pr et er
is conf used. Fix t he f ir st er r or , and t he ot her s might
ver y wel l go away
Interpretive Languages Versus Compiled Languages
As you've seen, r unning a Per l pr ogr am is easy. Al l you need t o do is cr eat e t he pr ogr am,
mar k it as execut abl e, and r un it . The Per l int er pr et er t akes car e of t he r est . Languages
such as Per l t hat ar e pr ocessed by an int er pr et er ar e known as interpretive languages.
Some pr ogr amming l anguages r equir e mor e compl icat ed pr ocessing. If a l anguage is a
compiled language, t he pr ogr am you wr it e must be t r ansl at ed int o machine-r eadabl e code
by a special pr ogr am known as a compiler. In addit ion, l ibr ar y code might need t o be added
by anot her special pr ogr am known as a linker. Af t er t he compil er and l inker have done
t heir jobs, t he r esul t is a pr ogr am t hat can be execut ed on your machine-assuming, of
cour se, t hat you have wr it t en t he pr ogr am cor r ect l y. If not , you have t o compil e and
l ink t he pr ogr am al l over again.
Int er pr et ive l anguages and compil ed l anguages bot h have advant ages and
disadvant ages, as f ol l ows:
G As you've seen wit h Per l , it t akes ver y l it t l e t ime t o r un a pr ogr am in an
int er pr et ive l anguage.
G Int er pr et ive l anguages, however , cannot r un unl ess t he int er pr et er is avail abl e.
Compil ed pr ogr ams, on t he ot her hand, can be t r ansf er r ed t o any machine t hat
under st ands t hem.
As you'l l see, Per l is as power f ul as a compil ed l anguage. This means t hat you can do a
l ot of wor k quickl y and easil y.
Summary
Today you l ear ned t hat Per l is a pr ogr amming l anguage t hat pr ovides many of t he
capabil it ies of a high-l evel pr ogr amming l anguage such as C. You al so l ear ned t hat Per l
is easy t o use; basical l y, you just wr it e t he pr ogr am and r un it .
You saw a ver y simpl e Per l pr ogr am t hat r eads a l ine of input f r om t he st andar d input
f il e and wr it es t he l ine t o t he st andar d out put f il e. The st andar d input f il e st or es
ever yt hing you t ype f r om your keyboar d, and t he st andar d out put f il e st or es
ever yt hing your Per l pr ogr am sends t o your scr een.
You l ear ned t hat Per l pr ogr ams cont ain a header comment , which indicat es t o t he
syst em t hat your pr ogr am is wr it t en in Per l . Per l pr ogr ams al so can cont ain ot her
comment s, each of which must be pr eceded by a #.
Per l pr ogr ams consist of a ser ies of st at ement s, which ar e execut ed one at a t ime. Each
st at ement consist s of a col l ect ion of t okens, which can be separ at ed by whit e space.
Per l pr ogr ams cal l l ibr ar y f unct ions t o per f or m cer t ain pr edef ined t asks. One exampl e
of a l ibr ar y f unct ion is print, which wr it es t o t he st andar d out put f il e. Libr ar y
f unct ions ar e passed chunks of inf or mat ion cal l ed ar gument s; t hese ar gument s t el l a
f unct ion what t o do.
The Per l int er pr et er execut es t he Per l pr ogr ams you wr it e. If it det ect s an er r or in your
pr ogr am, it displ ays an er r or message and uses t he er r or -r ecover y pr ocess t o t r y t o
cont inue pr ocessing your pr ogr am. If Per l get s conf used, er r or cascading can occur , and
t he Per l int er pr et er might displ ay inappr opr iat e er r or messages.
Final l y, you l ear ned about t he dif f er ences bet ween int er pr et ive l anguages and
compil ed l anguages, and t hat Per l is an exampl e of an int er pr et ive l anguage.
Q&A
Q: Is t her e any par t icul ar edit or I need t o use wit h Per l ?
A: No. Per l pr ogr ams ar e or dinar y t ext f il es. You can use any t ext edit or you l ike.
Q: Why do I need t o ent er t he chmod +x command bef or e r unning my pr ogr am?
A: Because Per l pr ogr ams ar e or dinar y t ext f il es, t he UNIX oper at ing syst em does
not know t hat t hey ar e execut abl e pr ogr ams. By def aul t , t ext f il es have r ead
and wr it e per missions gr ant ed, which means you can l ook at your f il e or change
it . The chmod +x command adds execut e per mission t o t he f il e; when t his
per mission is gr ant ed, t he syst em knows t hat t his is an execut abl e pr ogr am.
Q: Can I use print t o pr int ot her t hings besides input l ines?
A: Yes. You'l l l ear n mor e about how you can use print on Day 3, "Under st anding
Scal ar Val ues."
Q: Why is Per l avail abl e f or f r ee?
A: This encour ages t he disseminat ion of comput er knowl edge and capabil it ies.
It wor ks l ike t his: You can get Per l f or f r ee, and you can use it t o wr it e
int er est ing and usef ul pr ogr ams. If you want , you can t hen give t hese pr ogr ams
away and l et ot her peopl e wr it e int er est ing and usef ul pr ogr ams based on your
pr ogr ams. This way, ever ybody benef it s.
You al so can modif y t he sour ce f or Per l , pr ovided you t el l ever ybody t hat your
ver sion is a modif icat ion of t he or iginal . This means t hat if you t hink of a cl ever
t hing you want Per l t o do, you can add it your sel f . (However , you can't bl ame
anybody el se if your modif icat ion br eaks somet hing or if it doesn't wor k.)
Of cour se, you don't have t o give your Per l pr ogr ams away f or f r ee. In f act , you
even can sel l your Per l pr ogr ams, pr ovided you don't bor r ow anyt hing f r om
somebody el se's pr ogr am.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
t o under st and t he quiz and exer cise answer s bef or e cont inuing t o t he next day.
Quiz
1. What do Per l 's f ans appr eciat e about Per l ?
2. What does t he Per l int er pr et er do?
3. Def ine t he f ol l owing t er ms:
a st at ement
b t oken
c ar gument
d er r or r ecover y
e st andar d input f il e
4. What is a comment , and wher e can it appear ?
5. Wher e is Per l usual l y l ocat ed on a UNIX machine?
6. What is a header comment , and wher e does it appear in a pr ogr am?
7. What is a l ibr ar y f unct ion?
Exercises
1. Modif y program1_1 t o pr int t he input l ine t wice.
2. Modif y program1_1 t o r ead and pr int t wo dif f er ent input l ines.
3. Modif y program1_1 t o r ead t wo input l ines and pr int onl y t he second one.
4. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
$inputline = <STDIN>;
print ($inputline)
5. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
$inputline = <STDIN>;
# print my line! print($inputline);
6. What does t he f ol l owing pr ogr am do?
#!/usr/local/bin/perl
$inputline = <STDIN>;
$inputline2 = <STDIN>;
print ($inputline2);
print ($inputline);

Chapter 2
Basic Operators and Control Flow
CONTENTS
G St or ing in Scal ar Var iabl es Assignment
H The Def init ion of a Scal ar Var iabl e
H Scal ar Var iabl e Synt ax
H Assigning a Val ue t o a Scal ar Var iabl e
G Per f or ming Ar it hmet ic
H Exampl e of Mil es-t o-Kil omet er s Conver sion
H The chop Libr ar y Funct ion
G Expr essions
H Assignment s and Expr essions
G Ot her Per l Oper at or s
G Int r oduct ion t o Condit ional St at ement s
G The if St at ement
H The Condit ional Expr ession
H The St at ement Bl ock
H Test ing f or Equal it y Using ==
H Ot her Compar ison Oper at or s
G Two-Way Br anching Using if and else
G Mul t i-Way Br anching Using elsif
G Wr it ing Loops Using t he while St at ement
G Nest ing Condit ional St at ement s
G Looping Using t he until St at ement
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson gives you t he inf or mat ion you need t o wr it e some simpl e Per l pr ogr ams.
You'l l l ear n t he f ol l owing:
G Mor e about scal ar var iabl es and how t o assign val ues t o t hem
G The basic ar it hmet ic oper at or s and how t hey wor k wit h scal ar var iabl es
G What an expr ession is
G How t o use t he if st at ement and t he == oper at or t o t est f or simpl e condit ions
G How t o specif y t wo-way and mul t i-way br anches using else and elsif
G How t o wr it e simpl e l oops using t he while and until st at ement s
Storing in Scalar Variables Assignment
In yest er day's l esson, you saw t he f ol l owing st at ement , which assigns a l ine of input
f r om t he keyboar d t o t he var iabl e $inputline:
$inputline = <STDIN>;
This sect ion t el l s you mor e about var iabl es such as $inputline and how t o assign val ues
t o t hese var iabl es.
The Definition of a Scalar Variable
The var iabl e $inputline is an exampl e of a scalar variable. A scal ar var iabl e st or es
exact l y one it em-a l ine of input , a piece of t ext , or a number , f or exampl e. It ems t hat can
be st or ed in scal ar var iabl es ar e cal l ed scalar values.
You'l l l ear n mor e about scal ar val ues on Day 3, "Under st anding Scal ar Val ues." For
t oday, al l you need t o r emember is t hat a scal ar var iabl e st or es exact l y one val ue,
which is a scal ar val ue.
Scalar Variable Syntax
The name of a scal ar var iabl e consist s of t he char act er $ f ol l owed by at l east one
l et t er , which is f ol l owed by any number of l et t er s, digit s, or under scor e char act er s
(t hat is, t he _ char act er ).
The f ol l owing ar e exampl es of l egal scal ar var iabl e names:
$x
$var
$my_variable
$var2
$a_new_variable
These, however , ar e not l egal scal ar var iabl e names:
variable # the $ character is missing
$ # there must be at least one letter in the name
$47x # second character must be a letter
$_var # again, the second character must be a letter
$variable! # you can't have a ! in a variable name
$new.var # you can't have a . in a variable name
Per l var iabl es ar e case-sensit ive. This means t hat t he f ol l owing var iabl es ar e dif f er ent :
$VAR
$var
$Var
Your var iabl e name can be as l ong as you want .
$this_is_a_really_long_but_legal_name
$this_is_a_really_long_but_legal_name_that_is_different
The $ char act er is necessar y because it ensur es t hat t he Per l int er pr et er can dist inguish
scal ar var iabl es f r om ot her kinds of Per l var iabl es, which you'l l see on l at er days.
TIP
Var iabl e names shoul d be l ong enough t o be sel f -
expl anat or y but shor t enough t o be easy t o r ead and
t ype.
Assigning a Value to a Scalar Variable
The f ol l owing st at ement cont ains t he Per l assignment operator, which is t he = char act er :
$inputline = <STDIN>;
Remember t hat t his st at ement t el l s Per l t hat t he l ine of t ext r ead f r om t he st andar d
input f il e, r epr esent ed by <STDIN>, is t o become t he new val ue of t he scal ar var iabl e
$inputline.
You can use t he assignment oper at or t o assign ot her val ues t o scal ar var iabl es as wel l .
For exampl e, in t he f ol l owing st at ement , t he number 42 is assigned t o t he scal ar
var iabl e $var:
$var = 42;
A second assignment t o a scal ar var iabl e super sedes any pr evious assignment s. In t hese
t wo st at ement s:
$var = 42;
$var = 113;
t he ol d val ue of $var, 42, is dest r oyed, and t he val ue of $var becomes 113.
Assignment st at ement s can assign t ext t o scal ar var iabl es as wel l . Consider t he
f ol l owing st at ement :
$name = "inputdata";
In t his st at ement , t he t ext inputdata is assigned t o t he scal ar var iabl e $name.
Not e t hat t he quot at ion mar ks (t he " char act er s) on eit her end of t he t ext ar e not par t
of t he t ext assigned t o $name. This is because t he " char act er s ar e just t her e t o encl ose
t he t ext .
Spaces or t abs cont ained inside t he pair of " char act er s ar e t r eat ed as par t of t he t ext :
$name = "John Q Hacker";
Her e, t he spaces on eit her side of t he Q ar e consider ed par t of t he t ext .
In Per l , encl osed t ext such as John Q Hacker is known as a character string, and t he
sur r ounding " char act er s ar e an exampl e of string delimiters. You l ear n mor e about
char act er st r ings on Day 3; f or now, al l you need t o know is t hat ever yt hing inside t he
" char act er s is t r eat ed as a singl e unit .
Performing Arithmetic
As you've seen, t he assignment oper at or = t akes t he val ue t o t he r ight of t he = sign and
assigns it t o t he var iabl e on t he l ef t of t he =:
$var = 42;
Her e, t he val ue 42 is assigned t o t he scal ar var iabl e $var.
In Per l , t he assignment oper at or is just one of many operators t hat per f or m t asks, or
operations. Each oper at ion consist s of t he f ol l owing component s:
G The oper at or , such as t he assignment oper at or (=)
G One or mor e operands, such as $var and 42
This might sound a l it t l e conf using, but it 's r eal l y quit e st r aight f or war d. To il l ust r at e,
Tabl e 2.1 l ist s some of t he basic ar it hmet ic oper at or s t hat Per l suppor t s.
Tabl e 2.1. Basic ar it hmet ic oper at or s.
Oper at or Oper at ion
+
Addit ion
-
Subt r act ion
*
Mul t ipl icat ion
/
Division
You use t hese oper at or s in t he same way you use +, -, and so on when you do ar it hmet ic
on paper . For exampl e, t he f ol l owing st at ement adds 17 and 5 and t hen assigns t he
r esul t , 22, t o t he scal ar var iabl e $var:
$var = 17 + 5;
You can per f or m mor e t han one ar it hmet ic oper at ion in a singl e st at ement l ike t his one,
which assigns 19 t o $var:
$var = 17 + 5 - 3;
You can use t he val ue of a var iabl e in an ar it hmet ic oper at ion, as f ol l ows:
$var1 = 11;
$var2 = $var1 * 6;
The second st at ement t akes t he val ue cur r ent l y st or ed in $var1, 11, and mul t ipl ies it by
6. The r esul t , 66, is assigned t o $var2.
Now examine t he f ol l owing st at ement s:
$var = 11;
$var = $var * 6;
As you can see, $var appear s t wice in t he second st at ement . What Per l does in t his case is
st r aight f or war d:
1. The f ir st st at ement assigns t he val ue 11 t o $var.
2. In t he second st at ement , t he Per l int er pr et er r et r ieves t he cur r ent val ue of $var,
11, and mul t ipl ies it by 6, pr oducing t he r esul t 66.
3. This r esul t , 66, is t hen assigned t o $var (dest r oying t he ol d val ue, 11).
As you can see, t her e is no ambiguit y. Per l uses t he ol d val ue of $var in t he ar it hmet ic
oper at ion, and t hen it assigns t he r esul t of t he oper at ion t o $var.
NOTE
Per l al ways per f or ms mul t ipl icat ion and division bef or e
addit ion and subt r act ion-even if t he addit ion or
subt r act ion oper at or appear s f ir st . Per l does t his t o
conf or m t o t he r ul es of ar it hmet ic. For exampl e, in t he
f ol l owing st at ement :
$var = 5 + 6 * 4;
$var is assigned 29: 6 is mul t ipl ied by 4, and t hen 5 is
added t o t he r esul t
Example of Miles-to-Kilometers Conversion
To see how ar it hmet ic oper at or s wor k, l ook at List ing 2.1, which per f or ms a simpl e mil es-
t o-kil omet er s and kil omet er s-t o-mil es conver sion.

List ing 2.1. Mil es-t o-kil omet er s conver t er .
1: #!/usr/local/bin/perl
2:
3: print ("Enter the distance to be converted:\n");
4: $originaldist = <STDIN>;
5: chop ($originaldist);
6: $miles = $originaldist * 0.6214;
7: $kilometers = $originaldist * 1.609;
8: print ($originaldist, " kilometers = ", $miles,
9: " miles\n");
10: print ($originaldist, " miles = ", $kilometers,
11: " kilometers\n");

$ program2_1
Enter the distance to be converted:
10
10 kilometers = 6.2139999999999995 miles
10 miles = 16.09 kilometers
$
Line 3 of t his pr ogr am asks f or a dist ance t o conver t . To do t his, it pr int s t he
f ol l owing t ext on your scr een
Enter the distance to be converted:
Not e t hat t he \n at t he end of t he t ext is not pr int ed. The \n is a special sequence of
char act er s t hat r epr esent s t he newl ine char act er ; when t he print l ibr ar y f unct ion sees
\n, it st ar t s a new l ine of out put on your scr een. (You'l l l ear n mor e about special
sequences of char act er s such as \n on Day 3.)
At t his point , you can ent er any number you want in r esponse t o t he pr ogr am's r equest
f or a dist ance. The input /out put exampl e shows an ent r y of 10.
Line 4 r et r ieves t he l ine of input you ent er ed and t hen assigns it t o t he var iabl e named
$originaldist.
Line 5 cal l s t he l ibr ar y f unct ion chop, which get s r id of t he cl osing newl ine char act er
t hat is par t of t he input l ine you ent er ed. The chop l ibr ar y f unct ion is descr ibed in t he
f ol l owing sect ion, "The chop Libr ar y Funct ion."
Line 6 det er mines t he number of mil es t hat is equival ent t o 10 kil omet er s and assigns
t his number t o t he var iabl e $miles.
Line 7 det er mines t he number of kil omet er s t hat is equival ent t o 10 mil es and assigns
t his number t o t he var iabl e $kilometers.
Lines 8-11 pr int t he val ues of t he var iabl es $miles and $kilometers.
NOTE
Dif f er ent machines handl e f l oat ing-point number s
(number s cont aining a decimal point ) in dif f er ent ways.
Because of t his, t he number s displ ayed in your List ing 2.1
out put might not be exact l y t he same as t he number s
shown her e. These minor dif f er ences wil l appear
whenever a f l oat ing-point number is pr int ed.
For mor e inf or mat ion on dif f icul t ies wit h f l oat ing-point
number s, r ef er t o t he discussion of r ound-of f er r or s on
Day 3, "Under st anding Scal ar Val ues.
The chop Library Function
The pr ogr am shown in List ing 2.1 cal l s a special l ibr ar y f unct ion, chop. This f unct ion
assumes t hat a l ine of t ext is st or ed in t he var iabl e passed t o it ; chop's job is t o del et e
t he char act er at t he r ight end of t he l ine of t ext . Consider t his exampl e:
$line = "This is my line";
chop ($line);
Af t er chop is cal l ed, t he val ue of $line becomes
This is my lin
Her e's why List ing 2.1 uses chop. The st at ement
$originaldist = <STDIN>;
assigns a l ine of input f r om t he st andar d input f il e t o t he var iabl e $originaldist. When
you t ype 10 and pr ess Ent er , t he l ine of input assigned t o $originaldist consist s of t hr ee
char act er s: t he 1, t he 0, and a newl ine char act er . When chop is cal l ed, t he newl ine
char act er is r emoved, and $originaldist now cont ains t he val ue 10, which can be used
in ar it hmet ic oper at ions.
You'l l l ear n mor e about using l ines of input in ar it hmet ic oper at ions and about
conver sions f r om l ines of input t o number s on Day 3. For now, just r emember t o cal l chop
af t er r eading a number f r om t he st andar d input f il e.
$originaldist = <STDIN>;
chop ($originaldist);
Expressions
Now t hat you know a l it t l e mor e about oper at or s, oper ands, and how t hey bot h wor k,
it 's t ime t o l ear n some mor e t er minol ogy as wel l as t he det ail s about exact l y what Per l
is doing when it eval uat es oper at or s such as t he ar it hmet ic oper at or s and t he
assignment oper at or .
In Per l , a col l ect ion of oper at or s and oper ands is known as an expression. Each expr ession
yiel ds a result, which is t he val ue you get when t he Per l int er pr et er evaluates t he
expr ession (t hat is, when t he Per l int er pr et er per f or ms t he specif ied oper at ions). For
exampl e, in t he simpl e expr ession
4 * 5
t he r esul t is 20, or 4 t imes 5.
You can t hink of an expr ession as a set of subor dinat e expr essions. Consider t his exampl e:
4 * 5 + 3 * 6
When t he Per l int er pr et er eval uat es t his expr ession, it f ir st eval uat es t he
subexpr essions 4 * 5 and 3 * 6, yiel ding t he r esul t s 20 and 18. These r esul t s ar e t hen
(ef f ect ivel y) subst it ut ed f or t he subexpr essions, l eaving t he f ol l owing:
20 + 18
The Per l int er pr et er t hen per f or ms t he addit ion oper at ion, and t he f inal r esul t of t he
expr ession is 38.
Consider t he f ol l owing st at ement :
$var = 4 * 5 + 3;
As you can see, t he Per l int er pr et er mul t ipl ies 4 by 5, adds 3, and assigns t he r esul t , 23,
t o $var. Her e's what t he Per l int er pr et er is doing, mor e f or mal l y, when it eval uat es t his
expr ession ($var = 4 * 5 + 3):
1. The subexpr ession 4 * 5 is eval uat ed, yiel ding t he r esul t 20. The expr ession being
eval uat ed is now
$var = 20 + 3
because t he mul t ipl icat ion oper at ion has been r epl aced by it s r esul t .
2. The subexpr ession 20 + 3 is eval uat ed, yiel ding 23. The expr ession is now
$var = 23
3. Final l y, t he val ue 23 is assigned t o $var.
Her e's one mor e exampl e, t his t ime using t he val ue of a var iabl e in an expr ession:
$var1 = 15;
$var2 = $var1 - 11;
When t he Per l int er pr et er eval uat es t he second expr ession, it does t he f ol l owing:
1. It r et r ieves t he val ue cur r ent l y st or ed in $var1, which is 15, and r epl aces t he
var iabl e wit h it s val ue. This means t he expr ession is now
$var2 = 15 - 11
and $var1 is out of t he pict ur e.
2. The Per l int er pr et er per f or ms t he subt r act ion oper at ion, yiel ding
$var2 = 4
3. $var2 is t hus assigned t he val ue 4.
NOTE
An expr ession and a st at ement ar e t wo dif f er ent t hings.
A st at ement , however , can cont ain a Per l expr ession. For
exampl e, t he st at ement
$var2 = 4;
cont ains t he Per l expr ession
$var2 = 4
and is t er minat ed by a semicol on (;).
The dist inct ion bet ween st at ement s and expr essions wil l
become cl ear er when you encount er ot her pl aces wher e
Per l st at ement s use expr essions. For exampl e, expr essions
ar e used in condit ional st at ement s, which you'l l see
l at er t oday.
Assignments and Expressions
The assignment oper at or , l ike al l Per l oper at or s, yiel ds a r esul t . The r esul t of an
assignment oper at ion is t he val ue assigned. For exampl e, in t he expr ession
$var = 42
t he r esul t of t he expr ession is 42, which is t he val ue assigned t o $var.
Because t he assignment oper at or yiel ds a val ue, you can use mor e t han one assignment
oper at or in a singl e expr ession:
$var1 = $var2 = 42;
In t his exampl e, t he subexpr ession
$var2 = 42
is per f or med f ir st . (You'l l l ear n why on Day 4, "Mor e Oper at or s," in t he l esson about
oper at or pr ecedence.) The r esul t of t his subexpr ession is 42, and t he expr ession is now
$var1 = 42
At t his point , 42 is assigned t o $var1.
Other Perl Operators
So f ar , you have encount er ed t he f ol l owing Per l oper at or s, which ar e just a f ew of t he
many oper at or s Per l suppor t s:
G The assignment oper at or , =.
G The ar it hmet ic oper at or s +, -, *, and /.
You'l l l ear n about addit ional Per l oper at or s on Day 4.
Introduction to Conditional Statements
So f ar , t he Per l pr ogr ams you've seen have had t heir st at ement s execut ed in sequent ial
or der . For exampl e, consider t he kil omet er -t o-mil e conver sion pr ogr am you saw in
List ing 2.1:
#!/usr/local/bin/perl
print ("Enter the distance to be converted:\n");
$originaldist = <STDIN>;
chop ($originaldist);
$miles = $originaldist * 0.6214;
$kilometers = $originaldist * 1.609;
print ($originaldist, " kilometers = ", $miles,
" miles\n");
print ($originaldist, " miles = ", $kilometers,
" kilometers\n");
When t he Per l int er pr et er execut es t his pr ogr am, it st ar t s at t he t op of t he pr ogr am and
execut es each st at ement in t ur n. When t he f inal st at ement is execut ed, t he pr ogr am is
t er minat ed.
Al l t he st at ement s in t his pr ogr am ar e unconditional statements-t hat is, t hey al ways ar e
execut ed sequent ial l y, r egar dl ess of what is happening in t he pr ogr am. In some
sit uat ions, however , you might want t o have st at ement s t hat ar e execut ed onl y when
cer t ain condit ions ar e t r ue. These st at ement s ar e known as conditional statements.
Per l suppor t s a var iet y of condit ional st at ement s. In t he f ol l owing sect ions, you'l l
l ear n about t hese condit ional st at ement s:
Statement Description
if
Execut es when a specif ied condit ion is t r ue.
if-else Chooses bet ween t wo al t er nat ives.
if-elsif-else Chooses bet ween mor e t han t wo al t er nat ives.
While and until Repeat s a gr oup of st at ement s a specif ied
number of t imes.
Per l al so has ot her condit ional st at ement s, which you'l l l ear n about on Day 8, "Mor e
Cont r ol St r uct ur es."
The if Statement
The if st at ement is t he simpl est condit ional st at ement used in Per l . The easiest way t o
expl ain how t he if st at ement wor ks is t o show you a simpl e exampl e:
if ($number) {
print ("The number is not zero.\n");
}
The if st at ement consist s of (cl osing br ace char act er ):
This st at ement consist s of t wo par t s:
G The code bet ween t he if and t he open br ace char act er ({).
G The code bet ween t he { and t he }.
The f ir st par t is known as a conditional expression; t he second par t is a set of one or mor e
st at ement s cal l ed a statement block. Let 's l ook at each par t in det ail .
The Conditional Expression
The f ir st par t of an if st at ement -t he par t bet ween t he par ent heses-is t he conditional
expression associat ed wit h t he if st at ement . This condit ional expr ession is just l ike any
ot her expr ession you've seen so f ar ; in f act , you can use any l egal Per l expr ession as a
condit ional expr ession.
When t he Per l int er pr et er sees a condit ional expr ession, it eval uat es t he expr ession.
The r esul t of t he expr ession is t hen pl aced in one of t wo cl asses:
G If t he r esul t is a nonzer o val ue, t he condit ional expr ession is true.
G If t he r esul t is zer o, t he condit ional expr ession is false.
The Per l int er pr et er uses t he val ue of t he condit ional expr ession t o decide whet her t o
execut e t he st at ement s bet ween t he { and } char act er s. If t he condit ional expr ession is
t r ue, t he st at ement s ar e execut ed. If t he condit ional expr ession is f al se, t he st at ement s
ar e not execut ed.
In t he exampl e you have just seen,
if ($number) {
print ("The number is not zero.\n");
}
t he condit ional expr ession consist s of t he val ue of t he var iabl e $number. If $number
cont ains somet hing ot her t han zer o, t he condit ional expr ession is t r ue, and t he
st at ement
print ("The value is not zero.\n");
is execut ed. If $number cur r ent l y is set t o zer o, t he condit ional expr ession is f al se, and
t he print st at ement is not execut ed.
List ing 2.2 is a pr ogr am t hat cont ains t his simpl e if st at ement .

List ing 2.2. A pr ogr am cont aining a simpl e exampl e of an if st at ement .
1: #!/usr/local/bin/perl
2:
3: print ("Enter a number:\n");
4: $number = <STDIN>;
5: chop ($number);
6: if ($number) {
7: print ("The number is not zero.\n");
8: }
9: print ("This is the last line of the program.\n");

$ program2_2
Enter a number:
5
The number is not zero.
This is the last line of the program.
$
Lines 3, 4, and 5 of List ing 2.2 ar e simil ar t o l ines you've seen bef or e. Line 3
t el l s you t o ent er a number ; l ine 4 assigns t he l ine you've ent er ed t o t he var iabl e
$number; and l ine 5 t hr ows away t he t r ail ing newl ine char act er
Lines 6-8 const it ut e t he if st at ement it sel f . As you have seen, t his st at ement eval uat es
t he condit ional expr ession consist ing of t he var iabl e $number. If $number is not zer o, t he
expr ession is t r ue, and t he cal l t o print is execut ed. If $number is zer o, t he expr ession is
f al se, and t he cal l t o print is skipped; t he Per l int er pr et er t hus jumps t o l ine 9.
The Per l int er pr et er execut es l ine 9 and pr int s t he f ol l owing r egar dl ess of whet her t he
condit ional expr ession in l ine 6 is t r ue or f al se:
This is the last line of the program.
Now t hat you under st and how an if st at ement wor ks, you'r e r eady t o see t he f or mal
synt ax def init ion f or t he if st at ement .
The synt ax f or t he if st at ement is
if (expr) {
statement_block
}
This f or mal def init ion doesn't t el l you anyt hing you don't al r eady know. expr r ef er s t o
t he condit ional expr ession, which eval uat es t o eit her t r ue or f al se. statement_block is
t he gr oup of st at ement s t hat is execut ed when expr eval uat es t o t r ue.
If you ar e f amil iar wit h t he C pr ogr amming l anguage,
you pr obabl y have not iced t hat t he if st at ement in Per l
is synt act ical l y simil ar t o t he if st at ement in C. Ther e is
one impor t ant dif f er ence, however : In Per l , t he br aces ({
and }) must be pr esent
The f ol l owing st at ement is il l egal in Per l because t he { and } ar e missing:
if ($number)
print ("The value is not zero.\n");
Per l does suppor t a synt ax f or singl e-l ine condit ional st at ement s. This is discussed on
Day 8.
The Statement Block
The second par t of t he if st at ement , t he par t bet ween t he { and t he }, is cal l ed a
statement block. A st at ement bl ock consist s of any number of l egal Per l st at ement s
(incl uding no st at ement s, if you l ike).
In t he f ol l owing exampl e, t he st at ement bl ock consist s of one st at ement :
print ("The value is not zero.\n");
NOTE
A st at ement bl ock can be compl et el y empt y. In t his
st at ement , f or exampl e:
if ($number == 21) {
}
t her e is not hing bet ween t he { and }, so t he st at ement
bl ock is empt y. This is per f ect l y l egal Per l code,
al t hough it 's not par t icul ar l y usef ul
Testing for Equality Using ==
So f ar , t he onl y condit ional expr ession you've seen is an expr ession consist ing of a singl e
var iabl e. Al t hough you can use any expr ession you l ike and any oper at or s you l ike, Per l
pr ovides special oper at or s t hat ar e designed f or use in condit ional expr essions. One such
oper at or is t he equality comparison operator, ==.
The == oper at or , l ike t he ot her oper at or s you've seen so f ar , r equir es t wo oper ands or
subexpr essions. Unl ike t he ot her oper at or s, however , it yiel ds one of t wo possibl e
r esul t s: t r ue or f al se. (The ot her oper at or s you've seen yiel d a numer ic val ue as a
r esul t .) The == oper at or wor ks l ike t his:
G If t he t wo subexpr essions eval uat e t o t he same numer ic val ue, t he == oper at or
yiel ds t he r esul t true.
G If t he t wo subexpr essions have dif f er ent val ues, t he == oper at or yiel ds t he r esul t
false.
Because t he == oper at or r et ur ns eit her t r ue or f al se, it is ideal f or use in condit ional
expr essions, because condit ional expr essions ar e expect ed t o eval uat e t o eit her t r ue or
f al se. For an exampl e, l ook at List ing 2.3, which compar es t wo number s r ead in f r om t he
st andar d input f il e.

List ing 2.3. A pr ogr am t hat uses t he equal it y-compar ison oper at or t o
compar e t wo number s ent er ed at t he keyboar d.
1: #!/usr/local/bin/perl
2:
3: print ("Enter a number:\n");
4: $number1 = <STDIN>;
5: chop ($number1);
6: print ("Enter another number:\n");
7: $number2 = <STDIN>;
8: chop ($number2);
9: if ($number1 == $number2) {
10: print ("The two numbers are equal.\n");
11: }
12: print ("This is the last line of the program.\n");

$ program2_3
Enter a number:
17
Enter another number:
17
The two numbers are equal.
This is the last line of the program.
$
Lines 3-5 ar e again simil ar t o st at ement s you've seen bef or e. They pr int a
message on your scr een, r ead a number int o t he var iabl e $number1, and chop t he newl ine
char act er f r om t he number
Lines 6-8 r epeat t he pr eceding pr ocess f or a second number , which is st or ed in $number2.
Lines 9-11 cont ain t he if st at ement t hat compar es t he t wo number s. Line 9 cont ains t he
condit ional expr ession
$number1 == $number2
If t he t wo number s ar e equal , t he condit ional expr ession is t r ue, and t he print
st at ement in l ine 10 is execut ed. If t he t wo number s ar e not equal , t he condit ional
expr ession is f al se, so t he print st at ement in l ine 10 is not execut ed; in t his case, t he
Per l int er pr et er skips t o t he f ir st st at ement af t er t he if st at ement , which is l ine 12.
Line 12 is execut ed r egar dl ess of whet her or not t he condit ional expr ession in l ine 9 is
t r ue. It pr int s t he f ol l owing message on t he scr een:
This is the last line of the program.
Make sur e t hat you don't conf use t he = and == oper at or s.
Because any expr ession can be used as a condit ional
expr ession, Per l is quit e happy t o accept st at ement s such
as
if ($number = 5) {
print ("The number is five.\n");
}
Her e, t he if st at ement is eval uat ed as f ol l ows:
1. The number 5 is assigned t o $number , and t he f ol l owing
expr ession yiel ds t he r esul t 5:
$number = 5
2. The val ue 5 is nonzer o, so t he condit ional expr ession is t r ue.
3. Because t he condit ional expr ession is t r ue, t his st at ement is
execut ed:
print ("The number is five.\n");
Not e t hat t he print st at ement is execut ed r egar dl ess of
what t he val ue of $number was bef or e t he if st at ement .
This is because t he val ue 5 is assigned t o $number by t he
condit ional expr ession.
To r epeat : Be car ef ul when you use t he == oper at or
Other Comparison Operators
The == oper at or is just one of many compar ison oper at or s t hat you can use in condit ional
expr essions. For a compl et e l ist , r ef er t o Day 4.
Two-Way Branching Using if and else
When you examine List ing 2.3 (shown pr eviousl y), you might not ice a pr obl em. What
happens if t he t wo number s ar e not equal ? In t his case, t he st at ement
print ("The two numbers are equal.\n");
is not pr int ed. In f act , not hing is pr int ed.
Suppose you want t o modif y List ing 2.3 t o pr int one message if t he t wo number s ar e equal
and anot her message if t he t wo number s ar e not equal . One convenient way of doing
t his is wit h t he if-else st at ement .
List ing 2.4 is a modif icat ion of t he pr ogr am in List ing 2.3. It uses t he if-else st at ement t o
pr int one of t wo messages, depending on whet her t he number s ar e equal .

List ing 2.4. A pr ogr am t hat uses t he if-else st at ement .
1: #!/usr/local/bin/perl
2:
3: print ("Enter a number:\n");
4: $number1 = <STDIN>;
5: chop ($number1);
6: print ("Enter another number:\n");
7: $number2 = <STDIN>;
8: chop ($number2);
9: if ($number1 == $number2) {
10: print ("The two numbers are equal.\n");
11: } else {
12: print ("The two numbers are not equal.\n");
13: }
14: print ("This is the last line of the program.\n");

$ program2_4
Enter a number:
17
Enter another number:
18
The two numbers are not equal.
This is the last line of the program.
$
Lines 3-8 ar e ident ical t o t hose in List ing 2.3. They r ead in t wo number s, assign
t hem t o $number1 and $number2, and chop t heir newl ine char act er s
Line 9 compar es t he val ue st or ed in $number1 t o t he val ue st or ed in $number2. If t he t wo
val ues ar e equal , l ine 10 is execut ed, and t he f ol l owing message is pr int ed:
The two numbers are equal.
The Per l int er pr et er t hen jumps t o t he f ir st st at ement af t er t he if-else st at ement -l ine
14.
If t he t wo val ues ar e not equal , l ine 12 is execut ed, and t he f ol l owing message is
pr int ed:
The two numbers are not equal.
The int er pr et er t hen cont inues wit h t he f ir st st at ement af t er t he if-else-l ine 14.
In eit her case, t he Per l int er pr et er execut es l ine 14, which pr int s t he f ol l owing message:
This is the last line of the program.
The synt ax f or t he if-else st at ement is
if (expr) {
statement_block_1
} else {
statement_block_2
}
As in t he if st at ement , expr is any expr ession (it is usual l y a condit ional expr ession).
statement_block_1 is t he bl ock of st at ement s t hat t he Per l int er pr et er execut es if expr
is t r ue, and statement_block_2 is t he bl ock of st at ement s t hat ar e execut ed if expr is
f al se.
Not e t hat t he else par t of t he if-else st at ement cannot appear by it sel f ; it must al ways
f ol l ow an if.
TIP
In Per l , as you've l ear ned, you can use any amount of
whit e space t o separ at e t okens. This means t hat you can
pr esent condit ional st at ement s in a var iet y of ways.
The exampl es in t his book use what is cal l ed t he one true
brace st yl e:
if ($number == 0) {
print ("The number is zero.\n");
} else {
print ("The number is not zero.\n");
}
In t his br ace st yl e, t he opening br ace ({) appear s on t he
same l ine as t he if or else, and t he cl osing br ace (})
st ar t s a new l ine.
Ot her pr ogr ammer s insist on put t ing t he br aces on
separ at e l ines:
if ($number == 0)
{
print ("The number is zero.\n");
}
else
{
print ("The number is not zero.\n");
}
St il l ot her s pr ef er t o indent t heir br aces:
if ($number == 0)
{
print ("The number is not zero.\n");
}
I pr ef er t he one t r ue br ace st yl e because it is bot h
l egibl e and compact . However , it doesn't r eal l y mat t er
what br ace st yl e you choose, pr ovided t hat you f ol l ow
t hese r ul es:
G The br ace st yl e is consist ent . Ever y if and else t hat appear s in
your pr ogr am shoul d have it s br aces displ ayed in t he same way.
G The br ace st yl e is easy t o f ol l ow.
G The st at ement bl ocks inside t he br aces al ways shoul d be
indent ed in t he same way.
If you do not f ol l ow a consist ent st yl e, and you wr it e
st at ement s such as
if ($number == 0) { print ("The number is zero"); }
you'l l f ind t hat your code is dif f icul t t o under st and,
especial l y when you st ar t wr it ing l onger Per l pr ogr ams
Multi-Way Branching Using elsif
List ing 2.4 (which you've just seen) shows how t o wr it e a pr ogr am t hat chooses bet ween
t wo al t er nat ives. Per l al so pr ovides a condit ional st at ement , t he if-elsif-else
st at ement , which sel ect s one of mor e t han t wo al t er nat ives. List ing 2.5 il l ust r at es t he
use of elsif.

List ing 2.5. A pr ogr am t hat uses t he if-elsif-else st at ement .
1: #!/usr/local/bin/perl
2:
3: print ("Enter a number:\n");
4: $number1 = <STDIN>;
5: chop ($number1);
6: print ("Enter another number:\n");
7: $number2 = <STDIN>;
8: chop ($number2);
9: if ($number1 == $number2) {
10: print ("The two numbers are equal.\n");
11: } elsif ($number1 == $number2 + 1) {
12: print ("The first number is greater by one.\n");
13: } elsif ($number1 + 1 == $number2) {
14: print ("The second number is greater by one.\n");
15: } else {
16: print ("The two numbers are not equal.\n");
17: }
18: print ("This is the last line of the program.\n");

$ program2_5
Enter a number:
17
Enter another number:
18
The second number is greater by one.
This is the last line of the program.
$
You al r eady ar e f amil iar wit h l ines 3-8. They obt ain t wo number s f r om t he
st andar d input f il e and assign t hem t o $number1 and $number2, chopping t he t er minat ing
newl ine char act er in t he pr ocess
Line 9 checks whet her t he t wo number s ar e equal . If t he number s ar e equal , l ine 10 is
execut ed, and t he f ol l owing message is pr int ed:
The two numbers are equal.
The Per l int er pr et er t hen jumps t o t he f ir st st at ement af t er t he if-elsif-else
st at ement , which is l ine 18.
If t he t wo number s ar e not equal , t he Per l int er pr et er goes t o l ine 11. Line 11 per f or ms
anot her compar ison. It adds 1 t o t he val ue of $number2 and compar es it wit h t he val ue of
$number1. If t he t wo val ues ar e equal , t he Per l int er pr et er execut es l ine 12, pr int ing
t he message
The first number is greater by one.
The int er pr et er t hen jumps t o l ine 18-t he st at ement f ol l owing t he if-elsif-else
st at ement .
If t he condit ional expr ession in l ine 11 is f al se, t he int er pr et er jumps t o l ine 13. Line 13
adds 1 t o t he val ue of $number1 and compar es it wit h t he val ue of $number2. If t hese t wo
val ues ar e equal , t he Per l int er pr et er execut es l ine 14, which pr int s
The second number is greater by one.
on t he scr een. The int er pr et er t hen jumps t o l ine 18.
If t he condit ional expr ession in l ine 13 is f al se, t he Per l int er pr et er jumps t o l ine 15 and
execut es l ine 16, which pr int s
The two numbers are not equal.
on t he scr een. The Per l int er pr et er cont inues wit h t he next st at ement , which is l ine 18.
If you have f ol l owed t he pr ogr am l ogic t o t his point , you've r eal ized t hat t he Per l
int er pr et er event ual l y r eaches l ine 18 in ever y case. Line 18 pr int s t his st at ement :
This is the last line of the program.
The synt ax of t he if-elsif-else st at ement is as f ol l ows:
if (expr_1) {
statement_block_1
} elsif (expr_2) {
statement_block_2
} elsif (expr_3) {
statement_block_3
...
} else {
default_statement_block
}
Her e, expr_1, expr_2, and expr_3 ar e condit ional expr essions. statement_block_1,
statement_block_2, statement_block_3, and default_statement_block ar e bl ocks of
st at ement s.
The ... indicat es t hat you can have as many elsif st at ement s as you l ike. Each elsif
st at ement has t he same f or m:
} elsif (expr) {
statement_block
}
Synt act ical l y, an if-else st at ement is just an if-elsif-else st at ement wit h no elsif
par t s.
If you want , you can l eave out t he else par t of t he if-elsif-else st at ement , as f ol l ows:
if (expr_1) {
statement_block_1
} elsif (expr_2) {
statement_block_2
} elsif (expr_3) {
statement_block_3
...
}
Her e, if none of t he expr essions-expr_1, expr_2, expr_3, and so on-ar e t r ue, t he Per l
int er pr et er just skips t o t he f ir st st at ement f ol l owing t he if-elsif-else st at ement .
NOTE
The elsif par t s of t he if-elsif-else st at ement must
appear bet ween t he if par t and t he else par t
Writing Loops Using the while Statement
The condit ional st at ement s you've seen so f ar enabl e t he Per l int er pr et er t o decide
bet ween al t er nat ives. However , each st at ement in t he Per l pr ogr ams t hat you have seen
is eit her not execut ed or is execut ed onl y once.
Per l al so enabl es you t o wr it e condit ional st at ement s t hat t el l t he Per l int er pr et er t o
r epeat a bl ock of st at ement s a specif ied number of t imes. A bl ock of st at ement s t hat can
be r epeat ed is known as a loop.
The simpl est way t o wr it e a l oop in Per l is wit h t he while st at ement . Her e is a simpl e
exampl e of a while st at ement :
while ($number == 5) {
print ("The number is still 5!\n");
}
The while st at ement is st r uct ur al l y simil ar t o t he if st at ement , but it wor ks in a
sl ight l y dif f er ent way. Her e's how:
G Fir st , t he condit ional expr ession l ocat ed bet ween t he par ent heses is t est ed.
G If t he condit ional expr ession is t r ue, t he st at ement bl ock bet ween t he { and } is
execut ed. If t he expr ession is f al se, t he st at ement bl ock is skipped, and t he Per l
int er pr et er jumps t o t he st at ement f ol l owing t he while st at ement . (This is cal l ed
exiting the loop.)
G If t he st at ement bl ock is execut ed, t he Per l int er pr et er jumps back t o t he st ar t of
t he while st at ement and t est s t he condit ional expr ession over again. (This is t he
l ooping par t of t he while st at ement , because at t his point t he Per l int er pr et er is
execut ing a st at ement it has execut ed bef or e.)
The st at ement bl ock in t he while st at ement is r epeat ed unt il t he condit ional expr ession
becomes f al se. This means t hat t he st at ement
while ($number == 5) {
print ("The number is still 5!\n");
}
l oops f or ever (which is r ef er r ed t o as going int o an infinite loop) if t he val ue of $number is
5, because t he val ue of $number never changes and t he f ol l owing condit ional expr ession
is al ways t r ue:
$number == 5
For a mor e usef ul exampl e of a while st at ement -one t hat does not go int o an inf init e
l oop-t ake a l ook at List ing 2.6.

List ing 2.6. A pr ogr am t hat demonst r at es t he while st at ement .
1: #!/usr/local/bin/perl
2:
3: $done = 0;
4: $count = 1;
5: print ("This line is printed before the loop starts.\n");
6: while ($done == 0) {
7: print ("The value of count is ", $count, "\n");
8: if ($count == 3) {
9: $done = 1;
10: }
11: $count = $count + 1;
12: }
13: print ("End of loop.\n");

$ program2_6
This line is printed before the loop starts.
The value of count is 1
The value of count is 2
The value of count is 3
End of loop.
$
Lines 3-5 pr epar e t he pr ogr am f or l ooping. Line 3 assigns t he val ue 0 t o t he
var iabl e $done. (As you'l l see, t he pr ogr am uses $done t o indicat e whet her or not t o
cont inue l ooping.) Line 4 assigns t he val ue 1 t o t he var iabl e $count. Line 5 pr int s t he
f ol l owing l ine t o t he scr een
This line is printed before the loop starts.
The while st at ement appear s in l ines 6-12. Line 6 cont ains a condit ional expr ession t o be
t est ed. If t he condit ional expr ession is t r ue, t he st at ement bl ock in l ines 7-11 is
execut ed. At t his point , t he condit ional expr ession is t r ue, so t he Per l int er pr et er
cont inues wit h l ine 7.
Line 7 pr int s t he cur r ent val ue of t he var iabl e $count. At pr esent , $count is set t o 1. This
means t hat l ine 7 pr int s t he f ol l owing on t he scr een:
The value of count is 1
Lines 8-10 t est whet her $count has r eached t he val ue 3. Because $count is 1 at t he
moment , t he condit ional expr ession in l ine 8 is f al se, and t he Per l int er pr et er skips t o
l ine 11.
Line 11 adds 1 t o t he cur r ent val ue of $count, set t ing it t o 2.
Line 12 is t he bot t om of t he while st at ement . The Per l int er pr et er now jumps back t o
l ine 6, and t he whol e pr ocess is r epeat ed. Her e's how t he Per l int er pr et er cont inues f r om
her e:
G Line 6: $done == 0 is t r ue, so cont inue.
G Line 7: Pr int The value of count is 2 on t he scr een.
G Line 8: $count is 2; $count == 3 is f al se, so skip t o l ine 11.
G Line 11: 1 is added t o $count; $count is now 3.
G Line 12: Jump back t o t he st ar t of t he l oop, which is l ine 6.
G Line 6: $done == 0 is t r ue, so cont inue.
G Line 7: Pr int The value of count is 3 on t he scr een.
G Line 8: $count is 3; $count == 3 is t r ue, and t he if st at ement bl ock is execut ed.
G Line 9: $done is set t o 1. Execut ion cont inues wit h t he f ir st st at ement af t er t he if,
which is l ine 11.
G Line 11: $count is set t o 4.
G Line 12: Jump back t o l ine 6.
G Line 6: $done == 0 is now f al se, because t he val ue of $done is 1. The Per l
int er pr et er exit s t he l oop and cont inues wit h t he f ir st st at ement af t er while,
which is l ine 13.
Line 13 pr int s t he f ol l owing message on t he scr een:
End of loop.
At t his point , pr ogr am execut ion t er minat es because t her e ar e no mor e st at ement s t o
execut e.
The synt ax f or t he while st at ement is
while (expr) {
statement_block
}
As you can see, t he while st at ement is synt act ical l y simil ar t o t he if st at ement . expr is
a condit ional expr ession t o be eval uat ed, and statement_block is a bl ock of st at ement s
t o be execut ed whil e expr is t r ue.
Nesting Conditional Statements
The if st at ement in List ing 2.6 (shown pr eviousl y) is an exampl e of a nested conditional
statement. It is cont ained inside anot her condit ional st at ement (t he while st at ement ). In
Per l , you can nest any condit ional st at ement inside anot her . For exampl e, you can have
a while st at ement inside anot her while st at ement , as f ol l ows:
while (expr_1) {
some_statements
while (expr_2) {
inner_statement_block
}
some_more_statements
}
Simil ar l y, you can have an if st at ement inside anot her if st at ement , or you can have a
while st at ement inside an if st at ement .
You can nest condit ional st at ement s inside elsif and else par t s of if st at ement s as
wel l :
if ($number == 0) {
# some statements go here
} elsif ($number == 1) {
while ($number2 == 19) {
# here is a place for a statement block
}
} else {
while ($number2 == 33) {
# here is a place for another statement block
}
}
The br aces ({ and }) ar ound t he st at ement bl ock f or each condit ional st at ement ensur e
t hat t he Per l int er pr et er never get s conf used.
TIP
If you pl an t o nest condit ional st at ement s, it 's a good
idea t o indent each st at ement bl ock t o indicat e how
many l evel s of nest ing you ar e using. If you wr it e code
such as t he f ol l owing, it 's easy t o get conf used:
while ($done == 0) {
print ("The value of count is", $count, "\n");
if ($count == 3) {
$done = 1;
}
$count = $count + 1;
}
Al t hough t his code is cor r ect , it 's not easy t o see t hat
t he st at ement
$done = 1;
is act ual l y inside an if st at ement t hat is inside a while
st at ement . Lar ger and mor e compl icat ed pr ogr ams
r apidl y become unr eadabl e if you do not indent pr oper l y.
Looping Using the until Statement
Anot her way t o l oop in Per l is wit h t he until st at ement . It is simil ar in appear ance t o
t he while st at ement , but it wor ks in a sl ight l y dif f er ent way.
G The while st at ement l oops while it s condit ional expr ession is t r ue.
G The until st at ement l oops until it s condit ional expr ession is t r ue (t hat is, it l oops
as l ong as it s condit ional expr ession is false).
List ing 2.7 cont ains an exampl e of t he until st at ement .

List ing 2.7. A pr ogr am t hat uses t he until st at ement .
1: #!/usr/local/bin/perl
2:
3: print ("What is 17 plus 26?\n");
4: $correct_answer = 43; # the correct answer
5: $input_answer = <STDIN>;
6: chop ($input_answer);
7: until ($input_answer == $correct_answer) {
8: print ("Wrong! Keep trying!\n");
9: $input_answer = <STDIN>;
10: chop ($input_answer);
11: }
12: print ("You've got it!\n");

$ program2_7
What is 17 plus 26?
39
Wrong! Keep trying!
43
You've got it!
$
Lines 3 and 4 set up t he l oop. Line 3 pr int s t he f ol l owing quest ion on t he
scr een
What is 17 plus 26?
Line 4 assigns t he cor r ect answer , 43, t o $correct_answer.
Lines 5 and 6 r et r ieve t he f ir st at t empt at t he answer . Line 5 r eads a l ine of input and
st or es it in $input_answer. Line 6 chops of f t he newl ine char act er .
Line 7 t est s whet her t he answer ent er ed is cor r ect by compar ing $input_answer wit h
$correct_answer. If t he t wo ar e not equal , t he Per l int er pr et er cont inues wit h l ines 8-
10; if t hey ar e equal , t he int er pr et er skips t o l ine 12.
Line 8 pr int s t he f ol l owing on t he scr een:
Wrong! Keep trying!
Line 9 r eads anot her at t empt f r om t he st andar d input f il e and st or es it in
$input_answer.
Line 10 chops of f t he newl ine char act er . At t his point , t he Per l int er pr et er jumps back
t o l ine 7 and t est s t he new at t empt .
The int er pr et er r eaches l ine 12 when t he answer is cor r ect . At t his point , t he f ol l owing
message appear s on t he scr een, and t he pr ogr am t er minat es:
You've got it!
The synt ax f or t he until st at ement is
until (expr) {
statement_block
}
As in t he while st at ement , expr is a condit ional expr ession, and statement_block is a
st at ement bl ock.
Summary
Today, you l ear ned about scal ar var iabl es and how t o assign val ues t o t hem.
Scal ar var iabl es and val ues can be used by t he ar it hmet ic oper at or s t o per f or m t he basic
ar it hmet ic oper at ions of addit ion, subt r act ion, mul t ipl icat ion, and division. The chop
l ibr ar y f unct ion r emoves t he t r ail ing newl ine char act er f r om a l ine, which enabl es you
t o r ead scal ar val ues f r om t he st andar d input f il e.
A col l ect ion of oper at ions and t heir val ues is known as an expr ession. The val ues
oper at ed on by a par t icul ar oper at or ar e cal l ed t he oper ands of t he oper at or . Each
oper at or yiel ds a r esul t , which t hen can be used in ot her oper at ions.
An expr ession can be divided int o subexpr essions, each of which is eval uat ed in t ur n.
Today you wer e int r oduced t o t he idea of a condit ional st at ement . A condit ional
st at ement consist s of t wo component s: a condit ional expr ession, which yiel ds a r esul t of
eit her t r ue or f al se; and a st at ement bl ock, which is a gr oup of st at ement s t hat is
execut ed onl y when t he condit ional expr ession is t r ue.
Some condit ional expr essions cont ain t he == oper at or , which r et ur ns t r ue if it s oper ands
ar e numer ical l y equal , and r et ur ns f al se if it s oper ands ar e not .
The f ol l owing condit ional st at ement s wer e descr ibed t oday:
G The if st at ement , which is execut ed onl y if it s condit ional expr ession is t r ue
G The if-else st at ement , which chooses bet ween t wo al t er nat ives
G The if-elsif-else st at ement , which chooses bet ween mul t ipl e al t er nat ives
G The while st at ement , which l oops whil e a condit ion is t r ue
G The until st at ement , which l oops unt il a condit ion is t r ue
You al so l ear ned about nest ing condit ional st at ement s, as wel l as about inf init e l oops
and how t o avoid t hem.
Q&A
Q: Which shoul d I use, t he while st at ement or t he until st at ement ?
A: It doesn't mat t er , r eal l y; it just depends on which, in your judgment , is easier t o
r ead.
Once you l ear n about t he ot her compar ison oper at or s on Day 4, "Mor e
Oper at or s," you'l l be abl e t o use t he while st at ement wher ever you can use an
until st at ement , and vice ver sa.
Q: In List ing 2.7, you r ead input f r om t he st andar d input f il e in t wo separ at e
pl aces. Is t her e any way I can r educe t his t o one?
A: Yes, by using t he do st at ement , which you'l l encount er on Day 8, "Mor e Cont r ol
St r uct ur es."
Q: Do I r eal l y need bot h a $done var iabl e and a $count var iabl e in List ing 2.6?
A: No. On Day 4 you'l l l ear n about compar ison oper at or s, which enabl e you t o t est
whet her a var iabl e is l ess t han or gr eat er t han a par t icul ar val ue. At t hat
point , you won't need t he $done var iabl e.
Q: How many elsif par t s can I have in an if-elsif-else st at ement ?
A: Ef f ect ivel y, as many as you l ike. (Ther e is an upper l imit , but it 's so l ar ge t hat
you ar e not l ikel y ever t o r each it .)
Q: How much nest ing of condit ional st at ement s does Per l al l ow? Can I put an
if inside a while t hat is inside an if t hat is inside an until?
A: Yes. You can nest as many l evel s deep as you l ike. Gener al l y, t hough, you don't
want t o go t oo many l evel s down because your pr ogr am wil l become dif f icul t t o
r ead.
The l ogical oper at or s, which you'l l l ear n about on Day 4, make it possibl e t o
pr oduce mor e compl icat ed condit ional expr essions. They'l l el iminat e t he need f or
t oo much nest ing.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. Def ine t he f ol l owing t er ms:
a. expr ession
b. oper and
c. condit ional st at ement
d. st at ement bl ock
e. inf init e l oop
2. When does a while st at ement st op l ooping?
3. When does an until st at ement st op l ooping?
4. What does t he == oper at or do?
5. What is t he r esul t when t he f ol l owing expr ession is eval uat ed?
14 + 6 * 3 - 10 / 2
6. Which of t he f ol l owing ar e l egal scal ar var iabl e names?
a. $hello
b. $_test
c. $now_is_the_time_to_come_to_the_aid_of_the_party
d. $fries&gravy
e. $96tears
f . $tea_for_2
Exercises
1. Wr it e a Per l pr ogr am t hat r eads in a number , mul t ipl ies it by 2, and pr int s t he
r esul t .
2. Wr it e a Per l pr ogr am t hat r eads in t wo number s and does t he f ol l owing:
H It pr int s Error: can't divide by zero if t he second number is 0.
H If t he f ir st number is 0 or t he second number is 1, it just pr int s t he f ir st
number (because no division is necessar y).
H In al l ot her cases, it divides t he f ir st number by t he second number and
pr int s t he r esul t .
3. Wr it e a Per l pr ogr am t hat uses t he while st at ement t o pr int out t he f ir st 10
number s (1-10) in ascending or der .
4. Wr it e a Per l pr ogr am t hat uses t he until st at ement t o pr int out t he f ir st 10
number s in descending or der (10-1).
5. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am? (Hint : t her e might be
more than one bug!)
#!/usr/local/bin/perl
$value = <STDIN>;
if ($value = 17) {
print ("You typed the number 17.\n");
else {
print ("You did not type the number 17.\n");
6. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
# program which prints the next five numbers after the
# number typed in
$input = <STDIN>;
chop ($input);
$input = $input + 1; # start with the next number;
$input = $terminate + 5; # we want to loop five times
until ($input == $terminate) {
print ("The next number is ", $terminate, "\n");

Chapter 3
Understanding Scalar Values
CONTENTS
G What Is a Scal ar Val ue?
G Int eger Scal ar Val ues
H Int eger Scal ar Val ue Limit at ions
G Fl oat ing-Point Scal ar Val ues
H Fl oat ing-Point Ar it hmet ic and Round-Of f Er r or
G Using Oct al and Hexadecimal Not at ion
H Decimal Not at ion
H Oct al Not at ion
H Hexadecimal Not at ion
H Why Bot her ?
G Char act er St r ings
H Using Doubl e-Quot ed St r ings
H Escape Sequences
H Singl e-Quot ed St r ings
G Int er changeabil it y of St r ings and Numer ic Val ues
H Init ial Val ues of Scal ar Var iabl es
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson descr ibes ever yt hing you need t o know about scal ar val ues in Per l .
Today, you l ear n about t he f ol l owing:
G Scal ar val ues
G How int eger s ar e r epr esent ed
G Fl oat ing-point val ues
G The oct al and hexadecimal not at ions
G Char act er st r ings, and using t he doubl e-quot e and singl e-quot e char act er s t o
encl ose t hem
G Escape sequences
G The int er changeabil it y of char act er st r ings and numer ic val ues
What Is a Scalar Value?
Basical l y, a scalar value is one unit of dat a. This unit of dat a can be eit her a number or a
chunk of t ext .
Ther e ar e sever al t ypes of scal ar val ues t hat Per l under st ands. Today's l esson descr ibes
each of t hem in t ur n and shows you how you can use t hem.
Integer Scalar Values
The most common scal ar val ues in Per l pr ogr ams ar e int eger scal ar val ues, al so known
as integer constants or integer literals.
An int eger scal ar val ue consist s of one or mor e digit s, opt ional l y pr eceded by a pl us or
minus sign and opt ional l y cont aining under scor es.
Her e ar e a f ew exampl es:
14
10000000000
-27
1_000_000
You can use int eger scal ar val ues in expr essions or assign t hem t o scal ar var iabl es, as
f ol l ows:
$x = 12345;
if (1217 + 116 == 1333) {
# statement block goes here
}
Integer Scalar Value Limitations
In Per l , t her e is a l imit on t he size of int eger s incl uded in a pr ogr am. To see what t his
l imit is and how it wor ks, t ake a l ook at List ing 3.1, which pr int s out int eger s of var ious
sizes.

List ing 3.1. A pr ogr am t hat displ ays int eger s and il l ust r at es t heir size
l imit at ions.
1: #!/usr/local/bin/perl
2:
3: $value = 1234567890;
4: print ("first value is ", $value, "\n");
5: $value = 1234567890123456;
6: print ("second value is ", $value, "\n");
7: $value = 12345678901234567890;
8: print ("third value is ", $value, "\n");

$ program3_1
first value is 1234567890
second value is 1234567890123456
third value is 12345678901234567168
$
This pr ogr am assigns int eger scal ar val ues t o t he var iabl e $value, and t hen
pr int s $value
Lines 3 and 4 st or e and pr int t he val ue 1234567890 wit hout any dif f icul t y. Simil ar l y,
l ines 5 and 6 successf ul l y st or e and pr int t he val ue 1234567890123456.
Line 7 at t empt s t o assign t he val ue 12345678901234567890 t o $value. Unf or t unat el y, t his
number is t oo big f or Per l t o under st and. When l ine 8 pr int s out t he val ue assigned t o
$value, it pr int s out
12345678901234567168
As you can see, t he l ast t hr ee digit s have been r epl aced wit h dif f er ent val ues.
Her e's what has happened: Per l act ual l y st or es int eger s in t he f l oat ing-point r egist er s
on your machine. In ot her wor ds, int eger s ar e t r eat ed as if t hey ar e f l oat ing-point
number s (number s cont aining decimal point s).
On most machines, f l oat ing-point r egist er s can st or e appr oximat el y 16 digit s bef or e
r unning out of space. As t he out put f r om l ine 8 shows, t he f ir st 17 digit s of t he number
12345678901234567890 ar e r emember ed and st or ed by t he Per l int er pr et er , and t he r est
ar e t hr own away. This means t hat t he val ue pr int ed by l ine 8 is not t he same as t he
val ue assigned in l ine 7.
This somewhat annoying l imit at ion on t he number of digit s in an int eger can be f ound in
al most al l pr ogr amming l anguages. In f act , many pr ogr amming l anguages have an upper
int eger l imit of 4294967295 (which is equal t o 232 minus 1).
The number of digit s t hat can be st or ed var ies f r om machine t o machine. For a mor e
det ail ed expl anat ion, r ef er t o t he discussion of pr ecision in t he f ol l owing sect ion,
"Fl oat ing-Point Scal ar Val ues."
An int eger const ant t hat st ar t s wit h a 0 is a special case:
$x = 012345;
The 0 at t he beginning of t he const ant (al so known as a
leading zero) t el l s t he Per l int er pr et er t o t r eat t his as an
octal integer constant. To f ind out about oct al int eger
const ant s, r ef er t o t he sect ion cal l ed "Using Oct al and
Hexadecimal Not at ion" l at er t oday
Floating-Point Scalar Values
As you have just seen, int eger s in Per l act ual l y ar e r epr esent ed as f l oat ing-point
number s. This means t hat an int eger scal ar val ue is act ual l y a special kind of f l oat ing-
point scal ar val ue.
In Per l , a f l oat ing-point scal ar val ue consist s of al l of t he f ol l owing:
G An opt ional minus sign (-)
G A sequence of digit s, opt ional l y cont aining a decimal point
G An opt ional exponent
Her e ar e some simpl e exampl es of f l oat ing-point scal ar val ues:
11.4
-275
-0.3
.3
3.
The opt ional exponent t el l s t he Per l int er pr et er t o mul t ipl y or divide t he scal ar val ue
by a power of t en. An exponent consist s of al l of t he f ol l owing:
G The l et t er e (E is al so accept abl e)
G An opt ional + or -
G A one-, t wo-, or t hr ee-digit number
The number in t he exponent r epr esent s t he val ue by which t o mul t ipl y or divide,
r epr esent ed as a power of 10. For exampl e, t he exponent e+01 t el l s t he Per l int er pr et er
t o mul t ipl y t he scal ar val ue by 10 t o t he power of 1, or 10. This means t hat t he scal ar
val ue 8e+01 is equival ent t o 8 mul t ipl ied by 10, or 80.
Simil ar l y, t he exponent e+02 is equival ent t o mul t ipl ying by 100, e+03 is equival ent t o
mul t ipl ying by 1,000, and so on. The f ol l owing scal ar val ues ar e al l equal :
541e+01
54.1e+02
5.41e+03
A negat ive exponent t el l s t he Per l int er pr et er t o divide by 10. For exampl e, t he val ue
54e-01 is equival ent t o 54 divided by 10, or 5.4. Simil ar l y, e-02 t el l s t he Per l int er pr et er
t o divide by 100, e-03 t o divide by 1,000, and so on.
The exponent e+00 is equival ent t o mul t ipl ying by 1, which does not hing. Ther ef or e, t he
f ol l owing val ues ar e equal :
5.12e+00
5.12
If you want , you can omit t he + when you mul t ipl y by a power of t en.
5.47e+03
5.47e03
List ing 3.2 shows how Per l wor ks wit h and pr int s out f l oat ing-point scal ar val ues.

List ing 3.2. A pr ogr am t hat displ ays var ious f l oat ing-point scal ar
val ues.
1: #!/usr/local/bin/perl
2:
3: $value = 34.0;
4: print ("first value is ", $value, "\n");
5: $value = 114.6e-01;
6: print ("second value is ", $value, "\n");
7: $value = 178.263e+19;
8: print ("third value is ", $value, "\n");
9: $value = 123456789000000000000000000000;
10: print ("fourth value is ", $value, "\n");
11: $value = 1.23e+999;
12: print ("fifth value is ", $value, "\n");
13: $value = 1.23e-999;
14: print ("sixth value is ", $value, "\n");

$ program3_2
first value is 34
second value is 11.460000000000001
third value is 1.7826300000000001e+21
fourth value is 1.2345678899999999e+29
fifth value is Infinity
sixth value is 0
$
As in List ing 3.1, t his pr ogr am st or es and pr int s var ious scal ar val ues. Line 3
assigns t he f l oat ing-point val ue 34.0 t o $value. Line 4 t hen pr int s t his val ue. Not e t hat
because t her e ar e no signif icant digit s af t er t he decimal point , t he Per l int er pr et er
t r eat s 34.0 as if it is an int eger
Line 5 assigns 114.6e-01 t o $value, and l ine 6 pr int s t his val ue. Whenever possibl e, t he
Per l int er pr et er r emoves any exponent s, shif t ing t he decimal point appr opr iat el y. As a
r esul t , l ine 6 pr int s out
11.460000000000001
which is 114.6e-01 wit h t he exponent e-01 r emoved and t he decimal point shif t ed one
pl ace t o t he l ef t (which is equival ent t o dividing by 10).
Not e t hat t he number pr int ed by l ine 6 is not exact l y equal t o t he val ue assigned in l ine
5. This is a r esul t of round-off error. The f l oat ing-point r egist er cannot cont ain t he exact
val ue 11.46, so it comes as cl ose as it can. It comes pr et t y cl ose-in f act , t he f ir st 16 digit s
ar e cor r ect . This number of cor r ect digit s is known as t he precision, and it is a pr oper t y of
t he machine on which you ar e wor king; t he pr ecision of a f l oat ing-point number var ies
f r om machine t o machine. (The machine on which I r an t hese t est exampl es suppor t s a
f l oat ing-point pr ecision of 16 or 17 digit s. This is about nor mal .)
NOTE
The size of an int eger is r oughl y equival ent t o t he
suppor t ed f l oat ing-point pr ecision. If a machine suppor t s
a f l oat ing-point pr ecision of 16 digit s, an int eger can be
appr oximat el y 16 digit s l ong.
Line 6 shows t hat a f l oat ing-point val ue has it s exponent r emoved whenever possibl e.
Lines 7 and 8 show what happens when a number is t oo l ar ge t o be convenient l y
displ ayed wit hout t he exponent . In t his case, t he number is displ ayed in scient if ic
not at ion.
In scientific notation, one digit appear s bef or e t he decimal point , and al l t he ot her
signif icant digit s (t he r est of t he machine's pr ecision) f ol l ow t he decimal point . The
exponent is adjust ed t o r ef l ect t his. In t his exampl e, t he number
178.263e+19
is conver t ed int o scient if ic not at ion and becomes
1.7826300000000001e+21
As you can see, t he decimal point has been shif t ed t wo pl aces t o t he l ef t , and t he
exponent has, as a consequence, been adjust ed f r om 19 t o 21. As bef or e, t he 1 at t he end is
an exampl e of r ound-of f er r or .
If an int eger is t oo l ar ge t o be displ ayed convenient l y, t he Per l int er pr et er conver t s it
t o scient if ic not at ion. Lines 9 and 10 show t his. The number
123456789000000000000000000000
is conver t ed t o
1.2345678899999999e+29
Her e, scient if ic not at ion becomes usef ul . At a gl ance, you can t el l appr oximat el y how
l ar ge t he number is. (In convent ional not at ion, you can't do t his wit hout count ing t he
zer os.)
Lines 11 and 12 show what happens when t he Per l int er pr et er is given a number t hat is
t oo l ar ge t o f it int o t he machine's f l oat ing-point r egist er . In t his case, Per l just pr int s
t he wor d Infinity.
The maximum size of a f l oat ing-point number var ies f r om machine t o machine. Gener al l y,
t he l ar gest possibl e exponent t hat can be st or ed is about e+308.
Lines 13 and 14 il l ust r at e t he case of a number having a negat ive exponent t hat is t oo
l ar ge (t hat is, it 's t oo smal l t o st or e). In such cases, Per l eit her get s as cl ose as it can or
just pr int s 0.
The l ar gest negat ive exponent t hat pr oduces r el iabl e val ues is about e-309. Bel ow t hat ,
accur acy diminishes.
Floating-Point Arithmetic and Round-Off Error
The ar it hmet ic oper at ions you saw on Day 2, "Basic Oper at or s and Cont r ol Fl ow," al so
wor k on f l oat ing-point val ues. On t hat day, you saw an exampl e of a mil es-t o-kil omet er s
conver sion pr ogr am t hat uses f l oat ing-point ar it hmet ic.
When you per f or m f l oat ing-point ar it hmet ic, you must r emember t he pr obl ems wit h
pr ecision and r ound-of f er r or . List ing 3.3 il l ust r at es what can go wr ong and shows you
how t o at t ack t his pr obl em.

List ing 3.3. A pr ogr am t hat il l ust r at es r ound-of f er r or pr obl ems in
f l oat ing-point ar it hmet ic.
1: #!/usr/local/bin/perl
2:
3: $value = 9.01e+21 + 0.01 - 9.01e+21;
4: print ("first value is ", $value, "\n");
5: $value = 9.01e+21 - 9.01e+21 + 0.01;
6: print ("second value is ", $value, "\n");

$ program3_3
first value is 0
second value is 0.01
$
Line 3 and l ine 5 bot h subt r act 9.01e+21 f r om it sel f and add 0.01. However , as
you can see when you examine t he out put pr oduced by l ine 4 and l ine 6, t he or der in
which you per f or m t he addit ion and subt r act ion has a signif icant ef f ect
In l ine 3, a ver y smal l number , 0.01, is added t o a ver y l ar ge number , 9.01e+21. If you
wor k it out your sel f , you see t hat t he r esul t is 9.01000000000000000000001e+21.
The f inal 1 in t he pr eceding number can be r et ained onl y on machines t hat suppor t 24
digit s of pr ecision in t heir f l oat ing-point number s. Most machines, as you've seen, handl e
onl y 16 or 17 digit s. As a r esul t , t he f inal 1, al ong wit h some of t he zer os, is l ost , and t he
number inst ead is st or ed as 9.0100000000000000e+21.
This is t he same as 9.01e+21, which means t hat subt r act ing 9.01e+21 yiel ds zer o. The 0.01
is l ost al ong t he way.
Line 5, however , doesn't have t his pr obl em. The t wo l ar ge number s ar e oper at ed on f ir st ,
yiel ding 0, and t hen 0.01 is added. The r esul t is what you expect : 0.01.
The mor al of t he st or y: Fl oat ing-point ar it hmet ic is accur at e onl y when you bunch
t oget her oper at ions on l ar ge number s. If t he ar it hmet ic oper at ions ar e on val ues st or ed
in var iabl es, it might not be as easy t o spot t his pr obl em.
$result = $number1 + $number2 - $number3;
If $number1 and $number3 cont ain l ar ge number s and $number2 is smal l , $result is l ikel y
t o cont ain an incor r ect val ue because of t he pr obl em demonst r at ed in List ing 3.3.
Using Octal and Hexadecimal Notation
So f ar , al l t he int eger scal ar val ues you've seen have been in what nor mal l y is cal l ed
base 10 or decimal notation. Per l al so enabl es you t o use t wo ot her not at ions t o r epr esent
int eger scal ar val ues:
G Base 8 not at ion, or octal
G Base 16 not at ion, or hexadecimal (somet imes shor t ened t o hex)
To use oct al not at ion, put a zer o in f r ont of your int eger scal ar val ue:
$result = 047;
This assigns 47 oct al , or 39 decimal , t o $result.
To use hexadecimal not at ion, put 0x in f r ont of your int eger scal ar val ue, as f ol l ows:
$result = 0x1f;
This assigns 1f hexadecimal , or 31 decimal , t o $result.
Per l accept s eit her upper case l et t er s or l ower case l et t er s as r epr esent at ions of t he
digit s a t hr ough f :
$result = 0xe;
$result = 0xE;
Bot h of t he pr eceding st at ement s assign 14 (decimal ) t o $result.
If you ar e not f amil iar wit h oct al and hexadecimal not at ions and woul d l ike t o l ear n
mor e, r ead t he f ol l owing sect ions. These sect ions expl ain how t o conver t number s t o
dif f er ent bases. If you ar e f amil iar wit h t his concept , you can skip t o t he sect ion cal l ed
"Char act er St r ings."
Decimal Notation
To under st and how t he oct al and hexadecimal not at ions wor k, t ake a cl oser l ook at
what t he st andar d decimal not at ion act ual l y r epr esent s.
In decimal not at ion, each digit in a number has one of 10 val ues: t he st andar d number s 0
t hr ough 9. Each digit in a number in decimal not at ion cor r esponds t o a power of 10.
Mat hemat ical l y, t he val ue of a digit x in a number is
x * 10 to the exponent n,
wher e n is t he number of digit s you have t o skip bef or e r eaching x.
This might sound compl icat ed, but it 's r eal l y st r aight f or war d. For exampl e, t he number
243 can be expr essed as f ol l ows:
G 2 * 10 t o t he exponent 2 (which is 200), pl us
G 4 * 10 t o t he exponent 1 (which is 40), pl us
G 3 * 10 t o t he exponent 0 (which is 3 * 1, which is 3)
Adding t he t hr ee number s t oget her yiel ds 243.
Octal Notation
Wor king t hr ough t hese st eps might seem l ike a wast e of t ime when you ar e deal ing wit h
decimal not at ion. However , once you under st and t his met hod, r eading number s in ot her
not at ions becomes simpl e.
For exampl e, in oct al not at ion, each digit x in a number is
x * 8 to the exponent n
wher e x is t he val ue of t he digit , and n is t he number of digit s t o skip bef or e r eaching x.
This is t he same f or mul a as in decimal not at ion, but wit h t he 10 r epl aced by 8.
Using t his met hod, her e's how t o det er mine t he decimal equival ent of 243 oct al :
G 2 * 8 t o t he exponent 2, which is 2 * 64, or 128, pl us
G 4 * 8 t o t he exponent 1, which is 4 * 8, or 32, pl us
G 3 * 8 t o t he exponent 0, which is 3 * 1, or 3
Adding 128, 32 and 3 yiel ds 163, which is t he decimal not at ion equival ent of 243 oct al .
Hexadecimal Notation
Hexadecimal not at ion wor ks t he same way, but wit h 16 as t he base inst ead of 10 or 8. For
exampl e, her e's how t o conver t 243 hexadecimal t o decimal not at ion:
G 2 * 16 t o t he exponent 2, which is 2 * 256, or 512, pl us
G 4 * 16 t o t he exponent 1, which is 4 * 16, or 64, pl us
G 3 * 16 t o t he exponent 0, which is 3 * 1, or 3
Adding t hese t hr ee number s t oget her yiel ds 579.
Not e t hat t he l et t er s a t hr ough f r epr esent t he number s 10 t hr ough 15, r espect ivel y.
For exampl e, her e's t he hexadecimal number f e in decimal not at ion:
G 15 * 16 t o t he exponent 1, which is 15 * 16, or 240, pl us
G 14 * 16 t o t he exponent 0, which is 14 * 1, or 14
Adding 240 and 14 yiel ds 254, which is t he decimal equival ent of f e.
Why Bother?
You might be wonder ing why Per l bot her s suppor t ing oct al and hexadecimal not at ion.
Her e's t he answer : Comput er s st or e number s in memor y in binar y (base 2) not at ion, not
decimal (base 10) not at ion. Because 8 and 16 ar e mul t ipl es of 2, it is easier t o r epr esent
st or ed comput er memor y in base 8 or base 16 t han in base 10. (You coul d use base 2, of
cour se; however , base 2 number s ar e cl umsy because t hey ar e ver y l ong.)
NOTE
Per l suppor t s base-2 oper at ions on int eger scal ar val ues.
These oper at ions, cal l ed bit -manipul at ion oper at ions, ar e
discussed on Day 4, "Mor e Oper at or s.
Character Strings
On pr evious days, you've seen t hat Per l enabl es you t o assign t ext t o scal ar var iabl es. In
t he f ol l owing st at ement , f or inst ance
$var = "This is some text";
t he t ext This is some text is an exampl e of what is cal l ed a character string (f r equent l y
shor t ened t o just string). A char act er st r ing is a sequence of one or mor e l et t er s, digit s,
spaces, or special char act er s.
The f ol l owing subsect ions show you
G How you can subst it ut e f or scal ar var iabl es in char act er st r ings
G How t o add escape sequences t o your char act er st r ings
G How t o t el l t he Per l int er pr et er not t o subst it ut e f or scal ar var iabl es
NOTE
C pr ogr ammer s shoul d be advised t hat char act er st r ings
in Per l do not cont ain a hidden nul l char act er at t he
end of t he st r ing. In Per l , nul l char act er s can appear
anywher e in a st r ing. (See t he discussion of escape
sequences l at er t oday f or mor e det ail s.
Using Double-Quoted Strings
Per l suppor t s scalar variable substitution in char act er st r ings encl osed by doubl e quot at ion-
mar k char act er s. For exampl e, consider t he f ol l owing assignment s:
$number = 11;
$text = "This text contains the number $number.";
When t he Per l int er pr et er sees $number inside t he st r ing in t he second st at ement , it
r epl aces $number wit h it s cur r ent val ue. This means t hat t he st r ing assigned t o $text is
act ual l y
This text contains the number 11.
The most immediat e pr act ical appl icat ion of t his is in t he print st at ement . So f ar , many of
t he print st at ement s you have seen cont ain sever al ar gument s, as in t he f ol l owing:
print ("The final result is ", $result, "\n");
Because Per l suppor t s scal ar var iabl e subst it ut ion, you can combine t he t hr ee ar gument s
t o print int o a singl e ar gument , as in t he f ol l owing:
print ("The final result is $result\n");
NOTE
Fr om now on, exampl es and l ist ings t hat cal l print use
scal ar var iabl e subst it ut ion because it is easier t o r ead
Escape Sequences
Char act er st r ings t hat ar e encl osed in doubl e quot es accept escape sequences f or special
char act er s. These escape sequences consist of a backsl ash (\) f ol l owed by one or mor e
char act er s. The most common escape sequence is \n, which r epr esent s t he newl ine
char act er as shown in t his exampl e:
$text = "This is a string terminated by a newline\n";
Tabl e 3.1 l ist s t he escape sequences r ecognized in doubl e-quot ed st r ings.
Tabl e 3.1. Escape sequences in st r ings.
Escape
Sequence
Descr ipt ion
\a
Bel l (beep)
\b
Backspace
\cn
The Ct r l +n char act er
\e
Escape
\E
Ends t he ef f ect of \L, \U or \Q
\f
For m f eed
\l
For ces t he next l et t er int o
l ower case
\L
Al l f ol l owing l et t er s ar e
l ower case
\n
Newl ine
\r
Car r iage r et ur n
\Q
Do not l ook f or special pat t er n
char act er s
\t
Tab
\u
For ce next l et t er int o upper case
\U
Al l f ol l owing l et t er s ar e
upper case
\v
Ver t ical t ab
The \Q escape sequence is usef ul onl y when t he st r ing is used as a pat t er n. Pat t er ns ar e
descr ibed on Day 7, "Pat t er n Mat ching."
The escape sequences \L, \U, and \Q can be t ur ned of f by \E, as f ol l ows:
$a = "T\LHIS IS A \ESTRING"; # same as "This is a STRING"
To incl ude a backsl ash or doubl e quot e in a doubl e-quot ed st r ing, pr ecede t he backsl ash
or quot e wit h anot her backsl ash:
$result = "A quote \" in a string";
$result = "A backslash \\ in a string";
A backsl ash al so enabl es you t o incl ude a $ char act er in a st r ing. For exampl e, t he
st at ement s
$result = 14;
print("The value of \$result is $result.\n");
pr int t he f ol l owing on your scr een:
The value of $result is 14.
You can specif y t he ASCII val ue f or a char act er in base 8 or oct al not at ion using \nnn,
wher e each n is an oct al digit ; f or exampl e:
$result = "\377"; # this is the character 255, or EOF
You can al so use hexadecimal not at ion t o specif y t he ASCII val ue f or a char act er . To do
t his, use t he sequence \xnn, wher e each n is a hexadecimal digit .
$result = "\xff"; # this is also 255
List ing 3.4 is an exampl e of a pr ogr am t hat uses escape sequences. This pr ogr am t akes a
l ine of input and conver t s it t o a var iet y of cases.

List ing 3.4. A case-conver sion pr ogr am.
1: #!/usr/local/bin/perl
2:
3: print ("Enter a line of input:\n");
4: $inputline = <STDIN>;
5: print ("uppercase: \U$inputline\E\n");
6: print ("lowercase: \L$inputline\E\n");
7: print ("as a sentence: \L\u$inputline\E\n");

$ program3_4
Enter a line of input:
tHis Is My INpUT LiNE.
uppercase: THIS IS MY INPUT LINE.
lowercase: this is my input line.
as a sentence: This is my input line.
$
Line 3 of t his pr ogr am r eads a l ine of input and st or es it in t he scal ar var iabl e
$inputline
Line 5 r epl aces t he st r ing $inputline wit h t he cur r ent val ue of t he scal ar var iabl e
$inputline. The escape char act er \U t el l s t he Per l int er pr et er t o conver t ever yt hing in
t he st r ing int o upper case unt il it sees a \E char act er ; as a r esul t , l ine 4 wr it es t he
cont ent s of $inputline in upper case.
Simil ar l y, l ine 6 wr it es t he input l ine in al l l ower case char act er s by specif ying t he
escape char act er \L in t he st r ing.
Line 7 combines t he escape char act er s \L and \u. The \L specif ies t hat ever yt hing in t he
st r ing is t o be in l ower case; however , t he \u special char act er t empor ar il y over r ides t his
and t el l s t he Per l int er pr et er t hat t he next char act er is t o be in upper case. When t his
char act er -t he f ir st char act er in t he l ine-is pr int ed, t he \L escape char act er r emains in
f or ce, and t he r est of t he l ine is pr int ed in l ower case. The r esul t is as if t he input l ine is
a singl e sent ence in Engl ish. The f ir st char act er is capit al ized, and t he r emainder is in
l ower case.
Single-Quoted Strings
Per l al so enabl es you t o encl ose st r ings using t he ' (singl e quot at ion mar k) char act er :
$text = 'This is a string in single quotes';
Ther e ar e t wo dif f er ences bet ween doubl e-quot ed st r ings and singl e-quot ed st r ings. The
f ir st dif f er ence is t hat scal ar var iabl es ar e r epl aced by t heir val ues in doubl e-quot ed
st r ings but not in singl e-quot ed st r ings. The f ol l owing is an exampl e:
$string = "a string";
$text = "This is $string"; # becomes "This is a string"
$text = 'This is $string'; # remains 'This is $string'
The second dif f er ence is t hat t he backsl ash char act er , \, does not have a special meaning
in singl e-quot ed st r ings. This means t hat t he st at ement
$text = 'This is a string.\n';
assigns t he f ol l owing st r ing t o $text:
This is a string.\n
The \ char act er is special in onl y t wo inst ances f or singl e-quot ed st r ings. The f ir st is
when you want t o incl ude a singl e-quot e char act er ' in a st r ing.
$text = 'This string contains \', a quote character';
The pr eceding l ine of code assigns t he f ol l owing st r ing t o $text:
This string contains ', a quote character
The second inst ance is t o escape t he backsl ash it sel f .
$text = 'This string ends with a backslash \\';
The pr eceding code l ine assigns t he f ol l owing st r ing t o $text:
This string ends with a backslash \
As you can see, t he doubl e backsl ash makes it possibl e f or t he backsl ash char act er (\) t o
be t he l ast char act er in a st r ing.
Singl e-quot ed st r ings can be spr ead over mul t ipl e l ines.
The st at ement
$text = 'This is two
lines of text
';
is equival ent t o t he st at ement
$text = "This is two\nlines of text\n";
This means t hat if you f or get t he cl osing ' f or a st r ing,
t he Per l int er pr et er is l ikel y t o get quit e conf used
because it won't det ect an er r or unt il af t er it st ar t s
pr ocessing t he next l ine
Interchangeability of Strings and Numeric Values
As you've seen, you can use a scal ar var iabl e t o st or e a char act er st r ing, an int eger , or a
f l oat ing-point val ue. In scal ar var iabl es, a val ue t hat was assigned as a st r ing can be
used as an int eger whenever it makes sense t o do so, and vice ver sa. In t he f ol l owing
exampl e:
$string = "43";
$number = 28;
$result = $string + $number;
t he val ue of $string is conver t ed t o an int eger and added t o t he val ue of $number. The
r esul t of t he addit ion, 71, is assigned t o $result.
Anot her inst ance in which st r ings ar e conver t ed t o int eger s is when you ar e r eading a
number f r om t he st andar d input f il e. The f ol l owing is some code simil ar t o code you've
seen bef or e:
$number = <STDIN>;
chop ($number);
$result = $number + 1;
This is what is happening: When $number is assigned a l ine of st andar d input , it r eal l y is
being assigned a st r ing. For inst ance, if you ent er 22, $number is assigned t he st r ing 22\n
(t he \n r epr esent s t he newl ine char act er ). The chop f unct ion r emoves t he \n, l eaving t he
st r ing 22, and t his st r ing is conver t ed t o t he number 22 in t he ar it hmet ic expr ession.
If a st r ing cont ains char act er s t hat ar e not digit s, t he
st r ing is conver t ed t o 0 when used in an int eger cont ext .
For exampl e:
$result = "hello" * 5;
# this assigns 0 to $result, since "hello" becomes
0
This is t r ue even if t he st r ing is a val id hexadecimal
int eger if t he quot es ar e r emoved, as in t he f ol l owing:
$result = "0xff" + 1;
In cases l ike t his, Per l does not t el l you t hat anyt hing
has gone wr ong, and your r esul t s might not be what you
expect .
Al so, st r ings cont aining mispr int s might not cont ain
what you expect . For exampl e:
$result = "12O34"; # the letter O, not the number 0
When conver t ing f r om a st r ing t o an int eger , Per l st ar t s
at t he l ef t and cont inues unt il it sees a l et t er t hat is
not a digit . In t he pr eceding inst ance, 12O34 is conver t ed
t o t he int eger 12, not 12034
Initial Values of Scalar Variables
In Per l , al l scal ar var iabl es have an init ial val ue of t he nul l st r ing, "". This means t hat
you do not need t o def ine a val ue f or a scal ar var iabl e.
#!/usr/local/bin/perl
$result = $undefined + 2; # $undefined is not defined
print ("The value of \$result is $result.\n");
This shor t pr ogr am is per f ect l y l egal Per l . The out put is
The value of $result is 2.
Because $undefined is not def ined, t he Per l int er pr et er assumes t hat it s val ue is t he
nul l st r ing. This nul l st r ing is t hen conver t ed t o 0, because it is being used in an
addit ion oper at ion. The r esul t of t he addit ion, 2, is assigned t o $result.
TIP
Al t hough you can use uninit ial ized var iabl es in your
Per l pr ogr ams, you shoul dn't . If your Per l pr ogr am get s
t o be l ar ge (as many compl icat ed pr ogr ams do), it might be
dif f icul t t o det er mine whet her a par t icul ar var iabl e is
supposed t o be appear ing f or t he f ir st t ime or whet her it
is a spel l ing mist ake t hat shoul d be f ixed. To avoid
ambiguit y and t o make l if e easier f or your sel f , init ial ize
ever y scal ar var iabl e bef or e using it
Summary
Per l suppor t s t hr ee kinds of scal ar val ues: int eger s, f l oat ing-point number s, and
char act er st r ings.
Int eger s can be in t hr ee not at ions: st andar d (decimal ) not at ion, oct al not at ion, and
hexadecimal not at ion. Oct al not at ion is indicat ed by a l eading 0, and hexadecimal
not at ion is indicat ed by a l eading 0x. Int eger s ar e st or ed as f l oat ing-point val ues and
can be as l ong as t he machine's f l oat ing-point pr ecision (usual l y 16 digit s or so).
Fl oat ing-point number s can consist of a st r ing of digit s t hat cont ain a decimal point and
an opt ional exponent . The exponent 's r ange can be anywher e f r om about e-309 t o e+308.
(This val ue might be dif f er ent on some machines.) When possibl e, f l oat ing-point number s
ar e displ ayed wit hout t he exponent ; f ail ing t hat , t hey ar e displ ayed in scient if ic
not at ion (one digit bef or e t he decimal point ).
When you use f l oat ing-point ar it hmet ic, be al er t f or r ound-of f er r or s. Per f or ming
ar it hmet ic oper at ions in t he pr oper or der -oper at ing on l ar ge number s f ir st -might yiel d
bet t er r esul t s.
You can encl ose char act er st r ings in eit her doubl e quot es (") or singl e quot es ('). If a
scal ar var iabl e name appear s in a char act er st r ing encl osed in doubl e quot es, t he val ue
of t he var iabl e is subst it ut ed f or it s name. Escape char act er s ar e r ecognized in st r ings
encl osed in doubl e quot es; t hese char act er s ar e indicat ed by a backsl ash (\).
Char act er st r ings in singl e quot es do not suppor t escape char act er s, wit h t he except ion
of \\ and \'. Scal ar var iabl e names ar e not r epl aced by t heir val ues.
St r ings and int eger s ar e f r eel y int er changeabl e in Per l whenever it is l ogical l y possibl e
t o do so.
Q&A
Q: If Per l char act er st r ings ar e not t er minat ed by nul l char act er s, how does
t he Per l int er pr et er know t he l engt h of a st r ing?
A: The Per l int er pr et er keeps t r ack of t he l engt h of a st r ing as wel l as it s cont ent s.
In Per l , you do not need t o use a nul l char act er t o indicat e "end of st r ing."
Q: Why does Per l use f l oat ing-point r egist er s f or f l oat ing-point ar it hmet ic
even t hough t hey cause r ound-of f er r or s?
A: Basical l y, it 's a per f or mance issue. It 's possibl e t o wr it e r out ines t hat st or e
f l oat ing-point number s as st r ings and conver t par t s of t hese st r ings t o number s
as necessar y; however , you of t en don't need mor e t han 16 or so digit s of pr ecision
anyway.
Appl icat ions t hat need t o do high-speed ar it hmet ic cal cul at ions of gr eat
pr ecision usual l y r un on special comput er s designed f or t hat pur pose.
Q: What happens if I f or get t o cal l chop when r eading a number f r om t he
st andar d input f il e?
A: As it happens, not hing. Per l is smar t enough t o ignor e whit e space at t he end of a
l ine t hat consist s onl y of a number . However , it 's a good idea t o get int o t he
habit of using chop t o get r id of a t r ail ing newl ine at al l t imes, because t he
t r ail ing newl ine becomes signif icant when you st ar t doing st r ing compar isons.
(You'l l l ear n about st r ing compar isons on Day 4, "Mor e Oper at or s.")
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. Def ine t he f ol l owing t er ms:
a round-off error
b octal notation
c precision
d scientific notation
2. Conver t t he f ol l owing number s f r om oct al not at ion t o decimal :
a 0377
b 06
c 01131
3. Conver t t he f ol l owing number s f r om hexadecimal not at ion t o decimal not at ion:
a 0xff
b 0x11
c 0xbead
4. What does t he f ol l owing l ine pr int ?
print ("I am bored\b\b\b\b\bhappy!\n");
5. Suppose t he val ue of $num is 21. What st r ing is assigned t o $text in each of t he
f ol l owing cases?
a $text = "This string contains $num.";
b $text = "\\$num is my favorite number.";
c $text = 'Assign \$num to this string.';
6. Conver t t he f ol l owing number s t o scient if ic not at ion:
a 43.71
b 0.000006e-02
c 3
d -1.04
Exercises
1. Wr it e a pr ogr am t hat pr int s ever y number f r om 0 t o 1 t hat has a singl e digit af t er
t he decimal pl ace (t hat is, 0.1, 0.2, and so on).
2. Wr it e a pr ogr am t hat r eads a l ine of input and pr int s out t he f ol l owing:
H 1 if t he l ine consist s of a non-zer o int eger
H 0 if t he l ine consist s of 0 or a st r ing
(Hint : Remember t hat char act er st r ings ar e conver t ed t o 0 when t hey ar e
conver t ed t o int eger s.)
3. Wr it e a pr ogr am t hat asks f or a number and keeps t r ying unt il you ent er t he
number 47. At t hat point , it pr int s Correct! and r ings a bel l .
4. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
$inputline = <STDIN>;
print ('here is the value of \$inputline\', ": $inputline");
5. BUG BUSTER: What is wr ong wit h t he f ol l owing code f r agment ?
$num1 = 6.02e+23;
$num2 = 11.4;
$num3 = 5.171e+22;
$num4 = -2.5;
$result = $num1 + $num2 - $num3 + $num4;
6. BUG BUSTER: What is wr ong wit h t he f ol l owing st at ement ?
$result = "26" + "0xce" + "1";

Chapter 4
More Operators
CONTENTS
G Using t he Ar it hmet ic Oper at or s
H Exponent iat ion
H The Remainder Oper at or
H Unar y Negat ion
G Using Compar ison Oper at or s
H Int eger -Compar ison Oper at or s
H St r ing-Compar ison Oper at or s
H St r ing Compar ison Ver sus Int eger Compar ison
H Compar ison and Fl oat ing-Point Number s
G Using Logical Oper at or s
H Eval uat ion Wit hin Logical Oper at or s
H Logical Oper at or s as Subexpr essions
G Using Bit -Manipul at ion Oper at or s
H What Bit s Ar e and How They Ar e Used
H The Bit -Manipul at ion Oper at or s
G Using t he Assignment Oper at or s
H Assignment Oper at or s as Subexpr essions
G Using Aut oincr ement and Aut odecr ement
H The Aut oincr ement Oper at or Pr e-Incr ement
H The Aut oincr ement Oper at or Post -Incr ement
H The Aut odecr ement Oper at or
H Using Aut oincr ement Wit h St r ings
G The St r ing Concat enat ion and Repet it ion Oper at or s
H The St r ing-Concat enat ion Oper at or
H The St r ing-Repet it ion Oper at or
H Concat enat ion and Assignment
G Ot her Per l Oper at or s
H The Comma Oper at or
H The Condit ional Oper at or
G The Or der of Oper at ions
H Pr ecedence
H Associat ivit y
H For cing Pr ecedence Using Par ent heses
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
On Day 2, "Basic Oper at or s and Cont r ol Fl ow," you l ear ned about t he f ol l owing
oper at or s:
G The ar it hmet ic oper at or s +, -, *, and /
G The compar ison oper at or ==
G The assignment oper at or =
Today, you l ear n about t he r est of t he oper at or s t hat Per l pr ovides, as wel l as about
oper at or associat ivit y and pr ecedence. The oper at or s ar e
G The ar it hmet ic oper at or s **, %, and - (unar y negat ion)
G The ot her int eger - and st r ing-compar ison oper at or s
G The l ogical oper at or s
G The bit -manipul at ion oper at or s
G The assignment oper at or s
G Aut oincr ement and aut odecr ement
G Concat enat ing and r epeat ing st r ings
G The comma and condit ional oper at or s
Using the Arithmetic Operators
The ar it hmet ic oper at or s t hat you have seen so f ar -t he +, -, *, and / oper at or s-wor k t he
way you expect t hem t o: They per f or m t he oper at ions of addit ion, subt r act ion,
mul t ipl icat ion, and division.
Per l al so suppor t s t hr ee ot her ar it hmet ic oper at ions:
G Exponent iat ion
G The modul o or r emainder oper at ion
G Unar y negat ion
Al t hough t hese oper at or s ar en't as int uit ivel y obvious as t he ones you've al r eady seen,
t hey ar e quit e easy t o use.
Exponentiation
The exponentiation operator, **, pr ovides a convenient way t o mul t ipl y a number by it sel f
r epeat edl y. For exampl e, her e is a simpl e Per l st at ement t hat uses t he exponent iat ion
oper at or :
$x = 2 ** 4;
The expr ession 2 ** 4 means "t ake f our copies of t wo and mul t ipl y t hem." This st at ement
assigns 16 t o t he scal ar var iabl e $x.
Not e t hat t he f ol l owing st at ement s ar e equival ent , but t he f ir st st at ement is much mor e
concise:
$x = 2 ** 7;
$x = 2 * 2 * 2 * 2 * 2 * 2 * 2;
When an exponent iat ion oper at or is empl oyed, t he base val ue (t he val ue t o t he l ef t of
t he **) is t he number t o be r epeat edl y mul t ipl ied. The number t o t he r ight , cal l ed t he
exponent, is t he number of t imes t he mul t ipl icat ion is t o be per f or med. Her e ar e some ot her
simpl e exampl es of t he exponent iat ion oper at or :
$x = 9 ** 2; # 9 squared, or 81
$x = 2 ** 3; # 2 * 2 * 2, or 8
$x = 43 ** 1; # this is just 43
The ** oper at or al so wor ks on t he val ues st or ed in var iabl es:
$x = $y ** 2;
Her e, t he val ue st or ed in $y is mul t ipl ied by it sel f , and t he r esul t is st or ed in $x. $y is not
changed by t his oper at ion.
$x = 2 ** $y;
In t his case, t he val ue st or ed in $y becomes t he exponent , and $x is assigned 2 mul t ipl ied
by it sel f $y t imes.
You can use t he exponent oper at or wit h non-int eger or negat ive exponent s:
2 ** -5 # this is the fraction 1/32
5 ** 2.5 # this is 25 * the square root of 5
List ing 4.1 shows an exampl e of a simpl e pr ogr am t hat uses t he exponent ial oper at or . It
pr ompt s f or a number , $exponent, and pr int s out 2 ** $exponent.

List ing 4.1. A pr ogr am t hat pr int s out t he power s of t wo.
1: #!/usr/local/bin/perl
2:
3: # this program asks for a number, n, and prints 2 to the
4: # exponent n
5:
6: print ("Enter the exponent to use:\n");
7: $exponent = <STDIN>;
8: chop ($exponent);
9: print ("Two to the power $exponent is ",
10: 2 ** $exponent, "\n");

$ program4_1
Enter the exponent to use:
16
Two to the power 16 is 65536
$
The pr ogr am shown in List ing 4.1 is usef ul if you have t o use, or be awar e of ,
number s such as 4,294,967,295 (t he l ar gest number t hat can be st or ed in a 32-bit unsigned
int eger ) and 2,147,483,647 (t he l ar gest number t hat can be st or ed in a 32-bit signed
int eger ). The f or mer is equival ent t o 2 ** 32 - 1, and t he l at t er is equival ent t o 2 **
31 - 1
DON' T use t he exponent oper at or wit h a negat ive base
and a non-int eger exponent :
(-5) ** 2.5 # error
The r esul t of t his expr ession is a compl ex (non-r eal )
number (just as, f or inst ance, t he squar e r oot of -2 is a
compl ex number ). Per l does not under st and compl ex
number s.
DON' T pr oduce a r esul t t hat is l ar ger t han t he l ar gest
f l oat ing-point number your machine can under st and:
10 ** 999999 # error
In t his exampl e, t he exponent is t oo l ar ge t o be st or ed on
most machines.
The Remainder Operator
The remainder operator r et r ieves t he r emainder r esul t ing f r om t he division of one int eger
by anot her . Consider t he f ol l owing simpl e exampl e:
$x = 25 % 4;
In t his case, 25 divided by 4 yiel ds 6, wit h a r emainder of 1. The r emainder , 1, is assigned t o
$x.
The % oper at or does not wor k on val ues t hat ar e not int eger s. Non-int eger s ar e
conver t ed t o int eger s, as f ol l ows:
$x = 24.77 % 4.21; # same as 25 % 4
Because division by 0 is impossibl e, you can't put a 0 t o t he r ight of a % oper at or .
$x = 25 % 0; # error: can't divide by 0
$x = 25 % 0.1; # error: 0.1 is converted to 0
Unary Negation
The unary negation operator is a - char act er in f r ont of a singl e val ue. (This dist inguishes it
f r om t he subt r act ion oper at or , which appear s bet ween t wo val ues.) It is equival ent t o
mul t ipl ying t he val ue by -1, as il l ust r at ed by t his exampl e:
- 5; # identical to the integer -5
- $y; # equivalent to $y * -1
Using Comparison Operators
On Day 2, "Basic Oper at or s and Cont r ol Fl ow," you l ear ned about t he equal it y
compar ison oper at or (==), which compar es t wo val ues and t est s whet her t hey ar e equal .
$x = $a == $b;
Recal l t hat t he val ue of $x depends on t he val ues st or ed in $a and $b:
G If $a equal s $b, $a == $b is t r ue, and $x is assigned a nonzer o val ue.
G If $a is not equal t o $b, $a == $b is f al se, and $x is assigned 0.
The == oper at or is an exampl e of a comparison operator. Compar ison oper at or s ar e most
commonl y used in cont r ol st at ement s such as t he if st at ement , as f ol l ows:
if ($a == $b) {
print("$a is equal to $b\n");
}
In Per l , t he compar ison oper at or s ar e divided int o t wo cl asses:
G Compar ison oper at or s t hat wor k wit h number s
G Compar ison oper at or s t hat wor k wit h st r ings
Integer-Comparison Operators
Tabl e 4.1 def ines t he int eger -compar ison oper at or s avail abl e in Per l .
Tabl e 4.1. Int eger -compar ison oper at or s.
Oper at or Descr ipt ion
< Less t han
> Gr eat er t han
== Equal t o
<= Less t han or equal t o
>= Gr eat er t han or equal t o
!= Not equal t o
<=> Compar ison r et ur ning 1, 0, or -
1
Her e ar e simpl e exampl es of each of t he f ir st six oper at or s in Tabl e 4.1:
$x < 10 # true if the value of $x is less than 10
$x > 10 # true if $x is greater than 10
$x == 10 # true if $x is equal to 10
$x <= 10 # true if $x is less than or equal to 10
$x >= 10 # true if $x is greater than or equal to 10
$x != 10 # true if $x is not equal to 10
Each of t hese oper at or s yiel ds one of t wo val ues:
G Tr ue, or nonzer o
G Fal se, or zer o
The <=> oper at or is a special case. Unl ike t he ot her int eger compar ison oper at or s, <=>
r et ur ns one of t hr ee val ues:
G 0, if t he t wo val ues being compar ed ar e equal
G 1, if t he f ir st val ue is gr eat er
G -1, if t he second val ue is gr eat er
For exampl e, consider t he f ol l owing st at ement :
$y = $x <=> 10;
These ar e t he possibl e r esul t s:
G If $x is gr eat er t han 10, t he f ir st val ue in t he compar ison is gr eat er , and $y is
assigned 1.
G If $x is l ess t han 10, t he second val ue in t he compar ison is gr eat er , and $y is
assigned -1.
G If $x is equal t o 10, $y is assigned 0.
Integer Comparisons and Readability
In any given st at ement , it 's best t o use t he compar ison t hat can be most easil y r ead. For
exampl e, consider t he f ol l owing:
if (3.2 < $x) {
# conditionally executed stuff goes here
}
Al t hough t he expr ession 3.2 < $x< is per f ect l y val id, it isn't easy t o r ead because
var iabl es usual l y appear f ir st in compar isons. Inst ead, it woul d be bet t er t o use
if ($x >= 3.2) {
...
because t his is easier t o under st and. I'm not sur e exact l y why t his is t r ue; I t hink it 's
r el at ed t o t he way t he Engl ish l anguage is spoken. (Nor mal l y, we say, "If I had f ive
dol l ar s, I'd buy some mil k," inst ead of , "If f ive dol l ar s had I, I'd buy some mil k," even
t hough bot h ar e cor r ect .)
String-Comparison Operators
For ever y numer ic-compar ison oper at or , Per l def ines an equival ent st r ing-compar ison
oper at or . Tabl e 4.2 displ ays each st r ing-compar ison oper at or , t he compar ison it per f or ms,
and t he equival ent numer ic-compar ison oper at or .
Tabl e 4.2. St r ing- and numer ic-compar ison oper at or s.
St r ing
oper at or
Compar ison oper at ion Equival ent numer ic
oper at or
lt Less t han <
gt Gr eat er t han >
eq Equal t o ==
le Less t han or equal t o <=
ge Gr eat er t han or equal t o >=
ne Not equal t o !=
cmp Compar e, r et ur ning 1, 0,
or -1
<=>
Per l compar es st r ings by det er mining t heir pl aces in an al phabet ical or der . For exampl e,
t he st r ing aaa is l ess t han t he st r ing bbb, because aaa appear s bef or e bbb when t hey ar e
sor t ed al phabet ical l y.
Her e ar e some exampl es of st r ing-compar ison oper at or s in act ion:
$result = "aaa" lt "bbb"; # result is true
$result = "aaa" gt "bbb"; # result is false
$result = "aaa" eq "bbb"; # result is false
$result = "aaa" le "aaa"; # result is true
$result = "aaa" ge "bbb"; # result is false
$result = "aaa" ne "aaa"; # result is false
$result = "aaa" cmp "bbb"; # result is -1
If you ar e f amil iar wit h t he C pr ogr amming l anguage, you might have not iced t hat t he
behavior of t he cmp oper at or is ident ical t o t hat of t he C f unct ion strcmp().
String Comparison Versus Integer Comparison
You might be t hinking: If st r ings and int eger s ar e equival ent in Per l , why do we need
t wo kinds of compar ison oper at or s?
To answer t his, consider t he st r ings 123 and 45. The r esul t when t hese t wo st r ings ar e
compar ed depends on whet her a st r ing or int eger compar ison is being per f or med.
$result = "123" < "45";
$result = "123" lt "45";
In t he f ir st st at ement , t he st r ings 123 and 45 ar e conver t ed t o int eger s, and 123 is
compar ed t o 45. The r esul t is f al se and $result is assigned 0, because 123 is not l ess t han
45.
In t he second st at ement , 123 is al phabet ical l y compar ed t o 45. Because 123 is
al phabet ical l y l ess t han 45, t he r esul t in t his case is t r ue, and $result is assigned a
nonzer o val ue.
Because t hese r esul t s ar e dif f er ent , you must ensur e t hat you ar e using t he pr oper
compar ison oper at or ever y t ime. If you don't , your pr ogr am can cont ain er r or s t hat ar e
not easy t o spot . For inst ance, consider t he f ol l owing:
$var1 = "string 1";
$var2 = "string 2";
$result = $var1 == $var2; # this statement is bad
Because == is a numer ic-compar ison oper at or , t he val ues string 1 and string 2 ar e
conver t ed t o int eger s bef or e t he compar ison is per f or med. Because bot h st r ings ar e non-
numer ic, t hey ar e bot h conver t ed t o t he int eger 0, and t he f ol l owing compar ison becomes
t r ue:
$var1 == $var2
This is pr obabl y not what you want .
Comparison and Floating-Point Numbers
Ther e is one t hing t o keep in mind when you use compar ison oper at or s: Fl oat ing-point
number s don't al ways behave pr oper l y in compar isons.
Take a l ook at List ing 4.2.

List ing 4.2. A pr ogr am t hat cont ains a f l oat ing-point compar ison.
1: #!/usr/local/bin/perl
2:
3: $value1 = 14.3;
4: $value2 = 100 + 14.3 - 100;
5: if ($value1 == $value2) {
6: print("value 1 equals value 2\n");
7: } else {
8: print("value 1 does not equal value 2\n");
9: }

$ program4_2
value 1 does not equal value 2
$
At f ir st gl ance, you might t hink t hat $value1 and $value2 ar e ident ical .
However , when you r un t his pr ogr am, you get t he f ol l owing:
value 1 does not equal value 2
What is wr ong? To f ind out , pr int out t he val ues of $value1 and $value2 bef or e doing t he
compar ison.
#!/usr/local/bin/perl
$value1 = 14.3;
$value2 = 100 + 14.3 - 100;
print("value 1 is $value1, value2 is $value2\n");
if ($value1 == $value2) {
print("value 1 equals value 2\n");
} else {
print("value 1 does not equal value 2\n");
}
When you r un t his pr ogr am, you get t he f ol l owing out put :
value 1 is 14.300000000000001, value 2 is 14.299999999999997
value 1 does not equal value 2
Wel l , Per l isn't l ying: $value1 and $value2 are dif f er ent . What happened?
To under st and what 's going on, consider what happens when you t ake an or dinar y
cal cul at or and t el l it t o divide 8 by 3. The act ual answer is
2.6666666...
wit h t he number of 6s being inf init e. Because your cal cul at or can't displ ay an inf init e
number of 6s, what it displ ays is somet hing l ike t he f ol l owing:
2.6666666667
This is as cl ose t o t he act ual number as your cal cul at or can get . The dif f er ence bet ween
t he act ual number and t he number displ ayed is an exampl e of a round-off error.
Round-of f er r or s of t en occur when Per l (or al most any ot her pr ogr amming l anguage)
st or es a f l oat ing-point number or adds a number t o a f l oat ing-point number . The
st at ement
$value1 = 14.3;
act ual l y assigns
14.300000000000001
t o $value1, because 14.3 cannot be exact l y r epr esent ed in t he machine's f l oat ing-point
st or age. When 100 is added t o t his number and subt r act ed again, t he r esul t is
14.299999999999997
Not e t hat bot h number s ar e ver y cl ose t o 14.3 but ar en't exact l y 14.3 due t o r ound-of f
er r or s. What 's wor se, each number is af f ect ed by a dif f er ent set of r ound-of f er r or s, so
t he t wo number s ar e not ident ical .
The mor al of t he st or y? Be ver y car ef ul when you use f l oat ing-point number s in
compar isons, because r ound-of f er r or s might af f ect your r esul t s.
Using Logical Operators
The compar ison oper at or s you've seen so f ar ar e suf f icient if you need t o t est f or onl y
one condit ion bef or e execut ing a par t icul ar code segment , as in t his exampl e:
if ($value == 26) {
# the code to execute if the condition is true
}
Suppose, however , t hat a par t icul ar sect ion of code is t o be execut ed onl y when a
var iet y of condit ions ar e t r ue. You can use a sequence of if st at ement s t o t est f or t he
condit ions, as f ol l ows:
if ($value1 == 26) {
if ($value2 > 0) {
if ($string1 eq "ready") {
print("all three conditions are true!\n");
}
}
}
This is t ir esome t o wr it e and not par t icul ar l y easy t o r ead.
For t unat el y, Per l pr ovides an easier way t o deal wit h mul t ipl e condit ions: t he logical
operators. The f ol l owing l ogical oper at or s ar e def ined:
$a || $b # logical or: true if either is nonzero
$a && $b # logical and: true only if both are nonzero
! $a # logical not: true if $a is zero
Per l 5 al so def ines t hese l ogical oper at or s:
$a or $b # another form of logical or
$a and $b # another form of logical and
not $a # another form of logical not
$a xor $b # logical xor: true if either $a or $b is nonzero,
but not both
The or, and, and not oper at or s l ist ed ar e ident ical t o ||, &&, and !, except t hat t heir
pr ecedence is l ower . (Operator precedence det er mines t he or der in which oper at or s ar e
eval uat ed, and is discussed l at er t oday.)
In each case, t he r esul t of t he oper at ion per f or med by a l ogical oper at or is nonzer o if
t r ue and 0 if f al se.
$a = 5;
$b = 0;
$a || $b; # true: $a is not zero
$b || $a; # also true
$a && $b; # false: $b is zero
! $a; # false: $a is nonzero, so ! $a is zero
! $b; # true: $b is zero, so ! $b is nonzero
These l ogical oper at or s enabl e you t o t est f or mul t ipl e condit ions mor e convenient l y.
Inst ead of wr it ing, f or exampl e, t his code:
if ($value1 == 26) {
if ($value2 > 0) {
if ($string1 eq "ready") {
print("all three conditions are true!\n");
}
}
}
you now can wr it e t his code inst ead:
if ($value == 26 && $value2 > 0 && $string1 eq "ready") {
print("all three conditions are true!\n");
}
In each case, t he r esul t is t he same: t he print oper at ion is per f or med onl y when $value is
26, $value2 is gr eat er t han 0, and $string1 is "r eady."
Evaluation Within Logical Operators
When Per l sees a l ogical AND oper at or or a l ogical OR oper at or , t he expr ession on t he
l ef t side of t he oper at or is al ways eval uat ed f ir st . For exampl e, consider t he f ol l owing:
$a = 0;
$b = 106;
$result = $a && $b;
When Per l is eval uat ing t he expr ession $a && $b, it f ir st checks whet her $a is 0. If $a is 0,
$a && $b must be f al se r egar dl ess of t he val ue of $b, so Per l doesn't bot her checking t he
val ue of $b. (This is cal l ed short-circuit evaluation.)
Simil ar l y, in t he f ol l owing exampl e, Per l doesn't bot her checking $b, because $a is
nonzer o and t her ef or e $a || $b must be t r ue:
$a = 43;
$b = 11;
$result = $a || $b;
You can t ake advant age of t he or der of eval uat ion of expr essions in || or && t o
saf eguar d your code.
$x == 0 || $y / $x > 5
Her e is how t he pr eceding st at ement pr ot ect s you f r om division-by-zer o er r or s:
G If $x is not 0, $x == 0 is f al se, so Per l eval uat es $y / $x > 5. This cannot pr oduce a
division-by-zer o er r or , because $x is guar ant eed t o be some val ue ot her t han 0.
G If $x is 0, $x == 0 is t r ue. This means t hat
$x == 0 || $y / $x > 5
is t r ue, so Per l doesn't bot her eval uat ing t he expr ession t o t he r ight of t he ||. As
a r esul t , t he expr ession
$y / $x > 5
is not eval uat ed when $x is 0, and t he division-by-zer o er r or is avoided.
Logical Operators as Subexpressions
Expr essions t hat cont ain l ogical oper at or s can be cont ained in l ar ger expr essions. The
f ol l owing is an exampl e:
$myval = $a || $b || $c;
Her e, Per l eval uat es t he expr ession $a || $b || $c and assigns it s val ue t o $myval.
To under st and t he behavior of t his st at ement , r ecal l t hat t he || oper at or eval uat es it s
subexpr essions in t he or der given, and eval uat es a subexpr ession onl y if t he pr evious
subexpr ession is zer o. This means t hat $b is eval uat ed onl y if $a is zer o.
When t he l ogical OR oper at or is used in a l ar ger expr ession, it s val ue is t he l ast
subexpr ession act ual l y eval uat ed, which is t he f ir st subexpr ession of t he l ogical OR
oper at or t hat is nonzer o. This means t hat
$myval = $a || $b || $c;
is equival ent t o
if ($a != 0) {
$myvalue = $a;
} elsif ($b != 0) {
$myvalue = $b;
} else {
$myvalue = $c;
}
The l ogical AND oper at or wor ks in t he same way, but isn't as usef ul . The st at ement
$myval = $a && $b && $c;
is equival ent t o
if ($a == 0) {
$myvalue = $a;
} elsif ($b == 0) {
$myvalue = $b;
} else {
$myvalue = $c;
}
This means t hat $myval is set t o eit her 0 or t he val ue of $c.
Using Bit-Manipulation Operators
Per l enabl es you t o manipul at e t he binar y digit s (or bit s) of an int eger . To under st and
how Per l does t his, f ir st l ook at what a bit is and how comput er s st or e int eger s. Once you
under st and how bit s wor k, you can easil y f igur e out how t he bit -manipul at ion oper at or s
wor k. (If you ar e f amil iar wit h binar y not at ion and t he comput er r epr esent at ion of an
int eger , f eel f r ee t o skip t he f ol l owing sect ion.)
What Bits Are and How They Are Used
On Day 3, "Under st anding Scal ar Val ues," you l ear ned t hat Per l under st ands t hr ee
dif f er ent not at ions f or int eger s:
G St andar d not at ion, or base 10
G Oct al not at ion, or base 8
G Hexadecimal not at ion, or base 16
However , when a comput er st or es an int eger , it uses none of t hese not at ions; inst ead, it
uses base 2, or binary notation.
In binar y not at ion, ever y number is r epr esent ed as a ser ies of 0s and 1s. For inst ance, t he
number 124 is r epr esent ed as
01111100
To under st and how t o get f r om base-10 not at ion t o binar y not at ion, r ecal l what t he
number 124 r epr esent s. When we wr it e "124," what we r eal l y mean is t he f ol l owing:
G 4 mul t ipl ied by 1, pl us
G 2 mul t ipl ied by 10, pl us
G 1 mul t ipl ied by 100
In gr ade school , your t eacher pr obabl y said t hese digit s r epr esent ed t he "ones pl ace," t he
"t ens pl ace," and t he "hundr eds pl ace." Each "pl ace" is t en t imes l ar ger t han t he pl ace t o
it s r ight . This means t hat you al so can t hink of 124 as f ol l ows:
G 4 mul t ipl ied by 1 (or 10 t o t he exponent 0), pl us
G 2 mul t ipl ied by 10 t o t he exponent 1, pl us
G 1 mul t ipl ied by 10 t o t he exponent 2
In binar y not at ion, you can use t his same met hod, but r epl ace t he 10s wit h 2s. Her e's how
t o use t his met hod t o f igur e out t hat t he binar y number 01111100 is equival ent t o 124 in
st andar d not at ion. St ar t ing f r om t he r ight , you have:
G 0 mul t ipl ied by 2 t o t he exponent 0, which is 0
G 0 mul t ipl ied by 2 t o t he exponent 1, which is 0
G 1 mul t ipl ied by 2 t o t he exponent 2, which is 4
G 1 mul t ipl ied by 2 t o t he exponent 3, which is 8
G 1 mul t ipl ied by 2 t o t he exponent 4, which is 16
G 1 mul t ipl ied by 2 t o t he exponent 5, which is 32
G 1 mul t ipl ied by 2 t o t he exponent 6, which is 64
G 0 mul t ipl ied by 2 t o t he exponent 7, which is 0
Adding 2, 8, 16, 32, and 64 gives you 124.
Each of t he 0s and 1s in t he binar y number 01111100 is cal l ed a bit (which is shor t f or
binar y digit). Each bit can have onl y t wo possibl e val ues: 0 or 1.
In comput er s, int eger s ar e st or ed as a sequence of bit s. This sequence of bit s is nor mal l y 8,
16, or 32 bit s l ong, depending on t he size and conf igur at ion of your comput er . In t he
exampl es in t oday's l esson, 8-bit int eger s ar e assumed; t o conver t an 8-bit binar y number
t o a 16-bit binar y number , just add eight zer os t o t he l ef t . For exampl e, t he f ol l owing
number s ar e equival ent :
01111100 # 124 as an 8-bit integer
0000000001111100 # 124 as a 16-bit integer
The exampl es in t oday's l esson use 8-bit int eger s. The Per l bit wise oper at or s wil l wor k on
int eger s of any size.
The Bit-Manipulation Operators
The f ol l owing bit -manipul at ion oper at or s ar e suppor t ed in Per l :
G The & (bit wise AND) oper at or
G The | (bit wise OR) oper at or
G The ^ (bit wise XOR or "excl usive or ") oper at or
G The ~ (bit wise NOT) oper at or
G The << (l ef t shif t ) and >> (r ight shif t ) oper at or s
The Bitwise AND Operator
In Per l , t he & oper at or r epr esent s t he bit wise AND oper at ion. This oper at ion wor ks as
f ol l ows:
G The val ue t o t he l ef t side of t he & (al so cal l ed t he left operand of t he & oper at ion)
is conver t ed t o an int eger , if necessar y.
G The val ue t o t he r ight side of t he & (t he right operand) al so is conver t ed t o an
int eger .
G Each bit of t he l ef t oper and is compar ed t o t he cor r esponding bit of t he r ight
oper and.
G If a pair of cor r esponding bit s bot h have t he val ue 1, t he cor r esponding bit of t he
r esul t is set t o 1. Ot her wise, t he cor r esponding bit of t he r esul t is set t o 0.
This might sound compl icat ed, but when you t ake a l ook at an exampl e, you'l l see t hat
it 's pr et t y easy t o f igur e out . For inst ance, consider t he f ol l owing:
$result = 124.3 & 99;
Fir st , t he l ef t oper and, 124.3, is conver t ed t o an int eger , becoming 124. (The r ight
oper and, 99, does not need t o be conver t ed.) Next , t ake a l ook at t he binar y
r epr esent at ions of 124 and 99:
01111100 # this is 124 in binary
01100011 # this is 99 in binary
When you examine each pair of bit s in t ur n, you can see t hat onl y t he second and t hir d
pair s (f r om t he l ef t ) ar e bot h 1. Thus, t he & oper at ion yiel ds t he f ol l owing binar y r esul t :
01100000
This is 96 in st andar d not at ion. As a consequence, t he st at ement
$result = 124.3 & 99;
assigns 96 t o $result.
DO use t he & oper at or wit h st r ings, pr ovided t he st r ings
can be conver t ed t o number s, as f ol l ows:
$result = "124.3" & "99";
Remember : St r ings and int eger s ar e int er changeabl e in
Per l .
DON' T conf use t he & oper at or wit h t he && oper at or . The
&& oper at or per f or ms a l ogical AND oper at ion, not a
bit wise AND oper at ion. For exampl e, t he st at ement
$result = 124.3 && 99;
assigns a nonzer o val ue t o $result (because 124.3 and 99
ar e bot h nonzer o). This nonzer o val ue is not l ikel y t o be
t he r esul t you want .
DON' T use t he & oper at or wit h negat ive int eger s, because
Per l wil l conver t t hem t o unsigned int eger s, and you
won't get t he r esul t you want .
The Bitwise OR Operator
The bit wise OR oper at or , |, al so compar es t wo int eger s one bit at a t ime. However , in t he
bit wise OR oper at ion, a r esul t bit is 1 if eit her of t he cor r esponding bit s in t he oper ands is
1.
To see how t his wor ks, l ook at anot her exampl e:
$result = 124.3 | 99;
Her e's how t his oper at ion is per f or med:
G As bef or e, t he t wo oper ands ar e conver t ed t o int eger s if necessar y. The oper ands
become 124 and 99; in binar y r epr esent at ion, t hese ar e, as bef or e,
01111100
01100011
G Each bit of t he l ef t oper and is compar ed wit h t he cor r esponding bit in t he r ight
oper and. If eit her of t he cor r esponding bit s is 1, t he cor r esponding r esul t bit is 1.
In t his exampl e, ever y bit becomes 1 except t he f ir st one, because at l east one of each of
t he ot her pair s is a 1. Ther ef or e, t he r esul t is
01111111
which t r ansl at es t o 127. This means t hat t he f ol l owing st at ement assigns 127 t o $result:
$result = 124.3 | 99;
DO make sur e you ar e using t he pr oper bit wise oper at or .
It 's easy t o sl ip and assume you want bit wise OR when you
r eal l y want bit wise AND. (Tr ust me.)
DON' T conf use t he | oper at or (bit wise OR) wit h t he ||
oper at or (l ogical OR).
The Bitwise XOR Operator
The bit wise XOR ("excl usive or ") oper at or , ^, is simil ar t o t he bit wise OR oper at or , but it 's
a l it t l e mor e demanding. In t he bit wise OR oper at ion, a r esul t bit is 1 if eit her of t he
cor r esponding bit s in t he oper ands is 1. In t he bit wise XOR oper at ion, a r esul t bit is 1 if
exactly one of t he cor r esponding bit s in t he oper ands is 1.
Her e is an exampl e of t he bit wise XOR oper at ion:
$result = 124.3 ^ 99;
This wor ks as f ol l ows:
G As bef or e, 124.3 is conver t ed t o 124, and t he binar y r epr esent at ions of t he t wo
oper ands ar e as f ol l ows:
01111100 # this is 124
01100011 # this is 99
G Each bit of t he l ef t oper and is compar ed wit h t he cor r esponding bit of t he r ight
oper and. The cor r esponding r esul t bit is set t o 1 if exact l y one of t he bit s in t he
oper ands is 1.
In t his case, t he r esul t is
00011111
which is 31. To wor k t hr ough how you get t his r esul t , consider t he f ol l owing:
G The f ir st bit of t he l ef t oper and and t he f ir st bit of t he r ight oper and ar e bot h 0.
This means t he f ir st bit of t he r esul t is 0.
G The second bit of t he l ef t oper and and t he second bit of t he r ight oper and bot h ar e
1. Ther ef or e, t he second bit of t he r esul t is 0, not 1.
G The same appl ies f or t he t hir d bit s: Bot h ar e 1, so t he r esul t bit is 0.
G The f our t h bit of t he l ef t oper and is 1, and t he f our t h bit of t he r ight oper and is 0.
Her e, exact l y one of t he bit s is 1, so t he r esul t bit becomes 1.
G Same f or t he f if t h and sixt h pair s: The f ir st bit is 1 and t he second is 0, so t he r esul t
is 1.
G The sevent h bit of t he l ef t oper and is 0, and t he sevent h bit of t he r ight oper and is
1. Again, exact l y one of t he bit s is 1, and t he r esul t bit is al so 1.
G Same f or t he eight h pair : The f ir st bit is 0, t he second is 1, so t he r esul t is 1.
Fr om t his, you can det er mine t hat t he f ol l owing st at ement assigns 31 t o $result:
$result = 124.3 ^ 99;
The Bitwise NOT Operator
Unl ike t he ot her bit wise oper at or s you've seen so f ar , t he bit wise NOT oper at or , ~, is a
unary oper at or , meaning it wor ks on onl y one oper and.
The way it wor ks is st r aight f or war d, as f ol l ows:
G The oper and is conver t ed t o an int eger , if necessar y.
G Each bit of t he oper and is examined. If a bit is 0, t he cor r esponding r esul t bit is set
t o 1, and vice ver sa.
For exampl e, consider t he f ol l owing:
$result = ~99;
The binar y r epr esent at ion of 99 is
01100011
Appl ying t he bit wise NOT oper at ion t o t his number pr oduces
10011100
This number , in st andar d not at ion, is 156. Ther ef or e, t he f ol l owing st at ement assigns 156
t o $result:
$result = ~99;
Not e t hat t he number of bit s used t o st or e an int eger af f ect s t he r esul t s pr oduced by t he
~ oper at or . For exampl e, if int eger s ar e st or ed in 16 bit s on your comput er , t he number 99
is r epr esent ed as
0000000001100011
This means t hat appl ying ~ t o t his number yiel ds
1111111110011100
which is 65436 in st andar d not at ion. As a consequence, t he st at ement
$result = ~99;
assigns 65436, not 156, t o $result. (On a comput er wit h 32-bit int eger s, t he val ue assigned
is 4294967196.)
The Shift Operators
Per l enabl es you t o shif t t he bit s of an int eger using t he << (shif t l ef t ) and >> (shif t
r ight ) oper at or s. For exampl e, in t he st at ement
$result = $x >> 1;
ever y bit of t he val ue st or ed in $x is shif t ed one pl ace t o t he r ight , and t he r esul t is
assigned t o $result ($x it sel f is not changed).
To see how t his wor ks, consider t he f ol l owing exampl e:
$result = 99 >> 1;
As you saw ear l ier , t he binar y r epr esent at ion of 99 is
01100011
Shif t ing ever y bit r ight one pl ace yiel ds
00110001
Not e t hat a 0 is added at t he f ar l ef t , and t he bit at t he f ar r ight disappear s.
Because 00110001 in binar y not at ion is t he same as 49 in st andar d not at ion, t he
f ol l owing st at ement assigns 49 t o $result:
$result = 99 >> 1;
The <<, or shif t -l ef t , oper at or wor ks in t he same way:
$result = 99 << 1;
The shif t -l ef t oper at or wor ks as f ol l ows:
01100011 # the binary representation of 99
11000110 # after shifting left 1 bit
The r esul t of t he shif t is 198, which is assigned t o $result.
DO r emember t hat when you use t he >> oper at or , t he bit s
on t he r ight ar e l ost . For exampl e:
$result1 = 17 >> 1;
$result2 = 16 >> 1;
In t his case, $result1 and $result2 ar e t he same val ue, 8.
This is because t he r ight most bit is shif t ed out in bot h
cases.
DON' T shif t l ef t t oo f ar , or you might not get t he r esul t
you want . For exampl e, if you ar e using 16-bit int eger s,
t he st at ement
$result = 35000 << 1;
does not assign 70000 t o $result as you might t hink it
woul d because t he l ar gest val ue t hat can be st or ed in a
16-bit int eger is 65536.
Shifting and Powers of 2
In t he f ol l owing st at ement , t he var iabl e $result is assigned t he val ue 49:
$result = 99 / 2;
Take a l ook at t he binar y r epr esent at ions of 99 and 49:
01100011 # 99 in binary form
00110001 # 49 in binary form
As you can see, dividing by 2 is ident ical t o shif t ing r ight one bit -in each case, ever y bit is
moved one pl ace t o t he r ight . Simil ar l y, shif t ing r ight t wo bit s is equival ent t o dividing
by 4:
$result = 99 / 4; # $result is assigned 24
01100011 # 99 in binary
00011000 # 24 in binary
Mul t ipl ying by 4 is simil ar t o shif t ing l ef t t wo bit s:
$result = 17 * 4; # $result is assigned 68
00010001 # 17 in binary
01000100 # 68 in binary
The gener al r ul es ar e as f ol l ows:
G Shif t ing l ef t n bit s, wher e n is some number gr eat er t han 0, is equival ent t o
mul t ipl ying by 2**n.
G Shif t ing r ight n bit s, wher e n is some number gr eat er t han 0, is equival ent t o
dividing by 2**n.
In t he ear l y days of pr ogr amming, many pr ogr ammer s used shif t oper at or s in pl ace of
mul t ipl icat ion and division wher ever possibl e, because t he shif t oper at ions wer e usual l y
mor e ef f icient . (In f act , some compil er s woul d opt imize t heir code by conver t ing
mul t ipl icat ion and division t o shif t s.) Today, it 's usual l y best t o use t he shif t oper at or s
when you ar e manipul at ing bit s, and t o use t he mul t ipl icat ion and division oper at or s
when you'r e act ual l y doing ar it hmet ic. This wil l make your pr ogr ams easier t o
under st and.
Using the Assignment Operators
As you saw on Day 2, t he assignment oper at or = associat es, or assigns, a val ue t o a
var iabl e. For exampl e, t he st at ement
$result = 42;
assigns t he val ue 42 t o t he var iabl e $result.
The = oper at or can appear mor e t han once in a singl e st at ement . For exampl e, in t he
st at ement
$value1 = $value2 = "a string";
t he char act er st r ing a string is assigned t o bot h $value1 and $value2.
Per l al so suppor t s ot her assignment oper at or s, each of which combines an assignment
wit h anot her oper at ion. For exampl e, suppose t hat you want t o add a val ue t o a scal ar
var iabl e and assign t he r esul t t o t he f ol l owing var iabl e:
$var = $var + 1;
Anot her way t o wr it e t his is wit h t he += assignment oper at or :
$var += 1;
This st at ement adds t he val ue 1 t o t he exist ing val ue of $var.
An assignment oper at or exist s f or just about ever y bit wise oper at or and ar it hmet ic
oper at or t hat Per l suppor t s. Tabl e 4.3 l ist s t he assignment oper at or s suppor t ed in Per l .
Tabl e 4.3. The assignment oper at or s.
Oper at or Oper at ions per f or med
= Assignment onl y
+= Addit ion and assignment
-= Subt r act ion and assignment
*= Mul t ipl icat ion and
assignment
/= Division and assignment
%= Remainder and assignment
**= Exponent iat ion and
assignment
&= Bit wise AND and assignment
|= Bit wise OR and assignment
^= Bit wise XOR and assignment
Tabl e 4.4 shows exampl es of t he assignment oper at or s, al ong wit h equival ent st at ement s
t hat use oper at or s you've seen ear l ier .
Tabl e 4.4. Exampl es of assignment oper at or s.
St at ement
using
Equival ent Per l
assignment oper at or
st at ement
$a = 1; none (basic assignment )
$a -= 1; $a = $a - 1;
$a *= 2; $a = $a * 2;
$a /= 2; $a = $a / 2;
$a %= 2; $a = $a % 2;
$a **= 2; $a = $a ** 2;
$a &= 2; $a = $a & 2;
$a |= 2; $a = $a | 2;
$a ^= 2; $a = $a ^ 2;
Assignment Operators as Subexpressions
Any expr ession t hat cont ains an assignment oper at or can appear on t he l ef t side of
anot her assignment oper at or . The f ol l owing is an exampl e:
($a = $b) += 3;
In cases such as t his, t he assignment encl osed in par ent heses is per f or med f ir st . This
assignment is t hen t r eat ed as a separ at e subexpr ession whose val ue is t he var iabl e t o
which it is being assigned. For exampl e, $a = $b has t he val ue $a.
This means t hat t he st at ement shown pr eviousl y is equival ent t o t he f ol l owing t wo
st at ement s:
$a = $b;
$a += 3;
TIP
Don't use assignment s in t his way unl ess you absol ut el y
have t o. At f ir st gl ance, t he st at ement
($a = $b) += 3;
appear s t o add 3 t o $b as wel l as t o $a.
Using Autoincrement and Autodecrement
So f ar , you've seen t wo ways t o add 1 t o a scal ar var iabl e:
$a = $a + 1;
$a += 1;
The f ir st met hod uses t he st andar d assignment oper at or = and t he addit ion oper at or +,
and t he second met hod uses t he addit ion assignment oper at or +=.
Per l al so suppor t s a t hir d met hod of adding 1 t o a scal ar var iabl e: t he autoincrement
operator, or ++. Her e ar e some exampl es of t he ++ oper at or in act ion:
$a++;
++$a;
$result = $a++;
$result2 = ++$a;
In each case, t he ++ oper at or t el l s Per l t o add 1 t o t he val ue st or ed in $a.
In some of t he exampl es, t he ++ is in f r ont of t he var iabl e it is af f ect ing, wher eas in
ot her s t he ++ f ol l ows t he var iabl e. If t he ++ is f ir st , t he oper at ion is a pre-increment
oper at ion; if t he ++ f ol l ows, t he oper at ion is a post-increment oper at ion.
The Autoincrement Operator Pre-Increment
To under st and how t he pr e-incr ement oper at ion wor ks, f ir st r ecal l t hat you can use a
singl e st at ement t o assign a val ue t o mor e t han one var iabl e, as f ol l ows:
$var1 = 43;
$var2 = $var1 += 1;
Her e, t he or iginal val ue st or ed in $var1, 43, has 1 added t o it . The r esul t , 44, becomes t he
new val ue of $var1. This new val ue of 44 is t hen assigned t o $var2.
The pr e-incr ement oper at ion wor ks in t he same way:
$var1 = 43;
$var2 = ++$var1;
The f ol l owing code f r agment t el l s Per l t o add 1 t o $var1 bef or e doing anyt hing el se:
++$var1
As a r esul t , $var1 becomes 44 bef or e t he val ue of $var1 is assigned t o $var2. Ther ef or e,
$var2 is assigned 44.
The ++ oper at or is most f r equent l y used in while st at ement s. List ing 4.3 pr ovides an
exampl e of a simpl e pr ogr am t hat uses t he ++ oper at or in a while st at ement .

List ing 4.3. A pr ogr am t hat uses t he pr e-incr ement oper at ion.
1: #!/usr/local/bin/perl
2: $value = 0;
3: while (++$value <= 5) {
4: print("value is now $value\n");
5: }
6: print("all done\n");

$ program4_3
value is now 1
value is now 2
value is now 3
value is now 4
value is now 5
all done
$
Not e t hat t he pr e-incr ement oper at ion enabl es you t o add 1 t o $value and t est
it al l at t he same t ime. This means t hat you no l onger have t o r emember t o add t he
f ol l owing:
$value = $value + 1;
at t he bot t om of t he while st at ement , which means t hat you ar e l ess l ikel y t o wr it e a
while st at ement t hat goes on f or ever .
Now see what happens when you change
while (++$value <= 5) {
t o t his:
while (++$value <= 0) {
and t hen r un t he pr ogr am again. This t ime, you get t he f ol l owing:
all done
Because t he ++ oper at or is in f r ont of $value, 1 is added t o $value bef or e t est ing. This
means t hat $value is not l ess t han or equal t o 0 when t he while st at ement is execut ed
f or t he f ir st t ime; as a r esul t , t he code inside t he while st at ement is never execut ed.
The Autoincrement Operator Post-Increment
The post -incr ement oper at or al so adds 1 t o t he var iabl e wit h which it is associat ed.
However , it s behavior is sl ight l y dif f er ent :
$var1 = 43;
$var2 = $var1++;
When t he ++ oper at or appear s af t er t he var iabl e, t he ++ oper at or is per f or med after ever y-
t hing el se is f inished. This means t hat t he or iginal val ue of $var1, 43, is assigned t o $var2.
Af t er t his assignment is compl et ed, 1 is added t o $var1 and t he new val ue of $var1
becomes 44.
To see how t his wor ks in while st at ement s, examine List ing 4.4. Al t hough it is simil ar t o
List ing 4.3, it per f or ms a post -incr ement oper at ion inst ead of a pr e-incr ement oper at ion.

List ing 4.4. A pr ogr am t hat uses t he post -incr ement oper at ion.
1: #!/usr/local/bin/perl
2: $value = 0;
3: while ($value++ <= 5) {
4: print("value is now $value\n");
5: }
6: print("all done\n");

$ program4_4
value is now 1
value is now 2
value is now 3
value is now 4
value is now 5
value is now 6
all done
$
You ar e pr obabl y wonder ing why t he out put of List ing 4.4 cont ained t he
f ol l owing l ine:
value is now 6
To f igur e out what happened, examine t he val ue st or ed in $value each t ime t he condit ion
in t he while st at ement is t est ed. Tabl e 4.5 l ist s t he cont ent s of $value when t he
condit ion is t est ed, t he r esul t of t he t est , and $value immediat el y af t er t he condit ion is
t est ed (af t er t he ++ oper at or is appl ied).
Tabl e 4.5. Condit ion eval uat ion.
$value at t ime of
t est
Resul t $value af t er
t est
0 t r ue (0 <= 5) 1
1 t r ue (1 <= 5) 2
2 t r ue (2 <= 5) 3
3 t r ue (3 <= 5) 4
4 t r ue (4 <= 5) 5
5 t r ue (5 <= 5) 6
6 f al se (6 <=
5)
7 (exit while)
As you know, when t he condit ion at t he t op of a while st at ement is t r ue, t he code inside
t he st at ement is execut ed, which in t his case is
print("value is now $value\n");
This is why t he l ine
value is now 6
appear s-$value is 5 at t he t ime t he condit ion is t est ed, so t he r esul t is t r ue.
To f ix t his pr obl em, change t he while condit ion t o t he f ol l owing and r un t he pr ogr am
again:
while ($value < 5) {
This is t he out put you get f r om t he changed pr ogr am:
value is now 1
value is now 2
value is now 3
value is now 4
value is now 5
all done
Now, when $value is 5, t he st at ement
while ($value++ < 5)
is f al se, and t he code inside t he while is not execut ed.
The Autodecrement Operator
As you've seen, t he ++ oper at or adds 1 t o t he val ue of t he var iabl e it is associat ed wit h
and can appear eit her bef or e or af t er t he var iabl e. The -- oper at or , or autodecrement
operator, wor ks in t he same way, but it subt r act s 1 f r om t he val ue of t he var iabl e it is
associat ed wit h, as f ol l ows:
$a--;
--$a;
$result = $a--;
$result2 = --$a;
When t he -- oper at or is in f r ont of t he var iabl e, t he oper at ion is a pre-decrement
oper at ion, which means t hat 1 is subt r act ed f r om t he var iabl e bef or e anyt hing el se
happens.
$var1 = 56;
$var2 = --$var1;
This subt r act s 1 f r om $var1 and assigns t he r esul t , 55, back t o $var1. The val ue 55 is t hen
assigned t o $var2.
When t he -- oper at or f ol l ows t he var iabl e, t he oper at ion is a post-decrement oper at ion,
which means t hat 1 is subt r act ed f r om t he var iabl e af t er ever yt hing el se happens.
$var1 = 56;
$var2 = $var1--;
This assigns 56 t o $var2 and t hen subt r act s 1 f r om $var1, which means t hat $var1 now has
t he val ue 55.
DO be car ef ul when you use t he aut oincr ement and
aut odecr ement oper at or s. As you've seen, it 's easy t o get
conf used and t el l your pr ogr am t o l oop one t oo many
t imes or one t oo f ew.
I t end not t o use t hese oper at or s in while st at ement s
except in ver y simpl e cases, because t hey can get
conf using. A bet t er sol ut ion is t o use t he for st at ement ,
which you'l l l ear n about on Day 8, "Mor e Cont r ol
St r uct ur es."
DON' T use ++ or -- on bot h sides of a singl e var iabl e, as
in t his st at ement , because it isn't al l owed in Per l :
++$var1--;
DON' T use aut oincr ement or aut odecr ement on a
var iabl e and t hen use t he var iabl e again in t he same
st at ement .
$var1 = 10;
$var2 = $var1 + ++$var1;
Is $var2 now 20, 21, or 22? It 's impossibl e t o t el l . Even
dif f er ent ver sions of Per l can pr oduce dif f er ent r esul t s!
Using Autoincrement With Strings
If a st r ing val ue cont ains onl y al phabet ic char act er s, t he ++ oper at or can be used t o
"add one" t o a st r ing. In ot her wor ds, t he oper at or r epl aces t he l ast char act er of t he
st r ing wit h t he next l et t er of t he al phabet . The f ol l owing is an exampl e:
$stringvar = "abc";
$stringvar++;
Her e, $stringvar now cont ains abd.
Not e t hat t his wor ks onl y wit h ++, not --:
$stringvar = "abc";
$stringvar--;
The -- oper at or t r eat s abc as a number , which means t hat it is equival ent t o 0. The
r esul t ing val ue of $stringvar is, t her ef or e, -1.
Aut o-incr ement ing st r ings using ++ al so wor ks on capit al l et t er s.
$stringvar = "aBC";
$stringvar++;
The val ue st or ed in $stringvar is now aBD.
If t he l ast l et t er of t he st r ing is z or Z, ++ conver t s t his l et t er t o a or A, and t hen "adds
one" t o t he second-t o-l ast char act er of t he st r ing:
$stringvar = "abz";
$stringvar++; # $stringvar now contains "aca"
$stringvar = "AGZZZ";
$stringvar++; # $stringvar now contains "AHAAA"
This al so wor ks if t he st r ing cont ains one or mor e t r ail ing digit s.
$stringvar = "ab4";
$stringvar++; # $stringvar now contains "ab5"
As in numer ic oper at ions, incr ement ing a st r ing t hat ends in 9 car r ies over t o t he next
char act er of t he st r ing. This wor ks r egar dl ess of whet her t he next char act er is a digit
or al phabet ic char act er .
$stringvar = "bc999";
$stringvar++; # $stringvar now contains "bd000"
Incr ement ing st r ing val ues using ++ wor ks onl y if t he
var iabl e has not al r eady been conver t ed t o a number .
$stringvar = "abc";
$stringvar += 5;
$stringvar++;
Her e, t he val ue of $stringvar is 6 because abc is
conver t ed t o 0 by t he += oper at or in t he second
st at ement .
Al so not e t hat t his does not wor k if t he st r ing val ue
cont ains any char act er ot her t han a l et t er or digit , or if
a digit is l ocat ed in t he middl e of t he st r ing.
$stringvar = "ab*c";
$stringvar++;
$stringvar = "ab5c";
$stringvar++;
In bot h of t hese cases, t he val ue st or ed in $stringvar is
conver t ed t o it s numer ic equival ent , 0, bef or e t he ++
oper at ion is per f or med. This means t hat $stringvar is
assigned t he val ue 1.
The String Concatenation and Repetition Operators
So f ar , t he Per l oper at or s you've seen oper at e onl y on int eger s. (To be exact , t hey can
al so oper at e on st r ings, but t hey conver t t he st r ings t o int eger s f ir st .) Per l al so suppor t s
t he f ol l owing special oper at or s t hat manipul at e st r ings:
G The . oper at or , which concatenates (joins t oget her ) t wo st r ings
G The x oper at or , which r epeat s a st r ing
G The .= oper at or , which combines concat enat ion and assignment
The String-Concatenation Operator
The st r ing-concat enat ion oper at or , ., joins t wo st r ings t oget her . For exampl e, t he
f ol l owing st at ement assigns t he st r ing potatohead t o $newstring:
$newstring = "potato" . "head";
You can use t he . oper at or wit h var iabl es as in t his exampl e:
$string1 = "potato";
$string2 = "head";
$newstring = $string1 . $string2;
This al so assigns potatohead t o $newstring. Not e t hat t he val ues of $string1 and
$string2 ar e not changed by t he . oper at or : $string1 st il l has t he val ue potato, and
$string2 st il l has t he val ue head.
The String-Repetition Operator
The st r ing-r epet it ion oper at or , x (l it er al l y t he l et t er x), makes mul t ipl e copies of a
st r ing and joins t he copies t oget her , as shown in t his exampl e:
$newstring = "t" x 5;
This st at ement t akes f ive copies of t he st r ing t and joins t hem t oget her , pr oducing t he
st r ing ttttt. This st r ing is t hen assigned t o t he var iabl e $newstring.
You can use var iabl es as oper ands f or t he x oper at or , if you l ike, as f ol l ows:
$copystring = "t";
$repeats = 5;
$newstring = $copystring x $repeats;
The onl y r est r ict ion is t hat t he var iabl e on t he r ight of t he x must cont ain an int eger or
a val ue t hat can be conver t ed t o an int eger .
DO make sur e you l eave a space bet ween t he x oper at or
and t he val ues or var iabl es on eit her side:
$newstring = $oldstring x 5; # this is correct
$newstring = $oldstringx 5; # incorrect
$newstring = $oldstring x5; # also incorrect
Nor mal l y, you don't need t o put spaces bet ween an
oper at or and it s oper ands.
$x = $x + 1; # this is OK
$x=$x+1; # this is also OK
You need spaces ar ound t he x because t he l et t er x can
appear in var iabl e names. (For exampl e, $oldstringx is a
per f ect l y val id var iabl e name.)
Concatenation and Assignment
The .= oper at or combines t he oper at ions of st r ing concat enat ion and assignment . For
exampl e, t he f ol l owing st at ement s:
$a = "be";
$a .= "witched"; # $a is now "bewitched"
ar e equival ent t o t hese st at ement s:
$a = "be";
$a = $a . "witched";
You can use t he .= oper at or t o wr it e a ver y simpl e pr ogr am t hat r eads mul t ipl e l ines of
input and joins t hem int o a singl e st r ing. This pr ogr am is shown in List ing 4.5.

List ing 4.5. A pr ogr am t hat r eads input l ines and concat enat es t hem.
1: #!/usr/local/bin/perl
2: $resultstring = "";
3: print("Enter your input - type an empty line to quit\n");
4: $input = <STDIN>;
5: chop ($input);
6: while ($input ne "") {
7: $resultstring .= $input;
8: $input = <STDIN>;
9: chop ($input);
10: }
11: print ("Here is the final string:\n");
12: print ("$resultstring\n");

$ program4_5
Enter your input - type an empty line to quit
this
is
a
test
Here is the final string:
thisisatest
$
As you can see f r om t he out put of List ing 4.5, t he f our input l ines ar e joined
and have become a singl e st r ing.
Not e t hat t her e is a much simpl er way t o do t his in Per l : using t he buil t -in f unct ion
join(). You'l l l ear n about join() on Day 5, "List s and Ar r ay Var iabl es."
Other Perl Operators
Per l al so suppor t s t wo ot her oper at or s t hat do not f it int o any of t he pr eceding
cat egor ies:
G The comma oper at or
G The condit ional oper at or
The Comma Operator
The comma operator (,) is an oper at or bor r owed f r om t he C pr ogr amming l anguage. It
guar ant ees t hat a par t icul ar par t of an expr ession (t he par t bef or e t he ,) is eval uat ed
f ir st .
Her e is an exampl e of a simpl e st at ement t hat uses t he , oper at or :
$var1 += 1, $var2 = $var1;
Because t he , oper at or indicat es t hat t he l ef t oper and is t o be per f or med f ir st , 1 is added
t o $var1 bef or e $var1 is assigned t o $var2. In ef f ect , t he , oper at or br eaks a st at ement
int o t wo separ at e st at ement s, as f ol l ows:
$var1 += 1;
$var2 = $var1;
In f act , t he onl y r eal r eason t o use t he , oper at or is when t wo oper at ions ar e so cl osel y
t ied t oget her t hat it is easier t o under st and t he pr ogr am if t hey appear as par t of t he
same expr ession.
The comma oper at or is of t en used in conjunct ion wit h t he = oper at or , as f ol l ows:
$val = 26;
$result = (++$val, $val + 5);
In t his st at ement , t he
++$val
oper at ion is per f or med f ir st , because it appear s bef or e t he , oper at or . This adds 1 t o $val,
which means t hat $val now has t he val ue 27. Then t his new val ue of $val has 5 added t o
it , and t he r esul t , 32, is assigned t o $result.
Not e t hat t he f ol l owing expr ession is encl osed in par ent heses:
++$val, $val + 5
This indicat es t hat t his set of oper at ions is t o be per f or med f ir st . Had t he par ent heses not
been pr esent , t he st at ement woul d have been
$result = ++$val, $val + 5;
In t his case, ever yt hing bef or e t he comma woul d be per f or med f ir st :
$result = ++$val
This means t hat $result woul d be assigned 27, not 32.
You'l l l ear n mor e about par ent heses and t he or der of oper at ions l at er t oday, in t he
sect ion t it l ed "The Or der of Oper at ions."
The Conditional Operator
The condit ional oper at or al so is bor r owed f r om t he C pr ogr amming l anguage. Unl ike t he
ot her oper at or s you've seen, t he condit ional oper at or r equir es t hr ee oper ands, as
f ol l ows:
G A condit ion t o t est
G A val ue t hat is t o be used when t he t est condit ion is t r ue (eval uat es t o a nonzer o
val ue)
G A val ue t hat is t o be used when t he t est condit ion is f al se (eval uat es t o zer o)
The f ir st t wo oper ands ar e separ at ed by t he char act er ?, and t he second and t hir d
oper ands ar e separ at ed by t he char act er :.
Her e is a simpl e exampl e of an expr ession t hat uses t he condit ional oper at or :
$result = $var == 0 ? 14 : 7;
Her e, t he t est condit ion is t he expr ession
$var == 0
If t his expr ession is t r ue, t he val ue 14 is assigned t o $result. If it is f al se, t he val ue 7 is
assigned t o $result.
As you can see, t he condit ional oper at or behaves just l ike t he if and else st at ement s.
The expr ession
$result = $var == 0 ? 14 : 7;
is ident ical t o t he f ol l owing:
if ($var == 0) {
$result = 14;
} else {
$result = 7;
}
The dif f er ence bet ween t he condit ional oper at or and t he if-else const r uct is t hat t he
condit ional oper at or can appear in t he middl e of expr essions. For exampl e, t he
condit ional oper at or can be used as anot her way t o pr event division by 0, as f ol l ows:
$result = 43 + ($divisor == 0 ? 0 : $dividend / $divisor);
Her e, $result is assigned t he val ue 43 pl us t he r esul t of $dividend divided by $divisor,
unl ess $divisor is 0. If $divisor is 0, t he r esul t of t he division is assumed t o be 0, and
$result is assigned 43.
List ing 4.6 is a simpl e pr ogr am t hat r eads f r om t he st andar d input f il e and compar es t he
input l ine wit h a pr edet er mined passwor d.

List ing 4.6. A ver y simpl e passwor d checker .
1: #!/usr/local/bin/perl
2: print ("Enter the secret password:\n");
3: $password = "bluejays";
4: $inputline = <STDIN>;
5: chop ($inputline);
6: $outputline = $inputline eq $password ?
7: "Yes, that is the correct password!\n" :
8: "No, that is not the correct password.\n";
9: print ($outputline);

$ program4_6
Enter the secret password:
orioles
No, that is not the correct password.
$
When you r un program4_6 and t ype in a r andom passwor d, you get t he r esul t s
shown in t he Input -Out put exampl e.
The advant age of using t he condit ional oper at or her e is t hat t he assignment t o
$outputline occur s in onl y one pl ace, and t he st at ement is much mor e concise. If you use
if and else, you need t wo assignment s t o $outputline and f ive l ines, as f ol l ows:
if ($inputline eq $password) {
$outputline = "Yes, that is the correct password!\n";
} else {
$outputline = "No, that is not the correct password.\n");
}
Of cour se, t he if and else st at ement s ar e easier t o use when t hings get mor e compl ex.
Consider t he f ol l owing exampl e:
if ($var1 == 47) {
print("var1 is already 47\n");
$is_fortyseven = 1;
} else {
$var1 = 47;
print("var1 set to 47\n");
$is_fortyseven = 0;
}
You can wr it e t his using t he condit ional oper at or if you use t he comma oper at or , as
f ol l ows:
$var1 == 47 ? (print("var1 is already 47\n"), $is_fortyseven = 1) :
($var1 = 47, print("var1 set to 47\n"), $is_fortyseven = 0);
As you can see, t his is dif f icul t t o under st and. The basic r ul es ar e as f ol l ows:
G Use t he condit ional oper at or f or ver y simpl e condit ional st at ement s.
G Use if and else f or ever yt hing el se.
Conditional Operators on the Left Side of Assignments
In Per l 5, you can use t he condit ional oper at or on t he l ef t side of an assignment . This
enabl es you t o assign a val ue t o eit her of t wo var iabl es, depending on t he r esul t of a
condit ional expr ession.
$condvar == 43 ? $var1 : $var2 = 14;
This st at ement checks whet her $condvar has t he val ue 43. If it does, $var1 is assigned 14.
If it doesn't , $var2 is assigned 14.
Nor mal l y, you won't want t o use condit ional oper at or s in t his way because your code
wil l become dif f icul t t o f ol l ow. Al t hough t he f ol l owing code is a l it t l e l ess ef f icient ,
it per f or ms t he same t ask in a way t hat is easier t o under st and:
$condvar == 43 ? $var1 = 14 : $var2 = 14;
The Order of Operations
Per l , l ike al l pr ogr amming l anguages, has a cl ear l y def ined set of r ul es t hat det er mine
which oper at ions ar e t o be per f or med f ir st in a par t icul ar expr ession. The f ol l owing
t hr ee concept s hel p expl ain t hese r ul es:
G The concept of precedence
G The concept of associativity
G The abil it y t o over r ide pr ecedence and associat ivit y using parentheses
Precedence
In gr ade school , you l ear ned t hat cer t ain ar it hmet ic oper at ions al ways ar e per f or med
bef or e ot her ones. For exampl e, mul t ipl icat ion and division al ways ar e per f or med bef or e
addit ion and subt r act ion.
4 + 5 * 3
Her e, t he mul t ipl icat ion is per f or med f ir st , even t hough t he addit ion is encount er ed f ir st
when t he st at ement is r ead f r om l ef t t o r ight . Because mul t ipl icat ion al ways is
per f or med f ir st , it has higher precedence t han addit ion.
Tabl e 4.6 def ines t he pr ecedence of t he oper at or s in Per l . The it ems at t he t op of t he
t abl e have t he highest pr ecedence, and t he it ems at t he bot t om have t he l owest .
Tabl e 4.6. Oper at or pr ecedence.
Oper at or Oper at ion Per f or med
++, -- Aut oincr ement and
aut odecr ement
-, ~, ! Oper at or s wit h one oper and
** Exponent iat ion
=~, !~ Pat t er n-mat ching oper at or s
*, /, %, x Mul t ipl icat ion, division,
r emainder , r epet it ion
+, -, . Addit ion, subt r act ion,
concat enat ion
<<, >> Shif t ing oper at or s
-e, -r, et c. Fil e-st at us oper at or s
<, <=, >, >=, lt, le, gt,
ge
Inequal it y-compar ison oper at or s
==, !=, <=>, eq, ne, cmp Equal it y-compar ison oper at or s
& Bit wise AND
|, ^ Bit wise OR and XOR
&& Logical AND
|| Logical OR
.. List -r ange oper at or
? and : Condit ional oper at or (t oget her )
=, +=, -=, *=, Assignment oper at or s
and so on
,
Comma oper at or
not Low-pr ecedence l ogical NOT
and Low-pr ecedence l ogical AND
or, xor Low-pr ecedence l ogical OR and
XOR
Using t his t abl e, you can det er mine t he or der of oper at ions in compl icat ed expr essions.
For exampl e:
$result = 11 * 2 + 6 ** 2 << 2;
To det er mine t he or der of oper at ions in t his expr ession, st ar t at t he t op of Tabl e 4.6 and
wor k down. The f ir st oper at or you see is **, which means t hat it is per f or med f ir st ,
l eaving
$result = 11 * 2 + 36 << 2;
The next oper at ion you f ind in t he t abl e is t he * oper at or . Per f or ming t he mul t ipl icat ion
l eaves t he f ol l owing:
$result = 22 + 36 << 2;
The + oper at or is next :
$result = 58 << 2;
Next up is t he << oper at or :
$result = 232;
The = oper at or is l ast on t he l ist and assigns 232 t o $result.
You might have not iced t hat Tabl e 4.6 cont ains some oper at or s t hat you've not yet seen
and which you'l l l ear n about l at er :
G The l ist -r ange oper at or , def ined on Day 5
G The f il e-st at us oper at or s, def ined on Day 6, "Reading f r om and Wr it ing t o Fil es"
G The pat t er n-mat ching oper at or s, =~ and !~, def ined on Day 7, "Pat t er n Mat ching"
Associativity
The r ul es of oper at or pr ecedence enabl e you t o det er mine which oper at ion t o per f or m
f ir st when an expr ession cont ains dif f er ent oper at or s. But what shoul d you do when an
expr ession cont ains t wo or mor e oper at or s t hat have t he same pr ecedence?
In some cases, it doesn't mat t er what or der you per f or m t he oper at ions in. For exampl e:
$result = 4 + 5 + 3;
Her e, $result get s 12 no mat t er which addit ion is per f or med f ir st . However , f or some
oper at ions t he or der of eval uat ion mat t er s.
$result = 2 ** 3 ** 2;
If you per f or m t he l ef t most exponent iat ion f ir st , $result is assigned 8 ** 2, or 64. If you
per f or m t he r ight most exponent iat ion f ir st , $r esul t is assigned 2 ** 9, or 512.
Because t he or der of oper at ions is somet imes impor t ant , Per l def ines t he or der in which
oper at ions of t he same pr ecedence ar e t o be per f or med. Oper at ions t hat ar e per f or med
r ight -t o-l ef t (wit h t he r ight most oper at ion per f or med f ir st ) ar e said t o be right associative.
Oper at ions t hat ar e per f or med l ef t -t o-r ight (wit h t he l ef t most oper at ion per f or med
f ir st ) ar e left associative.
Tabl e 4.7 l ist s t he associat ivit y f or each of t he Per l oper at or s. The oper at or s ar e sor t ed
accor ding t o pr ecedence (in t he same or der as Tabl e 4.6).
Tabl e 4.7. Oper at or associat ivit y.
Oper at or Associat ivit y
++, -- Not appl icabl e
-, ~, ! Right -t o-l ef t
** Right -t o-l ef t
=~, !~ Lef t -t o-r ight
*, /, %, x Lef t -t o-r ight
+, -, . Lef t -t o-r ight
<<, >> Lef t -t o-r ight
-e, -r, Not appl icabl e and so on
<, <=, >, >=, lt, le, gt, ge Lef t -t o-r ight
==, !=, <=>, eq, ne, cmp Lef t -t o-r ight
& Lef t -t o-r ight
|, ^ Lef t -t o-r ight
&& Lef t -t o-r ight
|| Lef t -t o-r ight
.. Lef t -t o-r ight
? and : Right -t o-l ef t
=, +=, -=, *=, Right -t o-l ef t
and so on
,
Lef t -t o-r ight
not Lef t -t o-r ight
and Lef t -t o-r ight
or, xor Lef t -t o-r ight
Fr om Tabl e 4.7, you see t hat t he exponent iat ion oper at or is r ight associat ive. This means
t hat in t he f ol l owing:
$result = 2 ** 3 ** 2;
$result is assigned 512, because t he r ight most ** oper at ion is per f or med f ir st .
Forcing Precedence Using Parentheses
Per l enabl es you t o f or ce t he or der of eval uat ion of oper at ions in expr essions. To do
t his, use par ent heses as f ol l ows:
$result = 4 * (5 + 3);
In t his st at ement , 5 is added t o 3 and t hen mul t ipl ied by 4, yiel ding 32.
You can use as many set s of par ent heses as you l ike:
$result = 4 ** (5 % (8 - 6));
Her e, t he r esul t is 4:
G 8 - 6 is per f or med, l eaving 4 ** (5 % 2)
G 5 % 2 is per f or med, l eaving 4 ** 1
G 4 ** 1 is 4
DO use par ent heses whenever you ar en't sur e whet her a
par t icul ar oper at ion is t o be eval uat ed f ir st . For
exampl e, I don't know many pr ogr ammer s who r emember
t hat addit ion oper at or s ar e eval uat ed bef or e shif t s:
$result = 4 << 2 + 3;
And vir t ual l y no one r emember s t hat && has higher
pr ecedence t han ||:
if ($value == 0 || $value == 2 && $value2 ==
"hello") {
print("my condition is true\n");
}
You can make l if e a l ot easier f or peopl e who r ead your
code if you use par ent heses when t he or der of eval uat ion
is not obvious. For exampl e:
$result = 4 << (2 + 3);
if ($value == 0 || ($value == 2 && $value2 ==
"hello")) {
print("my condition is true\n");
}
DO use mul t ipl e l ines, ext r a spaces, and indent at ion t o
make compl icat ed expr essions easier t o r ead. For exampl e:
if ($value == 0 ||
($value == 2 && $value2 == "hello")) {
Her e, it 's obvious t hat t her e ar e t wo main condit ions t o
be t est ed and t hat one of t hem cont ains a pair of
subcondit ions.
DON' T l eave out cl osing par ent heses by mist ake.
$result = 4 + (2 << ($value / 2); # error
This st at ement wil l be f l agged as er r oneous because you
ar e missing a cl osing par ent hesis.
A handy way of checking whet her you have enough
par ent heses in compl icat ed expr essions is t o use t his
simpl e t r ick:
G St ar t at t he l ef t end of your expr ession.
G St ar t ing f r om 0, add 1 f or ever y l ef t par ent hesis you see.
G Subt r act 1 f or ever y cl osing par ent hesis you see.
If your f inal r esul t is 0, you've got enough opening and
cl osing par ent heses. (This doesn't guar ant ee t hat you've
put t he par ent heses in t he r ight pl aces, but at l east you
now know t hat you have enough of t hem.)
Summary
Today you l ear ned about t he oper at or s t hat Per l suppor t s. Each oper at or r equir es one
or mor e oper ands, which ar e t he val ues on which t he oper at or oper at es. A col l ect ion of
oper ands and oper at or s is known as an expr ession.
The oper at or s you l ear ned how t o use ar e as f ol l ows:
G The ar it hmet ic oper at or s +, -, *, /, %, **, and unar y negat ion
G The int eger -compar ison oper at or s ==, !=, <, >, <=, >=, and <=>
G The st r ing-compar ison oper at or s eq, ne, lt, gt, le, ge, and cmp
G The l ogical oper at or s ||, &&, and !
G The bit -manipul at ion oper at or s |, &, ^, ~, <<, and >>
G The assignment oper at or s =, +=, -=, *=, /=, %=, **=, !=, &=, ^=, and .=
G The aut oincr ement oper at or ++
G The aut odecr ement oper at or --
G The st r ing-concat enat ion oper at or .
G The st r ing-r epet it ion oper at or x
G The comma oper at or ,
G The condit ional oper at or (? and : t oget her )
You al so l ear ned about oper at or pr ecedence and associat ivit y, t wo concept s t hat t el l
you which oper at or s in an expr ession usual l y ar e per f or med f ir st . Oper at or pr ecedence
and associat ivit y can be cont r ol l ed by put t ing par ent heses ar ound t he oper at ions you
want t o per f or m f ir st .
Q&A
Q: Is t her e a l imit on how l ar ge my expr essions can be?
A: Ef f ect ivel y, no. Ther e is a l imit , but it 's so l ar ge t hat no one woul d possibl y want
t o cr eat e an expr ession t hat l ong, because it woul d be impossibl e t o r ead or
under st and.***It 's easier t o under st and expr essions if t hey ar e shor t er .
Q: Is it bet t er t o use += or ++ when adding 1 t o a var iabl e?
A: It 's best t o use ++ when using a var iabl e as a count er in a while st at ement (or in
ot her l oops, which you l ear n about on Day 8, "Mor e Cont r ol St r uct ur es"). For
ot her addit ion oper at ions, you shoul d use +=.
Q: Why ar e some oper at or s l ef t associat ive and ot her s r ight associat ive?
A: Most oper at or s ar e l ef t associat ive, because we nor mal l y r ead f r om l ef t t o r ight .
Assignment is r ight associat ive because it 's easier t o r ead. For inst ance:
$var1 = $var2 = 5;
If assignment happened t o be l ef t associat ive, $var1 woul d be assigned t he ol d
val ue of $var2, not 5. This woul d not be obvious t o a casual r eader of t he
pr ogr am.Exponent iat ion is r ight associat ive because t hat 's how exponent iat ion is
per f or med in mat hemat ics.Ot her oper at or s t hat ar e r ight associat ive ar e easier t o
r ead f r om r ight t o l ef t .
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. Def ine t he f ol l owing t er ms:
a. oper at or
b. oper and
c. expr ession
d. pr ecedence
e. associat ivit y
2. What oper at ions ar e per f or med by t he f ol l owing oper at or s?
a. &&
b. &
c. ^
d. ne
e. .
3. What oper at or s per f or m t he f ol l owing oper at ions?
a. st r ing-equal it y compar ison
b. r emainder
c. st r ing dupl icat ion
d. bit wise OR
e. numer ic gr eat er -t han-or -equal -t o
4. What is t he binar y r epr esent at ion of t he f ol l owing number s?
a. 171
b. 1105
c. 0
5. What is t he st andar d (base-10) r epr esent at ion of t he f ol l owing number s?
a. 01100100
b. 00001111
c. 01000001
6. What is t he val ue of t he f ol l owing expr essions?
a. 17 * 2 ** 3 / 9 % 2 << 2
b. 0 && (171567 * 98275 / 1174.5 ** 4)
c. 1171 ^ 904
d. "abc" . "de" x 2
Exercises
1. Wr it e a pr ogr am t hat uses t he << oper at or t o pr int out t he f ir st 16 power s of 2.
2. Rewr it e t he f ol l owing st at ement using t he condit ional oper at or :
if ($var1 == 5 || $var2 == 7) {
$result = $var1 * $var2 + 16.5;
} else {
print("condition is false\n");
$result = 0;
}
3. Rewr it e t he f ol l owing expr ession using t he if and else st at ement s:
$result = $var1 <= 26 ? ++$var2 : 0;
4. Wr it e a pr ogr am t hat r eads t wo int eger s f r om st andar d input (one at a t ime),
divides t he f ir st one by t he second one, and pr int s out t he quot ient (t he r esul t )
and t he r emainder .
5. Why might t he f ol l owing st at ement not assign t he val ue 5.1 t o $result?
$result = 5.1 + 100005.2 - 100005.2;
6. Det er mine t he or der of oper at ions in t he f ol l owing st at ement , and add
par ent heses t o t he st at ement t o indicat e t his or der :
$result = $var1 * 2 << 5 + 3 || $var2 ** 3, $var3;
7. What val ue is assigned t o $result by t he f ol l owing code?
$var 1 = 43;
$var 2 = 16;
$r esul t = ++$var 2 == 17 ? $var 1++ * 2 - 5 : ++$var 1 * 3 - 11;
8. BUG BUSTER: Find and f ix t he bugs in t he f ol l owing pr ogr am:
#!/usr/local/bin/perl
$num = <STDIN>;
chop ($num);
$x = "";
$x += "hello";
if ($x != "goodbye" | $x == "farewell") {
$result = $num eq 0 ? 43;
} else {
$result = ++$num++;
}
print("the result is $result\n");

Chapter 5
Lists and Array Variables
CONTENTS
G Int r oducing List s
G Scal ar Var iabl es and List s
H List s and St r ing Subst it ut ion
G St or ing List s in Ar r ay Var iabl es
G Accessing an El ement of an Ar r ay Var iabl e
H Mor e Det ail s on Ar r ay El ement Names
G Using List s and Ar r ays in Per l Pr ogr ams
H Using Br acket s and Subst it ut ing f or Var iabl es
G Using List Ranges
H Expr essions and List Ranges
G Mor e on Assignment and Ar r ay Var iabl es
H Copying f r om One Ar r ay Var iabl e t o Anot her
H Using Ar r ay Var iabl es in List s
H Subst it ut ing f or Ar r ay Var iabl es in St r ings
H Assigning t o Scal ar Var iabl es f r om Ar r ay Var iabl es
G Ret r ieving t he Lengt h of a List
G Using Ar r ay Sl ices
H Using List Ranges in Ar r ay-Sl ice Subscr ipt s
H Using Var iabl es in Ar r ay-Sl ice Subscr ipt s
H Assigning t o Ar r ay Sl ices
H Over l apping Ar r ay Sl ices
H Using t he Ar r ay-Sl ice Not at ion as a Shor t hand
G Reading an Ar r ay f r om t he St andar d Input Fil e
G Ar r ay Libr ar y Funct ions
H Sor t ing a List or Ar r ay Var iabl e
H Rever sing a List or Ar r ay Var iabl e
H Using chop on Ar r ay Var iabl es
H Cr eat ing a Singl e St r ing f r om a List
H Spl it t ing a St r ing int o a List
H Ot her List -Manipul at ion Funct ions
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
The Per l pr ogr ams you have seen so f ar deal wit h scalar values, which ar e singl e unit s of
dat a, and scalar variables, which can st or e one piece of inf or mat ion.
Per l al so enabl es you t o def ine an or der ed col l ect ion of val ues, known as a list; t his
col l ect ion of val ues can be st or ed in var iabl es known as array variables.
Today's l esson descr ibes l ist s and ar r ay var iabl es, and it shows you what you can do
wit h t hem. Today, you l ear n about t he f ol l owing:
G What l ist s ar e
G The r el at ionship bet ween scal ar var iabl es and l ist s
G St or ing l ist s in ar r ay var iabl es
G Accessing an el ement of an ar r ay var iabl e or l ist
G How t o use l ist r anges
G Assigning t o ar r ay var iabl es
G Assigning t o scal ar var iabl es f r om ar r ay var iabl es
G Ret r ieving t he l engt h of a l ist
G Using ar r ay sl ices
G Using an ar r ay t o st or e input
G Sor t ing a l ist or ar r ay var iabl e
G Rever sing a l ist or ar r ay var iabl e
G Cr eat ing a st r ing f r om a l ist
G Cr eat ing a l ist f r om a st r ing
Introducing Lists
A list is a sequence of scal ar val ues encl osed in par ent heses. The f ol l owing is a simpl e
exampl e of a l ist :
(1, 5.3, "hello", 2)
This l ist cont ains f our el ement s, each of which is a scal ar val ue: t he number s 1 and 5.3,
t he st r ing hello, and t he number 2.
List s can be as l ong as needed, and t hey can cont ain any scal ar val ue. A l ist can have
no el ement s at al l , as f ol l ows:
()
This l ist al so is cal l ed an empty list.
NOTE
A l ist wit h one el ement and a scal ar val ue ar e dif f er ent
ent it ies. For exampl e, t he l ist
(43.2)
and t he scal ar val ue
43.2
ar e not t he same t hing. This is not a sever e l imit at ion
because one can be conver t ed t o or assigned t o t he
ot her . See t he sect ion t it l ed "Assigning t o Scal ar
Var iabl es f r om Ar r ay Var iabl es" l at er t oday.
Scalar Variables and Lists
A scal ar var iabl e name can al ways be incl uded as par t of a l ist . In t his case, t he cur r ent
val ue of t he scal ar var iabl e becomes t he l ist el ement val ue. For exampl e:
(17, $var, "a string")
If $var has been assigned t he val ue 26, t he second el ement of t he l ist becomes 26. (It
r emains 26 even if a dif f er ent val ue is assigned t o $var.)
Simil ar l y, you can use t he val ue of an expr ession as an el ement of a l ist . For exampl e:
(17, 26 << 2)
This l ist cont ains t wo el ement s: 17 and 104 (which is 26 l ef t -shif t ed t wo pl aces).
Expr essions in l ist s, l ike ot her expr essions, can cont ain scal ar var iabl es.
(17, $var1 + $var2)
Her e, t he expr ession $var1 + $var2 is eval uat ed and it s val ue becomes t he second
el ement of t he l ist .
Lists and String Substitution
Because char act er st r ings ar e scal ar val ues, t hey can be used in l ist s, as f ol l ows:
("my string", 24.3, "another string")
You can subst it ut e f or scal ar var iabl e names in char act er st r ings in l ist s, as f ol l ows:
($value, "The answer is $value")
This l ist cont ains t wo el ement s: t he val ue of t he scal ar var iabl e $value, and a st r ing
cont aining t he name of $value. If t he cur r ent val ue of $value is 26, t he t wo el ement s of
t he l ist ar e 26 and The answer is 26.
Storing Lists in Array Variables
Per l enabl es you t o st or e l ist s in special var iabl es designed f or t hat pur pose. These
var iabl es ar e cal l ed array variables (or arrays f or shor t ).
The f ol l owing is an exampl e of a l ist being assigned t o an ar r ay var iabl e:
@array = (1, 2, 3);
Her e, t he l ist (1, 2, 3) is assigned t o t he ar r ay var iabl e @array.
Not e t hat t he name of t he ar r ay var iabl e st ar t s wit h t he char act er @. This enabl es Per l
t o dist inguish ar r ay var iabl es f r om ot her kinds of var iabl es-f or exampl e, scal ar
var iabl es, which st ar t wit h t he char act er $. As wit h scal ar var iabl es, t he second
char act er of t he var iabl e name must be a l et t er , whil e subsequent char act er s of t he
name can be l et t er s, number s, or under scor es. Ar r ay var iabl e names can be as l ong as
you want .
The f ol l owing ar e l egal ar r ay-var iabl e names:
@my_array
@list2
@a_very_long_array_name_with_lots_of_underscores
The f ol l owing ar e not l egal ar r ay-var iabl e names:
@1array # can't start with a number
@_array # can't start with an underscore
@a.new.array # . is not a legal variable-name character
When an ar r ay var iabl e is f ir st cr eat ed (t hat is, seen f or t he f ir st t ime), it is assumed t o
cont ain t he empt y l ist () unl ess it is assigned t o.
NOTE
Because Per l uses @ and $ t o dist inguish ar r ay var iabl es
f r om scal ar var iabl es, t he same name can be used in an
ar r ay var iabl e and in a scal ar var iabl e. For exampl e:
$var = 1;
@var = (11, 27.1, "a string");
Her e, t he name var is used in bot h t he scal ar var iabl e
$var and t he ar r ay var iabl e @var. These ar e t wo
compl et el y separ at e var iabl es.
Nor mal l y, you won't want t o use t he same name in bot h
an ar r ay and a scal ar var iabl e, because t his is conf using.
Accessing an Element of an Array Variable
Af t er you have assigned a l ist t o an ar r ay var iabl e, you can r ef er t o any el ement of t he
ar r ay var iabl e as if it is a scal ar var iabl e.
For exampl e, t o assign t he f ir st el ement of t he ar r ay var iabl e @array t o t he scal ar
var iabl e $scalar, use t he f ol l owing st at ement :
$scalar = $array[0];
The char act er sequence [0] is an exampl e of a subscript. A subscr ipt indicat es a par t icul ar
el ement of an ar r ay. In t his case, 0 r ef er s t o t he f ir st el ement of t he ar r ay. Simil ar l y,
t he subscr ipt 1 r ef er s t o t he second el ement of t he ar r ay, as f ol l ows:
$scalar = $array[1];
Her e, t he second el ement of t he ar r ay @array is assigned t o $scalar. The gener al r ul e is
t his:
An ar r ay subscr ipt n, wher e n is any non-negat ive int eger , al ways r ef er s t o ar r ay
el ement n+1.
This not at ion is empl oyed t o ensur e compat ibil it y wit h t he C pr ogr amming l anguage,
which al so st ar t s it s ar r ay subscr ipt ing wit h 0.
You can assign a scal ar val ue t o an individual ar r ay el ement in t he same way:
@array = (1, 2, 3, 4);
$array[3] = 5;
Af t er t he second assignment , t he val ue of @array becomes
(1, 2, 3, 5)
This is because t he f our t h el ement of t he ar r ay has been r epl aced.
NOTE
If you t r y t o access an ar r ay el ement t hat does not
exist , t he Per l int er pr et er uses t he nul l st r ing (which is
equival ent t o zer o).
@array = (1, 2, 3, 4);
$scalar = $array[4];
Her e, $array[4] r ef er s t o t he f if t h el ement of @array,
which does not exist . In t his case, $scalar is assigned t he
nul l st r ing.
NOTE
The same t hing happens when t he subscr ipt is a negat ive
number , as f ol l ows:
$scalar = $array[-1];
Once again, t he nul l st r ing is assigned t o $scalar.
Not e al so t hat ar r ays aut omat ical l y gr ow when a
pr eviousl y unr ef er enced el ement is assigned t o f or t he
f ir st t ime:
@array = (1, 2, 3, 4);
$array[6] = 17;
Because t he sevent h el ement of @array is assigned 17, t he
val ue of @array is now
(1, 2, 3, 4, "", "", 17)
The missing f if t h and sixt h el ement s now cont ain t he
nul l st r ing.
You can use t he val ue of a scal ar var iabl e as a subscr ipt , as f ol l ows:
$index = 1;
$scalar = $array[$index];
Her e, t he val ue of $index, 1, becomes t he subscr ipt . This means t hat t he second el ement
of @array is assigned t o $scalar.
When you use a scal ar var iabl e as a subscr ipt , make sur e
t hat t he val ue st or ed in t he scal ar var iabl e cor r esponds
t o an ar r ay el ement t hat exist s. For exampl e:
@array = (1, 2, 3, 4);
$index = 4;
$scalar = $array[$index];
Her e, t he t hir d st at ement t r ies t o access t he f if t h
el ement of @array, which does not exist . In t his case,
$scalar is assigned t he nul l st r ing, and t he Per l
int er pr et er doesn't t el l you t hat anyt hing went wr ong.
More Details on Array Element Names
Not e t hat t he f ir st char act er of an ar r ay-el ement var iabl e name is t he $ char act er , not
t he @ char act er . For exampl e, t o r ef er t o t he f ir st el ement of t he ar r ay @potato, use
$potato[0]
and not
@potato[0]
The basic r ul e is as f ol l ows:
Things t hat r ef er ence one val ue-such as scal ar var iabl es and ar r ay el ement s-must st ar t
wit h a $.
NOTE
Even t hough r ef er ences t o el ement s of ar r ay var iabl es
st ar t wit h a $, t he Per l int er pr et er st il l has no t r oubl e
dist inguishing scal ar var iabl es f r om ar r ay-var iabl e
el ement s. For exampl e, if you have def ined a scal ar
var iabl e $potato and an ar r ay var iabl e @potato, t he
Per l int er pr et er uses t he subscr ipt t o dist inguish
bet ween t he scal ar var iabl e and t he ar r ay-var iabl e
el ement .
$result = $potato; # the scalar variable $potato
$result = $potato[0]; # the first element of
@potato
Using Lists and Arrays in Perl Programs
Now t hat you have seen how l ist s and ar r ay var iabl es wor k, it 's t ime t o t ake a l ook at a
simpl e pr ogr am t hat uses t hem. List ing 5.1 is a simpl e pr ogr am t hat pr int s t he el ement s of
a l ist .

List ing 5.1. A pr ogr am t hat pr int s t he el ement s of a l ist .
1: #!/usr/local/bin/perl
2:
3: @array = (1, "chicken", 1.23, "\"Having fun?\"", 9.33e+23);
4: $count = 1;
5: while ($count <= 5) {
6: print ("element $count is $array[$count-1]\n");
7: $count++;
8: }

$ program5_1
element 1 is 1
element 2 is chicken
element 3 is 1.23
element 4 is "Having fun?"
element 5 is 9.3300000000000005+e23
$
Line 3 assigns a l ist cont aining f ive el ement s t o t he ar r ay var iabl e @array.
Line 5 t est s whet her $count is l ess t han or equal t o 5. This condit ional expr ession
ensur es t hat t he while st at ement l oops f ive t imes.
Line 6 pr int s t he cur r ent val ue of $count and t he cor r esponding el ement of @array. Not e
t hat t he expr ession used in t he subscr ipt is $count-1, not $count, because subscr ipt ing
st ar t s f r om 0. For exampl e, when count is 3, t he subscr ipt is 2, which means t hat t he t hir d
el ement of @array is pr int ed.
When you examine l ine 6, you see t hat Per l l et s you subst it ut e f or ar r ay el ement s in
char act er st r ings. When t he Per l int er pr et er sees $array[$count-1] in t he char act er
st r ing, it r epl aces t his ar r ay el ement name wit h it s cor r esponding val ue.
List ing 5.2 is anot her exampl e of a pr ogr am t hat uses ar r ays. This one is a l it t l e mor e
int er est ing; it uses t he buil t -in f unct ions rand and int t o gener at e r andom int eger s
bet ween 1 and 10.

List ing 5.2. A pr ogr am t hat gener at es r andom int eger s bet ween 1 and 10.
1: #!/usr/local/bin/perl
2:
3: # collect the random numbers
4: $count = 1;
5: while ($count <= 100) {
6: $randnum = int( rand(10) ) + 1;
7: $randtotal[$randnum] += 1;
8: $count++;
9: }
10:
11: # print the total of each number
12: $count = 1;
13: print ("Total for each number:\n");
14: while ($count <= 10) {
15: print ("\tnumber $count: $randtotal[$count]\n");
16: $count++;
17: }

$ program5_2
Total for each number:
number 1: 11
number 2: 8
number 3: 13
number 4: 6
number 5: 10
number 6: 9
number 7: 12
number 8: 11
number 9: 11
number 10: 9
$
This pr ogr am is divided int o t wo par t s: t he f ir st par t col l ect s t he r andom
number s, and t he second par t pr int s t hem.
Line 5 ensur es t hat t he l oop iterates (is per f or med) 100 t imes. You can just as easil y have
t he pr ogr am gener at e any ot her quant it y of r andom number s just by changing t he val ue
in t his condit ional expr ession.
Line 6 gener at es a r andom number bet ween 1 and 10 and assigns it t o t he scal ar var iabl e
$randnum. To see how it does t his, f ir st not e t hat t he code f r agment
int ( rand (10) )
act ual l y is t wo f unct ion cal l s, one inside anot her . When t he Per l int er pr et er sees t his,
it f ir st cal l s t he inner one, which is rand. The val ue r et ur ned by rand becomes t he
ar gument t o t he l ibr ar y f unct ion int.
Her e's how l ine 6 gener at es a r andom number :
1. Fir st , it cal l s t he Per l l ibr ar y f unct ion rand. This f unct ion gener at es a f l oat ing-
point r andom number bet ween 0 and 1 and t hen mul t ipl ies it by t he ar gument it is
passed. In t his pr ogr am, rand is passed 10, which means t hat t he r andom number is
mul t ipl ied by 10 and is now a f l oat ing-point number t hat is gr eat er t han 0 and
l ess t han 10.
2. The val ue r et ur ned by rand is t hen passed t o t he l ibr ar y f unct ion int, which t akes
a f l oat ing-point number and get s r id of t he non-int eger par t . This oper at ion is
known as truncation. The int eger pr oduced by t his t r uncat ion oper at ion becomes
t he r et ur n val ue of t he f unct ion. For exampl e, t he f ol l owing r et ur ns 5:
int (5.7)
In t his pr ogr am, int t r uncat es t he r andom number r et ur ned by rand and r et ur ns
t he r esul t ing int eger , which is now a r andom number bet ween 0 and 9.
3. The val ue 1 is added t o t he number r et ur ned by int, r esul t ing in a r andom number
bet ween 1 and 10.
4. This number is assigned t o t he scal ar var iabl e $randnum.
Line 7 now adds 1 t o t he el ement of t he ar r ay @randtotal cor r esponding t o t he number
gener at ed. For exampl e, if t he r andom number is 7, t he ar r ay el ement $randtotal[7] has
1 added t o it .
NOTE
As you can see, l ine 7 wor ks even t hough @randtotal is
not init ial ized. When t he pr ogr am r ef er s t o an ar r ay
el ement f or t he f ir st t ime, t he Per l int er pr et er assumes
t hat t he el ement has an init ial val ue of t he nul l st r ing
"". This nul l st r ing is conver t ed t o 0, which means t hat
adding 1 f or t he f ir st t ime pr oduces t he r esul t 1, which is
what you want .
The second par t of t he pr ogr am, which pr int s t he t ot al of each r andom number , st ar t s
wit h l ines 12 and 13. These l ines get t hings st ar t ed by r eset t ing t he count er var iabl e
$count t o 1 and pr int ing an int r oduct or y message.
The condit ional expr ession in l ine 14 ensur es t hat t he l oop it er at es 10 t imes-once f or
each possibl e r andom number .
Line 15 pr int s t he t ot al f or a par t icul ar r andom number .
Using Brackets and Substituting for Variables
As you have just seen, Per l l et s you subst it ut e f or ar r ay-el ement var iabl e names in
st r ings, as f ol l ows:
print ("element $count is $array[ $count-1]\n");
This might l ead t o pr obl ems if you want t o incl ude t he char act er s [ and ] in char act er
st r ings. For exampl e, suppose t hat you have def ined t he scal ar var iabl e $var and t he
ar r ay var iabl e @var. The char act er st r ing
"$var[0]"
subst it ut es t he val ue of t he f ir st el ement of @var in t he st r ing. To subst it ut e t he val ue
of $var and keep t he [0] as it is, you must use one of t he f ol l owing:
"${var}[0]"
"$var\[0]"
"$var" . "[0]"
The char act er st r ing
"${var}[0]"
uses t he br ace char act er s { and } t o keep var and [ separ at e; t his t el l s t he Per l
int er pr et er t o subst it ut e f or t he var iabl e $var, not $var[0]. Af t er t he subst it ut ion, t he
br ace char act er s ar e not incl uded in t he st r ing.
NOTE
To incl ude a br ace char act er af t er a $, use a backsl ash,
as f ol l ows:
"$\{var}"
This char act er st r ing cont ains t he t ext ${var}.
The char act er st r ing
"$var\[0]"
uses \ t o indicat e t hat t he [ char act er is t o be given a dif f er ent meaning t han nor mal ;
in t his case, t his means t hat [ is t o be t r eat ed as a pr int abl e char act er and not as par t of
t he var iabl e name t o be subst it ut ed.
The expr ession
"$var" . "[0]"
consist s of t wo char act er st r ings joined t oget her by t he . oper at or . Her e, t he Per l
int er pr et er r epl aces t he f ir st char act er st r ing wit h t he cur r ent val ue of $var.
Using List Ranges
Suppose t hat you want t o def ine a l ist consist ing of t he number s 1 t hr ough 10, incl usive.
You can do t his by t yping each of t he number s in t ur n.
(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
However , t her e is a simpl er way t o do it : Use t he list-range operator, which is .. (t wo
consecut ive per iod char act er s). The f ol l owing is an exampl e of a l ist cr eat ed using t he
l ist -r ange oper at or :
(1..10)
This t el l s Per l t o def ine a l ist t hat has a f ir st val ue of 1, a second val ue of 2, and so on
up t o 10.
The l ist -r ange oper at or can be used t o def ine par t of a l ist .
(2, 5..7, 11)
This l ist consist s of f ive el ement s: t he number s 2, 5, 6, 7, and 11.
List -r ange oper at or s can be used wit h f l oat ing-point val ues. For exampl e:
(2.1..5.3)
This l ist consist s of f our el ement s: 2.1, 3.1, 4.1, and 5.1. Each el ement of t he l ist is one
gr eat er t han t he pr evious el ement , and t he l ast el ement of t he l ist is t he l ar gest
possibl e number l ess t han or equal t o t he number t o t he r ight of t he .. oper at or . Her e,
5.1 is l ess t han 5.3, so it is incl uded in t he l ist ; however , 6.1 is gr eat er t han 5.3, so it is
not incl uded.
NOTE
If t he val ue t o t he l ef t of t he .. oper at or is gr eat er
t han t he val ue t o t he r ight , an empt y l ist is cr eat ed.
(4.5..1.6)
Because 4.5 is gr eat er t han 1.6, t his l ist is empt y.
If t he t wo val ues ar e equal , a one-el ement l ist is
cr eat ed.
(3..3)
This is equival ent t o t he l ist (3).
List -r ange oper at or s can specif y r anges of st r ings. For exampl e, t he l ist ("aaa", "aab",
"aac", "aad") can be expr essed as ("aaa".."aad"). Simil ar l y, t he l ist ("BCY", "BCZ",
"BDA", "BDB") is equival ent t o ("BCY".."BDB"), and t he st at ement @alphabet =
("a".."z"); cr eat es a l ist consist ing of t he 26 l ower case l et t er s of t he al phabet and
assigns t his l ist t o t he ar r ay var iabl e @alphabet.
List r anges al so enabl e you t o use st r ings t o specif y number s t hat cont ain l eading zer os.
@day_of_month = ("01".."31");
This st at ement cr eat es a l ist consist ing of t he st r ings 01, 02, 03 and so on, up t o 31, and
t hen assigns t his l ist t o @day_of_month. Because each st r ing cont ains t wo char act er s,
t his ar r ay is suit abl e f or use when you ar e pr int ing a dat e in a f or mat such as 08-June-
1960.
Expressions and List Ranges
The val ues t hat def ine t he r ange of a l ist -r ange oper at or can be expr essions, and t hese
expr essions can cont ain scal ar var iabl es. For exampl e:
($var1..$var2+5)
This l ist consist s of al l val ues bet ween t he cur r ent val ue of $var1 and t he cur r ent
val ue of t he expr ession $var2+5.
List ing 5.3 is an exampl e of a pr ogr am t hat uses l ist r anges. This pr ogr am asks f or a st ar t
number and an end number , and it pr int s al l t he number s bet ween t hem.

List ing 5.3. A pr ogr am t hat uses l ist r anges t o pr int a l ist of number s.
1: #!/usr/local/bin/perl
2:
3: print ("Enter the start number:\n");
4: $start = <STDIN>;
5: chop ($start);
6: print ("Enter the end number:\n");
7: $end = <STDIN>;
8: chop ($end);
9: @list = ($start..$end);
10: $count = 0;
11: print ("Here is the list:\n");
12: while ($list[$count] != 0 || $list[$count-1] == -1 ||
13: $list[$count+1] == 1) {
14: print ("$list[$count]\n");
15: $count++;
16: }

$ program5_3
Enter the start number:
-2
Enter the end number:
2
Here is the list:
-2
-1
0
1
2
$
Lines 3 t hr ough 5 r et r ieve t he st ar t of t he r ange t o be pr int ed. Line 3
r et r ieves t he number f r om t he st andar d input f il e. Line 4 assigns t he r esul t ing number
t o t he scal ar var iabl e $start. Line 5 chops t he t r ail ing newl ine char act er .
Lines 6 t hr ough 8 r epeat t he same pr ocess f or t he end of t he r ange, assigning t he end of
t he r ange t o t he scal ar var iabl e $end.
Line 9 cr eat es a l ist t hat consist s of t he number s bet ween $start and $end, and st or es
t he l ist in t he ar r ay var iabl e @list.
Line 10 init ial izes t he count er var iabl e $count t o 0.
Line 11 is a print st at ement t hat indicat es t hat t he l ist is about t o be pr int ed.
Lines 12 and 13 ar e t he st ar t of t he l oop t hat pr int s t he r ange. The condit ional
expr ession t o be eval uat ed consist s of t hr ee subexpr essions t hat ar e oper ands f or t he
l ogical or oper at or ||. If any of t hese subexpr essions ar e t r ue, t he l oop cont inues.
The f ir st subexpr ession t est s f or t he end of t he r ange. To do t his, it t akes advant age of
t he f act t hat an unident if ied l ist el ement is equal t o t he nul l st r ing and t hat t he nul l
st r ing is equival ent t o 0. When t he l ist el ement $list[$count] is undef ined, t he
f ol l owing subexpr ession is f al se:
$list[$count] != 0
The second and t hir d subexpr essions cover t he cases in which 0 is act ual l y a par t of t he
l ist . If t he l ist t o be pr int ed cont ains 0, one or bot h of t he f ol l owing condit ions must be
t r ue:
G The number 1 must be t he next el ement in t he l ist .
G The number -1 must be t he pr evious el ement in t he l ist .
The second and t hir d subexpr essions t est f or t hese condit ions. If eit her or bot h of t hese
condit ions is t r ue, at l east one of t he f ol l owing subexpr essions al so must be t r ue:
$list[$count-1] == -1
$list[$count+1] == 1
This ensur es t hat t he l oop cont inues. Of cour se, t his doesn't cover t he case in which t he
l ist consist s of just 0; however , t hat 's not a meaningf ul case. (If you want t o be f inicky,
you can add a special chunk of code t hat pr int s 0 if $start and $end ar e bot h 0, but
t hat 's not r eal l y wor t h bot her ing wit h.)
Af t er t his, t he r est of t he pr ogr am is st r aight f or war d. Line 14 pr int s a number in t he
r ange, l ine 15 adds one t o t he count er var iabl e $count, and l ine 16 ends t he while
st at ement .
TIP
One of t he pr obl ems wit h Per l is t hat it is somet imes
dif f icul t t o dist inguish t he f ol l owing scal ar var iabl e or
ar r ay-el ement val ues:
G The nul l st r ing "", which is conver t ed t o 0 in
numer ic expr essions
G An undef ined var iabl e or el ement , which def aul t s
t o t he nul l st r ing, which in t ur n is conver t ed t o 0
in numer ic expr essions
G The st r ing 0, which is conver t ed t o t he number 0 in
numer ic expr essions
G A non-numer ic st r ing such as string, which is
conver t ed t o 0 in numer ic expr essions
Ther e ar e sever al ways of deal ing wit h t his conf usion:
1. Ret r ieve t he l engt h of t he l ist st or ed in an ar r ay
var iabl e bef or e pr ocessing it . This ensur es t hat
you don't go past t he end of t he l ist . See t he
sect ion t it l ed "Ret r ieving t he Lengt h of a List "
l at er in t oday's l esson f or mor e det ail s on how t o
do t his.
2. Compar e t he val ue wit h t he st r ing 0 r at her t han
t he number 0, as f ol l ows:
if ($value eq "0") ...
This handl es t he st r ings t hat conver t t o 0 in
numer ic expr essions t hat ar e not 0 it sel f . (It
doesn't handl e st r ings such as 0000 or 0.0, which
you might want your pr ogr am t o consider
equival ent t o 0; t o deal wit h t hese, see t he
discussion of t he split f unct ion l at er in t oday's
l esson.)
3. Init ial ize t he scal ar var iabl e or ar r ay el ement t o
a val ue ot her t han 0 t hat you know is not going
t o appear nat ur al l y in your pr ogr am, such as -
99999.
Which par t icul ar met hod is best depends on
t he pr ogr am you want t o wr it e, t he input it
expect s, and how "bul l et pr oof " t he pr ogr am
needs t o be.
More on Assignment and Array Variables
So f ar , you've seen t hat you can assign l ist s t o ar r ay var iabl es.
@array = (1, 2, 3, 4, 5);
You've al so seen t hat you can assign an el ement of an ar r ay t o a scal ar var iabl e.
$scalar = $array[3];
The f ol l owing sect ions descr ibe t he ot her ways you can use assignment wit h l ist s and
ar r ay var iabl es.
Copying from One Array Variable to Another
You al so can assign one ar r ay var iabl e t o anot her .
@result = @original;
Her e, t he l ist cur r ent l y st or ed in t he ar r ay var iabl e @original is copied t o t he ar r ay
var iabl e @result. Each el ement of t he new ar r ay @result is t he same as t he
cor r esponding el ement of t he ar r ay @original. List ing 5.4 shows t hat t his is t r ue.

List ing 5.4. A pr ogr am t hat copies an ar r ay and compar es t he el ement s
of t he t wo ar r ays.
1: #!/usr/local/bin/perl
2:
3: @array1 = (14, "cheeseburger", 1.23, -7, "toad");
4: @array2 = @array1;
5: $count = 1;
6: while ($count <= 5) {
7: print("element $count: $array1[$count-1] ");
8: print("$array2[$count-1]\n");
9: $count++;
10: }

$ program5_4
element 1: 14 14
element 2: cheeseburger cheeseburger
element 3: 1.23 1.23
element 4: -7 -7
element 5: toad toad
$
Line 3 assigns t he l ist
(14, "cheeseburger", 1.23, -7, "toad")
t o t he ar r ay var iabl e @array1. Line 4 t hen copies t his ar r ay int o a second ar r ay var iabl e,
@array2.
The r est of t he pr ogr am pr int s t he el ement s of each ar r ay, as f ol l ows:
G Line 5 init ial izes t he count er var iabl e $count t o 1.
G The condit ional expr ession in l ine 6 ensur es t hat t he l oop is per f or med f ive t imes.
G Lines 7 and 8 pr int t he mat ching el ement of each ar r ay. (Not e t hat t he subscr ipt is
$count-1, not $count, because t he subscr ipt 0 is t he f ir st el ement of t he ar r ay.)
G Line 9 adds one t o t he count er var iabl e $count.
NOTE
You can assign t o mul t ipl e ar r ays in one st at ement . For
exampl e:
@array1 = @array2 = (1, 2, 3);
This assigns a copy of t he l ist (1, 2, 3) t o bot h @array1
and @array2.
Using Array Variables in Lists
As you've al r eady seen, l ist s can cont ain scal ar var iabl es. For exampl e:
@list = (1, $scalar, 3);
Her e, t he val ue of t he scal ar var iabl e $scalar becomes t he second el ement of t he l ist
assigned t o @list.
You al so can specif y t hat t he val ue of an ar r ay var iabl e is t o appear in a l ist , as
f ol l ows:
@list1 = (2, 3, 4);
@list2 = (1, @list1, 5);
Her e, t he val ue of t he ar r ay var iabl e @list1-t he l ist (2, 3, 4)-is subst it ut ed f or t he
name @list1, and t he r esul t ing l ist (1, 2, 3, 4, 5) is assigned t o @list2.
List ing 5.5 shows an exampl e of a l ist being cont ained in anot her l ist .

List ing 5.5. A pr ogr am t hat assigns a l ist as par t of anot her l ist .
1: #!/usr/local/bin/perl
2:
3: @innerlist = " never ";
4: @outerlist = ("I", @innerlist, "fail!\n");
5: print @outerlist;

$ program5_5
I never fail!
$
Al t hough t his pr ogr am is quit e simpl e, it cont ains a coupl e of new t r icks. The
f ir st of t hese is in l ine 3. Her e, a scal ar val ue, " never " (not e t he sur r ounding spaces),
is assigned t o t he ar r ay var iabl e @innerlist. This wor ks because t he Per l int er pr et er
aut omat ical l y conver t s t he scal ar val ue int o a one-el ement l ist bef or e assigning it t o
t he ar r ay var iabl e.
Line 4 assigns a l ist t o t he ar r ay var iabl e @outerlist. This l ist is assembl ed by t aking t he
f ol l owing l ist :
("I", @innerlist, "fail!\n")
and subst it ut ing in t he cur r ent val ue of t he ar r ay var iabl e @innerlist. As a r esul t , t he
l ist assigned t o @outerlist is
("I", " never ", "fail!\n")
Line 5 pr int s t he l ist . To do t his, it cal l s t he l ibr ar y f unct ion print and passes it t he
ar r ay var iabl e @outerlist. When print is given an ar r ay var iabl e or a l ist t o pr int , it
pr int s each el ement in t ur n. This means t hat t he f ol l owing is wr it t en t o t he st andar d
out put f il e:
I never fail!
Not e t hat print doesn't l eave any spaces bet ween t he el ement s of t he l ist when it pr int s
t hem. The onl y r eason t he out put is r eadabl e is because t he char act er st r ing cont ains
spaces ar ound never. This means t hat print isn't usual l y used t o pr int a l ist of number s
in t his way:
@list = (1, 2, 3);
print @list;
This pr int s t he f ol l owing, which isn't quit e what you want :
123
TIP
In List ing 5.5, t he ar gument passed t o t he print f unct ion
is not encl osed in par ent heses. This is per f ect l y
accept abl e. In Per l , t he par ent heses encl osing
ar gument s t o f unct ions ar e opt ional . For exampl e, when
you cal l t he l ibr ar y f unct ion chop, inst ead of wr it ing
chop ($number);
you can wr it e
chop $number;
Al t hough t his saves a f ew ext r a keyst r okes, it makes
t hings a l it t l e l ess r eadabl e (in t his aut hor 's opinion)
Besides, el iminat ing t he par ent heses can l ead t o
pr obl ems. Consider t he f ol l owing exampl e
$fred = "Fred";
print (("Hello, " . $fred . "!\n") x 2);
This code pr int s
Hello, Fred!
Hello, Fred!
In t his case, t he par ent heses encl osing t he ar gument s t o
print ar e absol ut el y necessar y. Wit hout t hem, you have
print ("Hello, " . $fred . "!\n") x 2;
When t he Per l int er pr et er sees t his st at ement , it assumes
t hat print is being cal l ed wit h t he f ol l owing ar gument ,
which is not what you want :
"Hello, " . $fred . "!\n"
As al ways in pr ogr amming, t he basic r ul e t o f ol l ow is
t his: Do what ever makes your pr ogr am easier t o wor k
wit h, and use your best judgment .
Substituting for Array Variables in Strings
As you have seen, Per l does not l eave spaces if you pass an ar r ay var iabl e t o print:
@array = (1, 2, 3);
print (@array, "\n");
This pr int s t he f ol l owing on your scr een:
123
To get ar ound t his pr obl em, put t he ar r ay you want t o pr int int o a st r ing:
print ("@array\n");
When t he Per l int er pr et er sees t he ar r ay var iabl e inside t he st r ing, it subst it ut es t he
val ues of t he l ist assigned t o t he ar r ay var iabl es, and l eaves a space bet ween each pair
of el ement s. For exampl e:
@array = (1, 2, 3);
print ("@array\n");
This pr int s t he f ol l owing on your scr een:
1 2 3
Assigning to Scalar Variables from Array Variables
Consider t he f ol l owing assignment , which you've al r eady seen:
@array = ($var1, $var2);
Her e, t he val ues of t he scal ar var iabl es $var1 and $var2 ar e used t o f or m a t wo-el ement
l ist t hat is assigned t o t he ar r ay var iabl e @array.
Per l al so enabl es you t o t ake t he cur r ent val ue of an ar r ay var iabl e and assign it s
component s t o a gr oup of scal ar var iabl es. For exampl e:
@array = (5, 7);
($var1, $var2) = @array;
Her e, t he f ir st el ement of t he l ist cur r ent l y st or ed in @array, 5, is assigned t o $var1. The
second el ement , 7, is assigned t o $var2.
Addit ional el ement s in an ar r ay, if t hey exist , ar e ignor ed. For exampl e:
@array = (5, 7, 11);
($var1, $var2) = @array;
Her e, 5 is assigned t o $var1, 7 is assigned t o $var2, and 11 is not assigned t o anyt hing.
If t her e ar e mor e scal ar var iabl es t han el ement s in an ar r ay var iabl e, t he excess scal ar
var iabl es ar e assigned t he nul l st r ing, as f ol l ows:
@array = (5, 7);
($var1, $var2, $var3) = @array;
This assigns 5 t o $var1 and 7 t o $var2. Because t her e ar e not enough el ement s in @array
t o assign anyt hing t o $var3, $var3 is assigned t he nul l st r ing "".
NOTE
You al so can assign t o sever al scal ar var iabl es using a
l ist . For exampl e:
($var1, $var2, $var3) = ("one", "two", "three");
This assigns one t o $var1, two t o $var2, and three t o
$var3.
As wit h ar r ay var iabl es, ext r a val ues in t he l ist ar e
ignor ed and ext r a scal ar var iabl es ar e assigned t he nul l
st r ing, as f ol l ows:
($var1, $var2) = (1, 2, 3); # 3 is ignored
($var1, $var2, $var3) = (1, 2); # $var3 is now ""
Retrieving the Length of a List
As you've seen, l ist s and ar r ay var iabl es can be any l engt h you want . As a consequence,
Per l pr ovides a way of det er mining t he l engt h of t he l ist assigned t o an ar r ay var iabl e.
Her e's how it wor ks: If an ar r ay var iabl e (or l ist ) appear s anywher e t hat a scal ar val ue
is expect ed, t he Per l int er pr et er obt ains a scal ar val ue by cal cul at ing t he l engt h of
t he l ist assigned t o t he ar r ay var iabl e.
Consider t he f ol l owing exampl e:
@array = (1, 2, 3);
$scalar = @array;
In t he assignment t o $scalar, t he Per l int er pr et er r epl aces @array wit h t he l engt h of
t he l ist cur r ent l y assigned t o @array, which is 3. $scalar, t her ef or e, is assigned t he
val ue 3.
NOTE
Not e t hat t he f ol l owing t wo st at ement s ar e not
equival ent :
$scalar = @array;
($scalar) = @array;
In t he f ir st st at ement , t he l engt h of t he l ist in @array is
assigned t o $scalar. In t he second st at ement , t he f ir st
el ement of @array is assigned t o $scalar.
It is al ways impor t ant t o r emember t hat $scalar and
($scalar) ar e not t he same t hing. $scalar is a scal ar
var iabl e, and ($scalar) is a one-el ement l ist cont aining
$scalar.
Being abl e t o access t he l engt h of an ar r ay is usef ul if you want t o wr it e a l oop t hat
per f or ms an oper at ion on ever y el ement of an ar r ay. List ing 5.6 is an exampl e of a
pr ogr am t hat does just t hat .

List ing 5.6. A pr ogr am t hat pr int s ever y el ement of an ar r ay.
1: #!/usr/local/bin/perl
2:
3: @array = (14, "cheeseburger", 1.23, -7, "toad");
4: $count = 1;
5: while ($count <= @array) {
6: print("element $count: $array[$count-1]\n");
7: $count++;
8: }

$ program5_6
element 1: 14
element 2: cheeseburger
element 3: 1.23
element 4: -7
element 5: toad
$
The onl y new f eat ur e of t his pr ogr am is l ine 5, which compar es t he count er
var iabl e $count t o t he l engt h of t he ar r ay @array. Because t he l ist assigned t o @array
cont ains f ive el ement s, t he condit ional expr ession
$count <= @array
ensur es t hat t he l oop it er at es f ive t imes.
Once again, not e t hat t he subscr ipt in l ine 6 is $count-1, not $count. This caut ion bear s
r epeat ing: It is ver y easy t o f or get t o subt r act 1 when you use a val ue as a subscr ipt .
If you l ike, you can wr it e your l oop in a dif f er ent way and use $count as a subscr ipt . For
exampl e:
$count = 0;
while ($count < @array) {
print ("element $count+1: $array[ $count]\n");
}
As you can see, t his isn't any easier t o f ol l ow because you now have t o r emember t hese
t wo t hings:
1. The condit ional expr ession now must use t he < oper at or , not t he <= oper at or . If
you use <= her e, t he l oop it er at es six t imes, not f ive.
2. The val ue of $count is now not t he same as t he el ement you ar e r ef er r ing t o. For
exampl e, if you ar e pr int ing t he t hir d el ement of t he ar r ay, $count has t he val ue
2. This means t hat r ef er ences t o $count, such as
element $count+1:
must add one t o t he val ue of $count t o get t he r esul t you want .
As you can see, t her e is no int uit ive or obvious way of wr it ing pr ogr ams t hat l oop
t hr ough ar r ays. Gener al l y, it 's best t o pick t he way t hat is easiest f or you t o r emember .
You cannot r et r ieve t he l engt h of a l ist wit hout f ir st
assigning t he l ist t o an ar r ay var iabl e. For exampl e:
@array = (10, 20, 30);
$scalar = @array;
This assigns 3 t o $scalar. Compar e t his wit h t he
f ol l owing st at ement :
$scalar = (10, 20, 30);
This st at ement act ual l y assigns 30 t o $scalar, not 3. In
t his st at ement , t he subexpr ession
(10, 20, 30)
is t r eat ed as t hr ee scal ar val ues separ at ed by comma
oper at or s.
For mor e det ail s on t he comma oper at or , r ef er t o "The
Comma Oper at or " in Day 4.
Using Array Slices
As you've seen, ar r ay subscr ipt ing enabl es you t o change or access one el ement of an
ar r ay. For exampl e:
$var = $array[2];
$array[2] = $var;
Per l enabl es you t o access mor e t han one el ement of an ar r ay at a t ime in much t he same
way. Fol l owing is a simpl e exampl e:
@subarray = @array[0,1];
Her e, t he code f r agment
@array[0,1]
r ef er s t o t he f ir st t wo el ement s of t he l ist st or ed in t he ar r ay var iabl e. This por t ion of
t he ar r ay is known as an array slice. An ar r ay sl ice is t r eat ed just l ike any ot her l ist . In
t he st at ement
@subarray = @array[0,1];
t he l ist consist ing of t he f ir st t wo el ement s of @array is assigned t o t he ar r ay var iabl e
@subarray.
Her e is anot her exampl e:
@slice = @array[1,2,3];
This st at ement assigns t he ar r ay sl ice consist ing of t he second, t hir d, and f our t h
el ement s of @array t o t he ar r ay var iabl e @slice.
Al t hough singl e el ement s of an ar r ay ar e r ef er enced
using t he $ char act er , ar r ay sl ices ar e r ef er enced using
@:
$var = $array[0];
@subarray = @array[0,1];
The basic r ul es ar e as f ol l ows:
G Ref er ences t o singl e it ems, such as scal ar var iabl es or singl e
ar r ay el ement s, st ar t wit h a $.
G Ref er ences t o ar r ay var iabl es or ar r ay sl ices, which r ef er t o
l ist s, st ar t wit h a @.
List ing 5.7 shows a simpl e exampl e of an ar r ay sl ice.

List ing 5.7. A pr ogr am t hat demonst r at es t he use of an ar r ay sl ice.
1: #!/usr/local/bin/perl
2:
3: @array = (1, 2, 3, 4);
4: @subarray = @array[1,2];
5: print ("The first element of subarray is $subarray[0]\n");
6: print ("The second element of subarray is $subarray[1]\n");

$ program5_7
The first element of subarray is 2
The second element of subarray is 3
$
Line 3 of t his pr ogr am assigns t he f ol l owing l ist t o t he ar r ay var iabl e @array:
(1, 2, 3, 4)
Line 4 assigns a sl ice of t he ar r ay var iabl e @array t o t he ar r ay var iabl e @subarray. The
ar r ay sl ice
@array[1,2]
specif ies t hat t he second and t hir d el ement s of t he ar r ay ar e t o be t r eat ed as a l ist and
assigned t o @subarray.
NOTE
In ar r ay sl ices, as in r ef er ences t o singl e el ement s of an
ar r ay, subscr ipt s st ar t f r om zer o. For exampl e, t he ar r ay
sl ice
@array[1,2]
r ef er s t o t he second and t hir d el ement s of an ar r ay.
The f inal t wo l ines of t he pr ogr am pr int t he t wo el ement s of t he ar r ay var iabl e
@subarray. As you can see, t hese el ement s ar e ident ical t o t he second and t hir d el ement s
of @array.
Using List Ranges in Array-Slice Subscripts
Per l pr ovides a convenient way t o r ef er t o l ar ge ar r ay sl ices. Inst ead of wr it ing
@array[0,1,2,3,4]
t o r ef er t o t he f ir st f ive el ement s of ar r ay @array, you can use t he l ist r ange oper at or ,
as f ol l ows:
@array[0..4]
This enabl es you t o assign l ar ge ar r ay sl ices easil y:
@subarray = @array[0..19];
This assigns t he f ir st 20 el ement s of @array t o @subarray.
Using Variables in Array-Slice Subscripts
You can use t he val ue of a scal ar var iabl e in a l ist r ange in an ar r ay sl ice subscr ipt . The
f ol l owing is an exampl e:
$endrange = 19;
@subarray = @array[0..$endrange];
Her e, t he scal ar var iabl e $endrange cont ains t he upper l imit of t he ar r ay sl ice, which in
t his case is 19. This means t hat t he ar r ay sl ice t o assign is
@array[0..19]
which assigns t he f ir st 20 el ement s of @array t o @subarray.
You can al so use t he l ist st or ed in an ar r ay var iabl e t o def ine an ar r ay sl ice. List ing 5.8
shows how t his wor ks.

List ing 5.8. A pr ogr am t hat uses an ar r ay var iabl e as an ar r ay-sl ice
subscr ipt .
1: #!/usr/local/bin/perl
2:
3: @array = ("one", "two", "three", "four", "five");
4: @range = (1, 2, 3);
5: @subarray = @array[@range];
6: print ("The array slice is: @subarray\n");

$ program5_8
The array slice is: two three four
$
Line 3 of t his pr ogr am assigns t he f ol l owing l ist t o t he ar r ay var iabl e @array:
("one", "two", "three", "four", "five")
Line 4 assigns t he l ist (1, 2, 3) t o t he ar r ay var iabl e @range, which is t o ser ve as t he
l ist r ange.
Line 5 uses t he val ue of @range as t he ar r ay subscr ipt f or an ar r ay sl ice. Because @range
cont ains (1, 2, 3), t he sl ice of @array t hat is sel ect ed consist s of t he second, t hir d, and
f our t h el ement s. These el ement s ar e t hen assigned t o t he ar r ay var iabl e @subarray.
Line 6 pr int s t he sel ect ed ar r ay sl ice. When t he Per l int er pr et er sees t he var iabl e name
@subarray in t he char act er st r ing t o be pr int ed, it subst it ut es t he val ue of @subarray
f or it s name. Because @subarray is inside a char act er st r ing, t he Per l int er pr et er l eaves
a space bet ween each pair of el ement s when pr int ing.
Compar e l ine 6 wit h t he f ol l owing:
print (@subarray, "\n");
Her e, print l eaves no spaces bet ween t he el ement s of @subarray, which means t hat it
pr int s
twothreefour
Which out come you want depends, of cour se, on what you want your pr ogr am t o do.
Assigning to Array Slices
You can assign t o ar r ay sl ices using t he not at ion you have just seen. The f ol l owing is an
exampl e:
@array[0,1] = ("string", 46);
Her e, t he f ir st t wo el ement s of t he ar r ay @array become string and 46, r espect ivel y.
You can use l ist -r ange oper at or s and var iabl es when you assign t o ar r ay sl ices as wel l .
The f ol l owing is an exampl e:
@array[0..3] = (1, 2, 3, 4);
@array[0..$endrange] = (1, 2, 3, 4);
If t her e ar e mor e it ems in t he ar r ay sl ice t han in t he l ist , t he ext r a it ems in t he ar r ay
sl ice ar e assigned t he nul l st r ing, as f ol l ows:
@array[0..2] = ("string1", "string2");
The t hir d el ement of @array now hol ds t he nul l st r ing.
If t her e ar e f ewer it ems in t he ar r ay sl ice t han in t he l ist , t he ext r a it ems in t he l ist ar e
ignor ed, as in t he f ol l owing:
@array[0..2] = (1, 2, 3, 4);
In t his assignment , t he f our t h el ement in t he l ist , 4, is not assigned t o anyt hing.
When an ar r ay sl ice is assigned t o, t he r emainder of t he ar r ay is not changed. List ing 5.9
shows how t his wor ks.

List ing 5.9. A pr ogr am t hat assigns t o an ar r ay sl ice.
1: #!/usr/local/bin/perl
2:
3: @array = ("old1", "old2", "old3", "old4");
4: @array[1,2] = ("new2", "new3");
5: print ("@array\n");

$ program5_9
old1 new2 new3 old4
$
In t he pr eceding pr ogr am, t he onl y st at ement t hat did not appear in pr evious
pr ogr ams is l ine 4, which assigns t he l ist ("new2", "new3") t o t he ar r ay sl ice of @array
consist ing of t he second and t hir d el ement s. This assignment changes t he val ue of
@array f r om
("old1", "old2", "old3", "old4")
t o
("old1", "new2", "new3", "old4")
Line 5 t hen pr int s t he changed ar r ay.
Overlapping Array Slices
As you've seen, Per l enabl es you t o use ar r ay sl ices on eit her side of an assignment
st at ement . The f ol l owing is an exampl e:
@newarray = @array[2,3,4];
@array[2,3,4] = @newarray;
This means t hat you can assign f r om one ar r ay sl ice t o anot her , even if t he t wo sl ices
over l ap, as in t he f ol l owing:
@array[1,2,3] = @array[2,3,4];
The Per l int er pr et er has no pr obl em wit h t his st at ement because it copies t he l ist st or ed
in @array[2,3,4] int o a t empor ar y l ocat ion (invisibl e t o you) bef or e assigning it t o
@array[1,2,3].
List ing 5.10 pr ovides an exampl e of over l apping ar r ay sl ices in use.

List ing 5.10. A pr ogr am cont aining over l apping ar r ay sl ices.
1: #!/usr/local/bin/perl
2:
3: @array = ("one", "two", "three", "four", "five");
4: @array[1,2,3] = @array[2,3,4];
5: print ("@array\n");

$ program5_10
one three four five five
$
Line 4 is an exampl e of an assignment wit h over l apping ar r ay sl ices. At t he
t ime of assignment , t he ar r ay sl ice @array[2,3,4] cont ains t he l ist
("three", "four", "five")
This l ist consist s of t he l ast t hr ee el ement s of @array. Assigning t his l ist t o
@array[1,2,3] means t hat t he l ist st or ed in @array changes f r om
("one", "two", "three", "four", "five")
t o
("one", "three", "four", "five", "five")
NOTE
Over l apping ar r ay sl ices of var ying l engt hs ar e deal t
wit h in t he same way as ot her ar r ay sl ice assignment s of
non-mat ching l engt hs. For exampl e:
@array = (1, 2, 3, 4, 5);
@array[0..2] = @array[3,4];
This assignment assigns t he ar r ay sl ice @array[3,4],
which is t he l ist (4, 5), t o t he ar r ay sl ice @array[0..2].
Af t er t his assignment , t he val ue of @array is t he l ist
(4, 5, "", 4, 5)
The t hir d el ement of @array is now t he nul l st r ing
because t her e ar e onl y t wo el ement s in t he ar r ay sl ice
being assigned.
Using the Array-Slice Notation as a Shorthand
So f ar , I've been using t he f ol l owing ar r ay-sl ice not at ion t o r ef er t o consecut ive
el ement s of an ar r ay:
@array[0,1]
In Per l , however , t her e is no r eal dif f er ence bet ween an ar r ay sl ice and a l ist
cont aining consecut ive el ement s of t he same ar r ay. For exampl e, t he f ol l owing
st at ement s ar e equival ent :
@subarray = @array[0,1];
@subarray = ($array[0], $array[1]);
Because of t his, you can use t he ar r ay-sl ice not at ion t o r ef er t o any el ement s of an
ar r ay, r egar dl ess of whet her t hey ar e in or der . For exampl e, t he f ol l owing t wo
st at ement s ar e equival ent :
@subarray = ($array[4], $array[1], $array[3]);
@subarray = @array[4,1,3];
In bot h cases, t he ar r ay var iabl e @subarray is assigned a l ist consist ing of t hr ee
el ement s: t he f if t h, second, and f our t h el ement s of @array.
You can use t his ar r ay-sl ice not at ion in a var iet y of ways. For exampl e, you can assign
one el ement of an ar r ay mul t ipl e t imes:
@subarray = @array[0,0,0];
This cr eat es a l ist consist ing of t hr ee copies of t he f ir st el ement of @array, and t hen
assigns t his l ist t o @subarray.
The ar r ay-sl ice not at ion pr ovides an easy way t o swap el ement s in a l ist . The f ol l owing
is an exampl e:
@array[1,2] = @array[2,1];
This st at ement swaps t he second and t hir d el ement s of @array. As wit h t he over l apping
ar r ay sl ices you saw ear l ier , t he Per l int er pr et er copies @array[2,1] int o a t empor ar y
l ocat ion bef or e assigning it , which ensur es t hat t he assignment t akes pl ace pr oper l y.
For an exampl e of a pr ogr am t hat swaps ar r ay el ement s, l ook at List ing 5.11, which sor t s
t he el ement s in an ar r ay using a simpl e sor t al gor it hm.

List ing 5.11. A pr ogr am t hat sor t s an ar r ay.
1: #!/usr/local/bin/perl
2:
3: # read the array from standard input one item at a time
4: print ("Enter the array to sort, one item at a time.\n");
5: print ("Enter an empty line to quit.\n");
6: $count = 1;
7: $inputline = <STDIN>;
8: chop ($inputline);
9: while ($inputline ne "") {
10: @array[$count-1] = $inputline;
11: $count++;
12: $inputline = <STDIN>;
13: chop ($inputline);
14: }
15:
16: # now sort the array
17: $count = 1;
18: while ($count < @array) {
19: $x = 1;
20: while ($x < @array) {
21: if ($array[$x - 1] gt $array[$x]) {
22: @array[$x-1,$x] = @array[$x,$x-1];
23: }
24: $x++;
25: }
26: $count++;
27: }
28:
29: # finally, print the sorted array
30: print ("@array\n");

$ program5_11
Enter the array to sort, one item at a time.
Enter an empty line to quit.
foo
baz
dip
bar
bar baz dip foo
$
This pr ogr am is divided int o t hr ee par t s:
G Reading t he ar r ay
G Sor t ing t he ar r ay
G Pr int ing t he ar r ay
Lines 3-14 r ead t he ar r ay int o t he var iabl e @array. The condit ional expr ession in l ine 9,
$inputline ne "", is t r ue as l ong as t he l ine is not empt y. (Recal l t hat an empt y l ine
consist s of just t he newl ine char act er , which t he l ibr ar y f unct ion chop r emoves.) In t his
exampl e, t he l ist foo baz dip bar is r ead int o t he ar r ay var iabl e @array.
Lines 17-27 per f or m t he sor t . The sor t consist s of t wo l oops, one inside t he ot her . The
inner l oop wor ks l ike t his:
G Line 21 compar es t he f ir st it em in t he l ist wit h t he it em next t o it . If t he f ir st it em
is gr eat er , l ine 22 swaps t he t wo it ems. Ot her wise, t he t wo it ems ar e l ef t wher e
t hey ar e. In t his exampl e, foo is gr eat er t han baz, so foo becomes t he second
el ement in t he l ist . At t his point , t he l ist is
baz foo dip bar
G The pr ogr am t hen l oops back t o l ine 21, which now compar es t he second pair in t he
l ist (t he second and t hir d el ement s). The new second el ement , foo, is compar ed t o
dip. foo is gr eat er , so foo becomes t he new t hir d el ement , and dip becomes t he
second el ement :
baz dip foo bar
G Line 20 t er minat es t he l oop when t he l ast pair is compar ed. (Not e t hat t he
condit ional expr ession compar es t he inner count ing var iabl e $x wit h t he l engt h
of t he ar r ay var iabl e @array. When $x becomes equal t o @array, ever y pair of
el ement s in t he l ist has been compar ed.)
At t his point , t he l ar gest el ement in t he l ist is at t he f ar end of t he l ist :
baz dip bar foo
The l ar gest val ue in t he l ist , foo, has been moved t o t he f ar r ight end of t he l ist , wher e
it bel ongs. The ot her el ement s have been displ aced t o make r oom.
Lines 17-19 and 26-27 cont ain t he out er l oop. This out er l oop just makes sur e t hat t he
inner l oop is r epeat ed n-1 t imes, wher e n is t he number of el ement s in t he l ist . When t he
inner l oop is r epeat ed a second t ime, t he second-l ar gest el ement moves up t o t he second
posit ion f r om t he r ight :
baz bar dip foo
The f inal pass t hr ough t he inner l oop sor t s t he f inal t wo el ement s:
bar baz dip foo
Line 30 t hen pr int s t he sor t ed l ist .
NOTE
You'l l never need t o wr it e a pr ogr am t hat sor t s val ues
in a l ist because Per l has a l ibr ar y f unct ion, sort, t hat
does it f or you. See t he sect ion "Ar r ay Libr ar y
Funct ions" l at er t oday f or mor e det ail s.
Reading an Array from the Standard Input File
In t he pr ogr ams you have seen so f ar , singl e l ines of input ar e r ead f r om t he st andar d
input f il e and st or ed in scal ar var iabl es. For exampl e:
$var = <STDIN>;
In t his case, ever y appear ance of <STDIN> means t hat anot her l ine of input is obt ained
f r om t he st andar d input f il e.
Per l al so pr ovides a quicker appr oach: If you assign <STDIN> t o an ar r ay var iabl e inst ead
of a scal ar var iabl e, t he Per l int er pr et er r eads in al l of t he dat a f r om t he st andar d
input f il e at once and assigns it . For exampl e, t he st at ement
@array = <STDIN>;
r eads ever yt hing t yped in and assigns it al l t o t he ar r ay var iabl e @array. The var iabl e
@array now cont ains a l ist ; each el ement of t he l ist is a l ine of input .
List ing 5.12 is an exampl e of a simpl e pr ogr am t hat r eads it s input dat a int o an ar r ay.

List ing 5.12. A pr ogr am t hat r eads dat a int o an ar r ay and wr it es t he
ar r ay.
1: #!/usr/local/bin/perl
2:
3: @array = <STDIN>;
4: print (@array);

$ program5_12
Here is my first line of data.
Here is another line.
Here is the last line.
^D
Here is my first line of data.
Here is another line.
Here is the last line.
$
As you can see, t his pr ogr am is ver y shor t . Line 3 r eads t he input f r om t he
st andar d input f il e. In t his exampl e, t he input t hat is ent er ed consist s of t he t hr ee l ines
Here is my first line of data.
Here is another line.
Here is the last line.
f ol l owed by t he Ct r l +D key combinat ion. Ct r l +D pr oduces a special char act er t hat
indicat es end of f il e; when t he Per l int er pr et er sees t his, it knows t hat t her e is no mor e
input .
NOTE
A bl ank l ine is per f ect l y accept abl e input and does not
t er minat e t he r eading of input f r om t he st andar d input
f il e. Onl y t he Ct r l +D char act er can do t hat .
Al so not e t hat t he Ct r l +D char act er is a non-pr int ing
char act er . When you t ype it , not hing appear s on t he
scr een. In t he exampl es in t his book, cont r ol char act er s
t hat ar e par t of t he input , such as Ct r l +D, ar e
r epr esent ed by t he ^ char act er f ol l owed by t he l et t er
t yped. For exampl e, Ct r l +D is r epr esent ed as
^D
This r epr esent at ion is t he st andar d one used in t he
comput ing wor l d.
Af t er l ine 3 is execut ed, t he ar r ay var iabl e @array cont ains a l ist compr ising t hr ee
el ement s: t he t hr ee l ines of input you just ent er ed. The l ast char act er of each input
l ine is t he newl ine char act er (because you didn't cal l chop t o get r id of it ).
Line 4 pr int s t he l ines of input you just r ead. Not e t hat you do not need t o separ at e t he
l ines wit h spaces or newl ine char act er s because each l ine in @array is t er minat ed by a
newl ine char act er .
When you use t he f ol l owing st at ement :
@array = <STDIN>;
ever y l ine of input you ent er is st or ed in @array al l at
once. If you ent er a l ot of input , @array can get ver y
l ar ge.
Use t his st at ement onl y when you r eal l y need t o wor k
wit h t he ent ir e input f il e at once.
Array Library Functions
Per l pr ovides a number of l ibr ar y f unct ions t hat wor k on l ist s and ar r ay var iabl es. You
can use t hem t o do t he f ol l owing:
G Sor t ar r ay el ement s in al phabet ical or der
G Rever se t he el ement s of an ar r ay
G Remove t he l ast char act er f r om al l el ement s of an ar r ay
G Mer ge t he el ement s of an ar r ay int o a singl e st r ing
G Spl it a st r ing int o ar r ay el ement s
The f ol l owing sect ions descr ibe t hese ar r ay l ibr ar y f unct ions.
Sorting a List or Array Variable
The l ibr ar y f unct ion sort sor t s t he el ement s of an ar r ay in al phabet ical or der and
r et ur ns t he sor t ed l ist .
The synt ax f or t he sort l ibr ar y f unct ion is
retlist = sort (array);
In t his synt ax, array is t he l ist t o sor t , and retlist is t he sor t ed l ist .
Her e ar e some exampl es:
@array = ("this", "is", "a", "test");
@array2 = sort (@array);
Af t er sort is cal l ed, t he val ue of @array2 is t he l ist
("a", "is", "test", "this")
Not e t hat sort does not modif y t he or iginal l ist . The st at ement
@array2 = sort (@array);
does not change t he val ue of @array. To r epl ace t he cont ent s of an ar r ay var iabl e wit h
t he sor t ed l ist , put t he ar r ay var iabl e on bot h sides of t he assignment , as f ol l ows:
@array = sort (@array);
Her e, t he sor t ed l ist is put back in @array.
The sor t ed l ist must be assigned t o an ar r ay var iabl e in
or der t o be used. The st at ement
sort (@array);
doesn't do anyt hing usef ul because t he sor t ed l ist is not
assigned t o anyt hing.
Not e t hat sort t r eat s it s it ems as st r ings, not int eger s; it ems ar e sor t ed in al phabet ical ,
not numer ic, or der . For exampl e:
@array = (70, 100, 8);
@array = sort (@array);
In t his case, sort pr oduces
(100, 70, 8)
not
(8, 70, 100)
Because sort is t r eat ing t he el ement s of t he l ist as st r ings, t he st r ings t o be sor t ed ar e
70, 100, and 8. When sor t ing char act er s t hat ar e not al phabet ic, sort l ooks at t he
int er nal r epr esent at ion of t he char act er s t o be sor t ed. If you ar e not f amil iar wit h
ASCII (which wil l be descr ibed shor t l y), t his might sound compl icat ed, but it 's not t oo
dif f icul t t o under st and.
Her e's how it wor ks: When Per l (or any ot her pr ogr amming l anguage) st or es a char act er
such as r or 1, what it act ual l y does is st or e a unique eight -bit number t hat cor r esponds
t o t his char act er . For exampl e, t he l et t er r is r epr esent ed by t he number 114, and 1 is
r epr esent ed by t he number 49. Ever y possibl e char act er has it s own unique number .
The sort f unct ion uses t hese unique number s t o det er mine how t o sor t char act er
st r ings. When sor t ing 70, 100, and 8, sort l ooks at t he unique number s cor r esponding t o
7, 1, and 8, which ar e t he f ir st char act er s in each of t he st r ings. As it happens, t he
unique number f or 1 is l ess t han t hat f or 7, which is l ess t han t hat f or 8 (which makes
sense when you t hink of it ). This means t hat 100 is "l ess t han" 70, and 70 is "l ess t han" 8.
Of cour se, if t wo st r ings have ident ical f ir st char act er s, sort t hen compar es t he second
char act er s. For exampl e, when sort sor t s 72 and 7$, t he f ir st char act er s ar e ident ical ;
sort t hen compar es t he unique number r epr esent ing 2 wit h t he number r epr esent ing $. As
it happens, t he number f or $ is smal l er , so 7$ is "l ess t han" 72.
NOTE
The set of unique number s t hat cor r espond t o t he
char act er s under st ood by t he comput er is known as t he
ASCII character set.
Most comput er s t oday use t he ASCII char act er set , wit h
a coupl e of except ions as f ol l ows:
G Some IBM comput er s use an IBM-devel oped
char act er set cal l ed EBCDIC. EBCDIC wor ks t he
same way as ASCII. In bot h cases, a char act er such
as r or 1 is t r ansl at ed int o a number t hat
r epr esent s it . The onl y dif f er ence bet ween
EBCDIC and ASCII is t hat t he t r ansl at ed number s
ar e dif f er ent .
G Comput er s t hat pr int a var iet y of spoken
l anguages, or which deal wit h l anguages such as
Japanese or Chinese, use a mor e compl icat ed 16-bit
code t o r epr esent t he wide var iet y of char act er s
t hey under st and.
You don't r eal l y need t o wor r y about what char act er
set your machine uses, except t o t ake not e of t he sor t ing
or der . A compl et e l ist ing of t he ASCII char act er s can be
f ound in Appendix B, "ASCII Char act er Set ."
Using Other Sort Keys
Nor mal l y, sort sor t s in al phabet ical or der . You can t el l t he Per l int er pr et er t o sor t
using any cr it er ion you l ike. To l ear n mor e about sor t keys, r ef er t o Day 9, "Using
Subr out ines."
Reversing a List or Array Variable
The l ibr ar y f unct ion reverse r ever ses t he or der of t he el ement s of a l ist or ar r ay
var iabl e, and r et ur ns t he r ever sed l ist .
The synt ax f or t he reverse l ibr ar y f unct ion is
retlist = reverse (array);
array is t he l ist t o r ever se, and retlist is t he r ever sed l ist .
Her e is an exampl e:
@array = ("backwards", "is", "array", "this");
@array2 = reverse(@array);
The val ue assigned t o @array2 is t he l ist
("this", "array", "is", "backwards")
As wit h sort, reverse does not change t he or iginal ar r ay.
If you l ike, you can sor t and r ever se t he same l ist by passing t he l ist r et ur ned by sort t o
reverse. List ing 5.13 shows an exampl e of t his. It r eads l ines of dat a f r om t he st andar d
input f il e and sor t s t hem in r ever se or der .

List ing 5.13. A pr ogr am t hat sor t s input l ines in r ever se or der .
1: #!/usr/local/bin/perl
2:
3: @input = <STDIN>;
4: @input = reverse (sort (@input));
5: print (@input);

$ program5_13
foo
bar
dip
baz
^D
foo
dip
baz
bar
$
Line 3 r eads al l t he input l ines f r om t he st andar d input f il e int o t he ar r ay
var iabl e @input. Each el ement of input consist s of a singl e l ine of input t er minat ed wit h
a newl ine char act er .
Line 4 sor t s and r ever ses t he input l ine. Fir st , sort is cal l ed t o sor t t he input l ines in
al phabet ical or der . (Recal l t hat when one l ibr ar y f unct ion appear s inside anot her , t he
inner most one is cal l ed f ir st .) The l ist r et ur ned by sort is t hen passed t o reverse, which
r ever ses t he or der of t he el ement s of t he l ist . The r esul t is a l ist sor t ed in r ever se
or der , which is t hen assigned t o @input.
Line 5 pr int s t he sor t ed l ines. Because each l ine is t er minat ed by a newl ine char act er ,
no ext r a spaces or newl ine char act er s need t o be added t o make t he out put r eadabl e.
NOTE
If you l ike, you can omit t he par ent heses t o t he cal l t o
reverse. This gives you t he f ol l owing st at ement :
@input = reverse sort (@input);
Her e is a case wher e el iminat ing a set of par ent heses
act ual l y makes t he code mor e r eadabl e; it is obvious
t hat t he st at ement sor t s @input in r ever se or der .
Using chop on Array Variables
As you've seen, t he chop l ibr ar y f unct ion r emoves t he l ast char act er f r om a char act er
st r ing. The f ol l owing is an exampl e:
$var = "bathe";
chop ($var); # $var now contains "bath"
The chop f unct ion al so can wor k on l ist s in ar r ay var iabl es. If you pass an ar r ay
var iabl e t o chop, it r emoves t he l ast char act er f r om ever y el ement in t he l ist st or ed in
t he ar r ay var iabl e. For exampl e:
@list = ("rabbit", "12345", "quartz");
chop (@list);
Af t er chop is cal l ed, t he l ist st or ed in @list is
("rabbi", "1234", "quart")
The chop f unct ion of t en is used on ar r ays r ead f r om t he st andar d input f il e, as shown in
t he f ol l owing:
@array = <STDIN>;
chop (@array);
This cal l t o chop r emoves t he newl ine char act er f r om each input l ine. In t he f ol l owing
sect ion, you wil l see pr ogr ams in which t his is hel pf ul .
Creating a Single String from a List
The l ibr ar y f unct ion join cr eat es a singl e st r ing f r om a l ist of st r ings, which t hen can
be assigned t o a scal ar var iabl e.
The synt ax f or t he join l ibr ar y f unct ion is
string = join (array);
array is t he l ist t o join t oget her , and string is t he r esul t ing char act er st r ing.
The f ol l owing is an exampl e using join:
$string = join(" ", "this", "is", "a", "string");
The f ir st el ement of t he l ist suppl ied t o join cont ains t he char act er s t hat ar e t o be
used t o join t he par t s of t he cr eat ed st r ing t oget her . In t his exampl e, $string becomes
this is a string.
join can specif y ot her join st r ings besides " ". For exampl e, t he f ol l owing st at ement
uses a pair of col ons t o join t he st r ings:
$string = join("::", "words", "and", "colons");
In t his st at ement , $string becomes words::and::colons.
You can use any l ist or ar r ay var iabl e as par t or al l of t he ar gument t o join. For
exampl e:
@list = ("here", "is", "a");
$string = join(" ", @list, "string");
This assigns here is a string t o $string.
List ing 5.14 is a simpl e pr ogr am t hat uses join. It joins t oget her al l t he input l ines f r om
t he st andar d input f il e.

List ing 5.14. A pr ogr am t hat t akes it s input and j oins it int o a singl e
st r ing.
1: #!/usr/local/bin/perl
2:
3: @input = <STDIN>;
4: chop (@input);
5: $string = join(" ", @input);
6: print ("$string\n");

$ program5_14
This
is
my
input
^D
This is my input
$
Line 3 r eads al l of t he input l ines int o t he ar r ay var iabl e @input. Each
el ement of @input is a singl e l ine of input t er minat ed by a newl ine char act er .
Line 4 passes t he ar r ay var iabl e @input t o t he l ibr ar y f unct ion chop, which r emoves t he
l ast char act er f r om each el ement of t he l ist st or ed in @input. This r emoves al l of t he
t r ail ing newl ine char act er s.
Line 5 cal l s join, which joins al l t he input l ines int o a singl e st r ing. The f ir st ar gument
passed t o join is " ", which t el l s join t o put one space bet ween each pair of l ines. This
t ur ns t he l ist
("This", "is", "my", "input")
int o t he st r ing
This is my input
Line 6 pr int s t he st r ing pr oduced by join. Not e t hat t he cal l t o print has t o specif y a
newl ine char act er because al l t he newl ine char act er s in t he input l ines have been
r emoved by t he cal l t o chop.
Splitting a String into a List
As you've seen, t he l ibr ar y f unct ion join cr eat es a char act er st r ing f r om a l ist . To undo
t he ef f ect s of join-t o spl it a char act er st r ing int o separ at e it ems-cal l t he f unct ion
split.
The synt ax f or t he l ibr ar y f unct ion split is
array = split (string);
string is t he char act er st r ing t o spl it , and array is t he r esul t ing ar r ay.
The f ol l owing is a simpl e exampl e of t he use of split:
$string = "words::separated::by::colons";
@array = split(/::/, $string);
The f ir st ar gument passed t o split t el l s it wher e t o br eak t he st r ing int o separ at e
par t s. In t his exampl e, t he f ir st ar gument is :: (t wo col ons); because t her e ar e t hr ee
pair s of col ons in t he st r ing, split br eaks t he st r ing int o f our separ at e par t s. The r esul t
is t he l ist
("words", "separated", "by", "colons")
which is assigned t o t he ar r ay var iabl e @array.
NOTE
The / char act er s sur r ounding t he :: in t he cal l t o split
indicat e t hat t he :: is a pattern t o be mat ched. Per l
suppor t s a wide var iet y of special pat t er n-mat ching
sequences, which you wil l l ear n about on Day 7,
"Pat t er n Mat ching."
The split f unct ion is used in a var iet y of appl icat ions. List ing 5.15 uses split t o count
t he number of wor ds in t he st andar d input f il e.

List ing 5.15. A simpl e wor d-count pr ogr am.
1: #!/usr/local/bin/perl
2:
3: $wordcount = 0;
4: $line = <STDIN>;
5: while ($line ne "") {
6: chop ($line);
7: @array = split(/ /, $line);
8: $wordcount += @array;
9: $line = <STDIN>;
10: }
11: print ("Total number of words: $wordcount\n");

$ program5_15
Here is some input.
Here are some more words.
Here is my last line.
^D
Total number of words: 14
$
When you ent er a Ct r l +D (End-of -Fil e) char act er and r ead it using <STDIN>,
t he r esul t ing l ine is t he nul l st r ing. Line 5 of t his pr ogr am t est s f or t his nul l st r ing.
Not e t hat l ine 5 has no pr obl em dist inguishing t he end of f il e f r om a bl ank input l ine
because a bl ank input l ine cont ains t he newl ine char act er , and chop has not yet been
cal l ed. Once t he Per l int er pr et er knows t hat t he pr ogr am is not at t he end of f il e, l ine
6 can be cal l ed; it chops t he newl ine char act er of f t he end of t he input l ine.
Line 7 spl it s t he input l ine int o wor ds. The f ir st ar gument t o spl it , / /, indicat es t hat
t he l ine is t o be br oken whenever t he Per l int er pr et er sees a space. The r esul t ing l ist is
st or ed in @array.
Because each el ement of t he l ist in @array is one wor d in t he input l ine, t he t ot al
number of wor ds in t he l ine is equival ent t o t he number of el ement s in t he ar r ay. Line 8
t akes advant age of t his t o count t he number of wor ds in t he input l ine. Her e's how l ine
8 wor ks:
G When an ar r ay var iabl e appear s in a pl ace wher e t he Per l int er pr et er nor mal l y
expect s a scal ar val ue, t he number of el ement s in t he l ist st or ed in t he ar r ay
var iabl e is subst it ut ed f or t he var iabl e name. In t his pr ogr am, when t he Per l
int er pr et er sees @array, it r epl aces it wit h t he number of el ement s in @array.
G Because t he number of el ement s in t he ar r ay is t he same as t he number of wor ds in
t he input l ine, t he st at ement
$wordcount += @array;
act ual l y adds t he number of wor ds in t he l ine t o $wordcount.
NOTE
List ing 5.15 does not wor k pr oper l y if an input l ine
cont ains mor e t han one space bet ween wor ds. The
f ol l owing is an exampl e:
This is a line
Because t her e ar e t wo spaces bet ween This and is, t he
split f unct ion br eaks
This is
int o t hr ee wor ds: This, an empt y wor d "", and is.
Because of t his, t he l ine
This is a line
appear s t o cont ain f ive wor ds when it r eal l y cont ains
onl y f our .
To get ar ound t his pr obl em, what you need is a pat t er n
t hat mat ches one or mor e spaces. To l ear n about special
pat t er ns such as t his, see Day 7.
List ing 5.16 is an exampl e of a pr ogr am t hat uses split, join, and reverse t o r ever se t he
wor d or der of t he input r ead f r om t he st andar d input f il e.

List ing 5.16. A pr ogr am t hat r ever ses t he wor d or der of t he input f il e.
1: #!/usr/local/bin/perl
2:
3: @input = <STDIN>;
4: chop (@input);
5:
6: # first, reverse the order of the words in each line
7: $currline = 1;
8: while ($currline <= @input) {
9: @words = split(/ /, $input[$currline-1]);
10: @words = reverse(@words);
11: $input[$currline-1] = join(" ", @words, "\n");
12: $currline++;
13: }
14:
15: # now, reverse the order of the input lines and print them
16: @input = reverse(@input);
17: print (@input);

$ program5_16
This sentence
is in
reverse order.
^D
order. reverse
in is
sentence This
$
Line 3 r eads al l of t he st andar d input f il e int o t he ar r ay @input. Line 4 t hen
r emoves t he t r ail ing newl ine char act er s f r om t he input l ines.
Lines 7-13 r ever se each individual l ine. Line 7 compar es t he cur r ent l ine number , st or ed
in $currline, wit h t he number of l ines of input . (Recal l t hat t he number of el ement s in
t he l ist is used whenever an ar r ay var iabl e appear s wher e a scal ar val ue is expect ed.)
Line 9 spl it s a l ine of input int o wor ds. The f ir st ar gument t o split, / /, indicat es t hat a
spl it is t o occur ever y t ime a space is seen. The l ist of wor ds is st or ed in t he ar r ay
var iabl e @words.
Line 10 r ever ses t he or der of t he l ist of wor ds st or ed in @words. Af t er t he l ist has been
r ever sed, l ine 11 joins t he input l ine back t oget her again. Not e t hat l ine 11 appends a
newl ine char act er t o t he input l ine.
Now t hat t he wor ds in each individual l ine have been r ever sed, al l t hat t he pr ogr am
needs t o do is r ever se t he or der of t he l ines t hemsel ves. Line 16 accompl ishes t his.
Line 17 pr int s t he r ever sed input f il e. Not e t hat t he per iod char act er (.) appear s at t he
end of t he f ir st wor d; t his is because t he r ever sing pr ogr am isn't smar t enough t o det ect
and get r id of it . (You can use split t o get r id of t his, t oo, if you want .)
Other List-Manipulation Functions
Per l pr ovides sever al ot her l ist -manipul at ion f unct ions al so. To l ear n about t hese,
r ef er t o Day 14, "Scal ar -Conver sion and List -Manipul at ion Funct ions."
Summary
In t oday's l esson, you l ear ned about l ist s and ar r ay var iabl es. A l ist is an or der ed
col l ect ion of scal ar val ues. A l ist can consist of any number of scal ar val ues.
List s can be st or ed in ar r ay var iabl es, which ar e var iabl es whose names begin wit h t he
char act er @.
Individual el ement s of ar r ay var iabl es can be accessed using subscr ipt s. The subscr ipt 0
r ef er s t o t he f ir st el ement of t he l ist st or ed in t he ar r ay var iabl e, t he subscr ipt 1 r ef er s
t o t he second el ement , and so on. If an ar r ay el ement is not def ined, it is assumed t o hol d
t he nul l st r ing "". If a pr eviousl y undef ined ar r ay el ement is assigned t o, t he ar r ay
gr ows appr opr iat el y.
The l ist -r ange oper at or pr ovides a convenient way t o cr eat e a l ist cont aining
consecut ive number s.
You can copy l ist s f r om one ar r ay var iabl e t o anot her . In addit ion, you can incl ude an
ar r ay var iabl e in a l ist , which means t hat t he l ist st or ed in t he ar r ay var iabl e is copied
int o t he l ist cont aining t he ar r ay-var iabl e name.
Ar r ay-var iabl e names can appear in char act er st r ings; in t his case, t he el ement s of t he
l ist ar e incl uded in pl ace of t he var iabl e name, wit h a space separ at ing each pair of
el ement s.
You can assign val ues t o scal ar var iabl es f r om ar r ay var iabl es, and vice ver sa.
If an ar r ay var iabl e appear s in a pl ace wher e a scal ar var iabl e is expect ed, t he l engt h of
t he l ist st or ed in t he ar r ay var iabl e is used.
You can access any par t of a l ist st or ed in an ar r ay var iabl e by using t he ar r ay-sl ice
not at ion. You can assign val ues t o ar r ay sl ices, and t hey can be used anywher e a l ist is
expect ed.
The ent ir e cont ent s of t he st andar d input f il e can be st or ed in a singl e ar r ay var iabl e.
The l ibr ar y f unct ions sort and reverse sor t and r ever se l ist s, r espect ivel y. The
f unct ion chop r emoves t he l ast char act er f r om each el ement of a l ist . The f unct ion
split br eaks a singl e st r ing int o a col l ect ion of l ist el ement s. The f unct ion join t akes a
col l ect ion of l ist el ement s and joins t hem int o a singl e st r ing.
Q&A
Q: How can I t el l whet her a r ef er ence t o an ar r ay var iabl e such as @array
r ef er s t o t he st or ed l ist or t o t he l engt h of t he l ist ?
A: It 's usual l y pr et t y easy t o t el l . In a l ot of pl aces, using a l ist makes no sense:
$result = $number + @array;
For exampl e, it makes no sense her e t o add a l ist t o $number, so t he l engt h of t he
l ist st or ed in @array is used.
Q: Why do ar r ay el ement s use $ f or t he f ir st char act er of t he el ement name,
and not @? Woul dn' t it make mor e sense t o r ef er t o an ar r ay el ement as
@array[2]
because we al l know t hat t he @ indicat es an ar r ay var iabl e?
A: This r el at es t o t he f ir st quest ion. The Per l int er pr et er needs t o know as soon as
possibl e whet her a var iabl e r ef er ence is a scal ar val ue or a l ist . The $ indicat es
r ight away t hat t he upcoming it em is a scal ar val ue.
Event ual l y, you'l l get used t o t his not at ion.
Q: Is t her e a dif f er ence bet ween an undef ined ar r ay var iabl e and an ar r ay
var iabl e cont aining t he empt y l ist ?
A: No. By def aul t , al l ar r ay var iabl es cont ain t he empt y l ist . Not e, however , t hat
t he empt y l ist is not t he same as a l ist cont aining t he nul l st r ing:
@array = ("");
This l ist cont ains one el ement , which happens t o be a nul l st r ing.
Q: How l ar ge an input f il e can I r ead in using t he f ol l owing st at ement ?
@array = <STDIN>;
A: Per l imposes no l imit on t he size of ar r ays. Your comput er , however , has a f init e
amount of memor y, which l imit s how l ar ge your ar r ays can be.
Q: Why does Per l add spaces when you subst it ut e f or an ar r ay var iabl e in a
st r ing?
A: The most common use of st r ing subst it ut ion is in t he print st at ement . Nor mal l y,
when you pr int a l ist you don't want t o have t he el ement s of t he l ist r unning
t oget her , because you want t o see wher e one el ement st ops and t he next one
st ar t s.
To pr int t he el ement s of a st r ing wit hout spaces bet ween t hem, pass t he l ist t o
print wit hout encl osing it in a st r ing, as f ol l ows:
print ("Here is my list", @list, "\n");
Q: Why does $ appear bef or e 1 in t he ASCII char act er set ?
A: The shor t answer is: Just because. (This r easoning occur s mor e of t en in comput ing
t han you might t hink.)
Her e's a mor e det ail ed expl anat ion: On ear l y machines t hat used t he ASCII
char act er set , per f or mance was mor e ef f icient if t her e was a r el at ionship
bet ween, f or inst ance, t he l ocat ion of t he upper case al phabet ic char act er s and
t he l ower case al phabet ic char act er s. (In f act , if you add 0x20, or 20 hexadecimal ,
t o t he ASCII r epr esent at ion of an upper case l et t er , you get t he cor r esponding
l ower case l et t er .)
Est abl ishing r el at ionships such as t hese meant t hat gaps exist ed bet ween, f or
exampl e, t he r epr esent at ion of Z (which is 90) and t he r epr esent at ion of a (which
is 97). These gaps ar e f il l ed by pr int abl e non-al phanumer ic char act er s; f or
exampl e, t he r epr esent at ion of [ is 91.
As f or why $ appear s bef or e 1, as opposed t o ?, which appear s af t er 1, t he
expl anat ion is: Just because.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. Def ine t he f ol l owing t er ms:
a. l ist
b. empt y l ist
c. ar r ay var iabl e
d. subscr ipt
e. ar r ay sl ice
2. Assume t he f ol l owing assignment s have been per f or med:
@list = (1, 2, 3);
$scalar1 = "hello";
$scalar2 = "there";
What is assigned t o t he ar r ay var iabl e @newlist in each of t he f ol l owing cases?
a. @newlist = @list;
b. @newlist = reverse(@list[1,2]);
c. @newlist = ($scalar1, @list[1,1]);
d. ($dummy, @newlist) = @list;
e. @newlist[2,1,3] = @list[1,2,1];
f . @newlist = <STDIN>;
3. Assume t hat t he f ol l owing assignment s have been per f or med:
@list1 = (1, 2, 3, 4);
@list2 = ("one", "two", "three");
What is t he val ue of $result in each of t he f ol l owing cases?
($dummy, $result) = @list1;
$result = @list1;
($result) = @list2;
($result) = @list1[1..2];
$result = $list2[$list1[$list1[0]]];
$result = $list2[3];
4. What is t he dif f er ence bet ween a l ist and an ar r ay var iabl e?
5. How does t he Per l int er pr et er dist inguish bet ween an ar r ay el ement and a scal ar
var iabl e?
6. How can you ensur e t hat t he @, $, and [ char act er s ar e not subst it ut ed f or in
st r ings?
7. How can you obt ain t he l engt h of a l ist st or ed in an ar r ay var iabl e?
8. What happens when you r ef er t o an ar r ay el ement t hat has not yet been def ined?
9. What happens when you assign t o an ar r ay el ement t hat is l ar ger t han t he
cur r ent l engt h of t he ar r ay?
Exercises
1. Wr it e a pr ogr am t hat count s al l occur r ences of t he wor d the in t he st andar d
input f il e.
2. Wr it e a pr ogr am t hat r eads l ines of input cont aining number s, each of which is
separ at ed by exact l y one space, and pr int s out t he f ol l owing:
a. The t ot al f or each l ine
b. The gr and t ot al
3. Wr it e a pr ogr am t hat r eads al l input f r om t he st andar d input f il e and sor t s al l
t he wor ds in r ever se or der , pr int ing out one wor d per l ine wit h dupl icat es
omit t ed.
4. BUG BUSTER: What is wr ong wit h t he f ol l owing st at ement ?
$result = @array[4];
5. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am? (See if you can f igur e
out what 's wr ong wit hout checking t he l ist ings in t oday's l esson.)
#!/usr/local/bin/perl
@input = <STDIN>;
$currline = 1;
while ($currline < @input) {
@words = split(/ /, $input[$currline]);
@words = sort(@words);
$input[$currline] = join(" ", @words);
$currline++;
}
print (@input);

Chapter 6
Reading from and Writing to Files
CONTENTS
G Opening a Fil e
H The Fil e Var iabl e
H The Fil ename
H The Fil e Mode
H Checking Whet her t he Open Succeeded
G Reading f r om a Fil e
H Fil e Var iabl es and t he St andar d Input Fil e
H Ter minat ing a Pr ogr am Using die
H Reading int o Ar r ay Var iabl es
G Wr it ing t o a Fil e
H The St andar d Out put Fil e Var iabl e
H Mer ging Two Fil es int o One
G Redir ect ing St andar d Input and St andar d Out put
G The St andar d Er r or Fil e
G Cl osing a Fil e
G Det er mining t he St at us of a Fil e
H Fil e-Test Oper at or Synt ax
H Avail abl e Fil e-Test Oper at or s
H Mor e on t he -e Oper at or
H Test ing f or Read Per mission-t he -r Oper at or
H Checking f or Ot her Per missions
H Checking f or Empt y Fil es
H Using Fil e-Test Oper at or s wit h Fil e Var iabl es
G Reading f r om a Sequence of Fil es
H Reading int o an Ar r ay Var iabl e
G Using Command-Line Ar gument s as Val ues
H ARGV and t he <> Oper at or
G Opening Pipes
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
So f ar , you've l ear ned t o r ead input f r om t he st andar d input f il e, which st or es dat a
t hat is ent er ed f r om t he keyboar d. You've al so l ear ned how t o wr it e t o t he st andar d
out put f il e, which sends dat a t o your scr een. In t oday's l esson, you'l l l ear n t he
f ol l owing:
G How t o open a f il e
G How t o r ead f r om and wr it e t o an opened f il e
G How t o r edir ect st andar d input and st andar d out put and how t o use t he st andar d
er r or f il e
G How t o cl ose a f il e
G About f il e-t est oper at or s, which det er mine t he st at us of a f il e
G How t o r ead f r om mul t ipl e f il es
G How t o use command-l ine ar gument s
G How t o open pipes
Opening a File
Bef or e you can r ead f r om or wr it e t o a f il e, you must f ir st open t he f il e. This oper at ion
t el l s t he oper at ing syst em t hat you ar e cur r ent l y accessing t he f il e and t hat no one
el se can change it whil e you ar e wor king wit h it . To open a f il e, cal l t he l ibr ar y
f unct ion open.
The synt ax f or t he open l ibr ar y f unct ion is
open (filevar, filename);
When you cal l open, you must suppl y t wo ar gument s:
G filevar r epr esent s t he name you want t o use in your Per l pr ogr am t o r ef er t o t he
f il e.
G filename r epr esent s t he l ocat ion of t he f il e on your machine.
The File Variable
The f ir st ar gument passed t o open is t he name t hat t he Per l int er pr et er uses t o r ef er t o
t he f il e. This name is al so known as t he file variable (or t he file handle).
A f il e-var iabl e name can be any sequence of l et t er s, digit s, and under scor es, as l ong as
t he f ir st char act er is a l et t er .
The f ol l owing ar e l egal f il e-var iabl e names:
filename
MY_NAME
NAME2
A_REALLY_LONG_FILE_VARIABLE_NAME
The f ol l owing ar e not l egal f il e-var iabl e names:
1NAME
A.FILE.NAME
_ANOTHERNAME
if
if is not a val id f il e-var iabl e name because it has anot her meaning: as you've seen, it
indicat es t he st ar t of an if st at ement . Wor ds such as if t hat have special meanings in
Per l ar e known as reserved words and cannot be used as names.
Tip
It 's a good idea t o use al l upper case l et t er s f or your f il e-
var iabl e names. This makes it easier t o dist inguish f il e-
var iabl e names f r om ot her var iabl e names and f r om
r eser ved wor ds.
The Filename
The second it em passed t o open is t he name of t he f il e you want t o open. For exampl e, if
you ar e r unning Per l on a UNIX f il e syst em, and your cur r ent wor king dir ect or y
cont ains a f il e named file1 t hat you woul d l ike t o open, you can open it as f ol l ows:
open(FILE1, "file1");
This st at ement t el l s Per l t hat you want t o open t he f il e file1 and associat e it wit h t he
f il e var iabl e FILE1.
If you want t o open a f il e in a dif f er ent dir ect or y, you can specif y t he compl et e
pat hname, as f ol l ows:
open(FILE1, "/u/jqpublic/file1");
This opens t he f il e /u/jqpublic/file1 and associat es it wit h t he f il e var iabl e FILE1.
NOTE
If you ar e r unning Per l on a f il e syst em ot her t han
UNIX, use t he f il ename and dir ect or y synt ax t hat is
appr opr iat e f or your syst em. The Per l int er pr et er
r unning on t hat syst em wil l be abl e t o f igur e out wher e
your f il e is l ocat ed.
The File Mode
When you open a f il e, you must decide how you want t o access t he f il e. Ther e ar e t hr ee
dif f er ent file-access modes (or , simpl y, file modes) avail abl e in Per l :
r ead mode Enabl es t he pr ogr am t o r ead t he exist ing cont ent s of
t he f il e but does not enabl e it t o wr it e int o t he f il e
wr it e mode Dest r oys t he cur r ent cont ent s of t he f il e and
over wr it es t hem wit h t he out put suppl ied by t he
pr ogr am
append mode Appends out put suppl ied by t he pr ogr am t o t he exist ing
cont ent s of t he f il e
By def aul t , open assumes t hat a f il e is t o be opened in r ead mode. To specif y wr it e mode,
put a > char act er in f r ont of t he f il ename t hat you pass t o open, as f ol l ows:
open (OUTFILE, ">/u/jqpublic/outfile");
This opens t he f il e /u/jqpublic/outfile f or wr it ing and associat es it wit h t he f il e
var iabl e OUTFILE.
To specif y append mode, put t wo > char act er s in f r ont of t he f il ename, as f ol l ows:
open (APPENDFILE, ">>/u/jqpublic/appendfile");
This opens t he f il e /u/jqpublic/appendfile in append mode and associat es it wit h t he f il e
var iabl e APPENDFILE.
NOTE
Her e ar e a f ew t hings t o r emember when opening f il es:
G When you open a f il e f or wr it ing, any exist ing
cont ent s ar e dest r oyed.
G You cannot r ead f r om and wr it e t o t he same f il e
at t he same t ime.
G When you open a f il e in append mode, t he exist ing
cont ent s ar e not dest r oyed, but you cannot r ead
t he f il e whil e wr it ing t o it .
Checking Whether the Open Succeeded
Bef or e you can use a f il e opened by t he open f unct ion, you shoul d f ir st check whet her
t he open f unct ion act ual l y is giving you access t o t he f il e. The open f unct ion enabl es
you t o do t his by r et ur ning a val ue indicat ing whet her t he f il e-opening oper at ion
succeeded:
G If open r et ur ns a nonzer o val ue, t he f il e has been opened successf ul l y.
G If open r et ur ns 0, an er r or has occur r ed.
As you can see, t he val ues r et ur ned by open cor r espond t o t he val ues f or t r ue and f al se
in condit ional expr essions. This means t hat you can use open in if and unless st at ement s.
The f ol l owing is an exampl e:
if (open(MYFILE, "/u/jqpublic/myfile")) {
# here's what to do if the file opened
}
The code inside t he if st at ement is execut ed onl y if t he f il e has been successf ul l y
opened. This ensur es t hat your pr ogr ams r ead or wr it e onl y t o f il es t hat you can access.
NOTE
If open r et ur ns f al se, you can f ind out what went wr ong
by using t he f il e-t est oper at or s, which you'l l l ear n
about l at er t oday.
Reading from a File
Once you have opened a f il e and det er mined t hat t he f il e is avail abl e f or use, you can
r ead inf or mat ion f r om it .
To r ead f r om a f il e, encl ose t he f il e var iabl e associat ed wit h t he f il e in angl e br acket s
(< and >), as f ol l ows:
$line = <MYFILE>;
This st at ement r eads a l ine of input f r om t he f il e specif ied by t he f il e var iabl e MYFILE
and st or es t he l ine of input in t he scal ar var iabl e $line.
List ing 6.1 is a simpl e pr ogr am t hat r eads input f r om a f il e and wr it es it t o t he st andar d
out put f il e.

List ing 6.1. A pr ogr am t hat r eads l ines f r om a f il e and pr int s t hem.
1: #!/usr/local/bin/perl
2:
3: if (open(MYFILE, "file1")) {
4: $line = <MYFILE>;
5: while ($line ne "") {
6: print ($line);
7: $line = <MYFILE>;
8: }
9: }

$ program6_1
Here is a line of input.
Here is another line of input.
Here is the last line of input.
$
Line 3 opens t he f il e file1 in r ead mode, which means t hat t he f il e is t o be
made avail abl e f or r eading. file1 is assumed t o be in t he cur r ent wor king dir ect or y. The
f il e var iabl e MYFILE is associat ed wit h t he f il e file1.
If t he cal l t o open r et ur ns a nonzer o val ue, t he condit ional expr ession
open(MYFILE, "file1")
is assumed t o be t r ue, and t he code inside t he if st at ement is execut ed.
Lines 4-8 pr int t he cont ent s of file1. The sampl e out put shown her e assumes t hat file1
cont ains t he f ol l owing t hr ee l ines:
Here is a line of input.
Here is another line of input.
Here is the last line of input.
Line 4 r eads t he f ir st l ine of input f r om t he f il e specif ied by t he f il e var iabl e MYFILE,
which is file1. This l ine of input is st or ed in t he scal ar var iabl e $line.
Line 5 t est s whet her t he end of t he f il e specif ied by MYFILE has been r eached. If t her e
ar e no mor e l ines l ef t in MYFILE, $line is assigned t he empt y st r ing.
Line 6 pr int s t he t ext st or ed in $line, which is t he l ine of input r ead f r om MYFILE.
Line 7 r eads t he next l ine of MYFILE, pr epar ing f or t he l oop t o st ar t again.
File Variables and the Standard Input File
Now t hat you have seen how Per l pr ogr ams r ead input f r om f il es in r ead mode, t ake
anot her l ook at a st at ement t hat r eads a l ine of input f r om t he st andar d input f il e.
$line = <STDIN>;
Her e's what is act ual l y happening: The Per l pr ogr am is r ef er encing t he f il e var iabl e
STDIN, which r epr esent s t he st andar d input f il e. The < and > on eit her side of STDIN t el l
t he Per l int er pr et er t o r ead a l ine of input f r om t he st andar d input f il e, just as t he <
and > on eit her side of MYFILE in
$line = <MYFILE>;
t el l t he Per l int er pr et er t o r ead a l ine of input f r om MYFILE.
STDIN is a f il e var iabl e t hat behaves l ike any ot her f il e var iabl e r epr esent ing a f il e in
r ead mode. The onl y dif f er ence is t hat STDIN does not need t o be opened by t he open
f unct ion because t he Per l int er pr et er does t hat f or you.
Terminating a Program Using die
In List ing 6.1, you saw t hat t he r et ur n val ue f r om open can be t est ed t o see whet her t he
pr ogr am act ual l y has access t o t he f il e. The code t hat oper at es on t he opened f il e is
cont ained in an if st at ement .
If you ar e wr it ing a l ar ge pr ogr am, you might not want t o put al l of t he code t hat
af f ect s a f il e inside an if st at ement , because t he dist ance bet ween t he beginning of t he
if st at ement and t he cl osing br ace (}) coul d get ver y l ar ge. For exampl e:
if (open(MYFILE, "file1")) {
# this could be many pages of statements!
}
Besides, af t er a whil e, you'l l pr obabl y get t ir ed of t yping t he spaces or t abs you use t o
indent t he code inside t he if st at ement . Per l pr ovides a way ar ound t his using t he
l ibr ar y f unct ion die.
The synt ax f or t he die l ibr ar y f unct ion is
die (message);
When t he Per l int er pr et er execut es t he die f unct ion, t he pr ogr am t er minat es
immediat el y and pr int s t he message passed t o die.
For exampl e, t he st at ement
die ("Stop this now!\n");
pr int s t he f ol l owing on your scr een and t er minat es t he pr ogr am:
Stop this now!
List ing 6.2 shows how you can use die t o smoot hl y t est whet her a f il e has been opened
cor r ect l y.

List ing 6.2. A pr ogr am t hat uses die when t est ing f or a successf ul f il e
open oper at ion.
1: #!/usr/local/bin/perl
2:
3: unless (open(MYFILE, "file1")) {
4: die ("cannot open input file file1\n");
5: }
6:
7: # if the program gets this far, the file was
8: # opened successfully
9: $line = <MYFILE>;
10: while ($line ne "") {
11: print ($line);
12: $line = <MYFILE>;
13: }

$ program6_2
Here is a line of input.
Here is another line of input.
Here is the last line of input.
$
This pr ogr am behaves t he same way as t he one in List ing 6.1, except t hat it
pr int s out an er r or message when it can't open t he f il e.
Line 3 opens t he f il e and t est s whet her t he f il e opened successf ul l y. Because t his is an
unless st at ement , t he code inside t he br aces ({ and }) is execut ed unl ess t he f il e opened
successf ul l y.
Line 4 is t he cal l t o die t hat is execut ed if t he f il e does not open successf ul l y. This
st at ement pr int s t he f ol l owing message on t he scr een and exit s:
cannot open input file file1
Because l ine 4 t er minat es pr ogr am execut ion when t he f il e is not open, t he pr ogr am can
make it past l ine 5 onl y if t he f il e has been opened successf ul l y.
The l oop in l ines 9-13 is ident ical t o t he l oop you saw in List ing 6.1. The onl y dif f er ence
is t hat t his l oop is no l onger inside an if st at ement .
NOTE
Her e is anot her way t o wr it e l ines 3-5:
open (MYFILE, "file1") || die ("Could not open
file");
Recal l t hat t he l ogical OR oper at or onl y eval uat es t he
expr ession on it s r ight if t he expr ession on it s l ef t is
f al se. This means t hat die is cal l ed onl y if open r et ur ns
f al se (if t he open oper at ion f ail s).
Printing Error Information Using die
If you l ike, you can have die pr int t he name of t he Per l pr ogr am and t he l ine number of
t he st at ement cont aining t he cal l t o die. To do t his, l eave of f t he t r ail ing newl ine
char act er in t he char act er st r ing, as f ol l ows:
die ("Missing input file");
If t he Per l pr ogr am cont aining t his st at ement is cal l ed myprog, and t his st at ement is l ine
14 of myprog, t his cal l t o die pr int s t he f ol l owing and exit s:
Missing input file at myprog line 14.
Compar e t his wit h
die ("Missing input file\n");
which simpl y pr int s t he f ol l owing bef or e exit ing:
Missing input file
Specif ying t he pr ogr am name and l ine number is usef ul in t wo cases:
G If t he pr ogr am cont ains many simil ar er r or messages, you can use die t o specif y t he
l ine number of t he message t hat act ual l y appear ed.
G If t he pr ogr am is cal l ed f r om wit hin anot her pr ogr am, you can use die t o indicat e
t hat t his pr ogr am gener at ed t he er r or .
Reading into Array Variables
Per l enabl es you t o r ead an ent ir e f il e int o a singl e ar r ay var iabl e. To do t his, assign
t he f il e var iabl e t o t he ar r ay var iabl e, as f ol l ows:
@array = <MYFILE>;
This r eads t he ent ir e f il e r epr esent ed by MYFILE int o t he ar r ay var iabl e @array. Each
l ine of t he f il e becomes an el ement of t he l ist t hat is st or ed in @array.
List ing 6.3 is a simpl e pr ogr am t hat r eads an ent ir e f il e int o an ar r ay.

List ing 6.3. A pr ogr am t hat r eads an ent ir e input f il e int o an ar r ay.
1: #!/usr/local/bin/perl
2:
3: unless (open(MYFILE, "file1")) {
4: die ("cannot open input file file1\n");
5: }
6: @input = <MYFILE>;
7: print (@input);

$ program6_3
Here is a line of input.
Here is another line of input.
Here is the last line of input.
$
Lines 3-5 open t he f il e, t est whet her t he f il e has been opened successf ul l y,
and t er minat e t he pr ogr am if t he f il e cannot be opened.
Line 6 r eads t he ent ir e cont ent s of t he f il e r epr esent ed by MYFILE int o t he ar r ay
var iabl e @input. @input now cont ains a l ist consist ing of t he f ol l owing t hr ee el ement s:
("Here is a line of input.\n",
"Here is another line of input.\n",
"Here is the last line of input.\n")
Not e t hat a newl ine char act er is incl uded as t he l ast char act er of each l ine.
Line 7 uses t he print f unct ion t o pr int t he ent ir e f il e.
Writing to a File
Af t er you have opened a f il e in wr it e or append mode, you can wr it e t o t he f il e you have
opened by specif ying t he f il e var iabl e wit h t he print f unct ion. For exampl e, if you have
opened a f il e f or wr it ing using t he st at ement
open(OUTFILE, ">outfile");
t he f ol l owing st at ement :
print OUTFILE ("Here is an output line.\n");
wr it es t he f ol l owing l ine t o t he f il e specif ied by OUTFILE, which is t he f il e cal l ed
outfile:
Here is an output line.
List ing 6.4 is a simpl e pr ogr am t hat r eads f r om one f il e and wr it es t o anot her .

List ing 6.4. A pr ogr am t hat opens t wo f il es and copies one int o anot her .
1: #!/usr/local/bin/perl
2:
3: unless (open(INFILE, "file1")) {
4: die ("cannot open input file file1\n");
5: }
6: unless (open(OUTFILE, ">outfile")) {
7: die ("cannot open output file outfile\n");
8: }
9: $line = <INFILE>;
10: while ($line ne "") {
11: print OUTFILE ($line);
12: $line = <INFILE>;
13: }

This pr ogr am wr it es not hing t o t he scr een because al l out put is dir ect ed t o t he f il e
cal l ed outfile.
Lines 3-5 open file1 f or r eading. If t he f il e cannot be opened, l ine 4 is
execut ed, which pr int s t he f ol l owing message on t he scr een and t er minat es t he pr ogr am:
cannot open input file file1
Lines 6-8 open outfile f or wr it ing; t he > in >outfile indicat es t hat t he f il e is t o be
opened in wr it e mode. If outfile cannot be opened, l ine 7 pr int s t he message
cannot open output file outfile
on t he scr een and t er minat es t he pr ogr am.
The onl y ot her l ine in t he pr ogr am t hat you have not seen in ot her l ist ings in t his
l esson is l ine 11, which wr it es t he cont ent s of t he scal ar var iabl e $line on t he f il e
specif ied by OUTFILE.
Once t his pr ogr am has compl et ed, t he cont ent s of file1 ar e copied int o outfile.
Here is a line of input.
Here is another line of input.
Here is the last line of input.
Make sur e t hat f il es you open in wr it e mode cont ain
not hing val uabl e. When t he open f unct ion opens a f il e
in wr it e mode, any exist ing cont ent s ar e dest r oyed.
The Standard Output File Variable
If you want , your pr ogr am can r ef er ence t he st andar d out put f il e by r ef er r ing t o t he
f il e var iabl e associat ed wit h t he out put f il e. This f il e var iabl e is named STDOUT.
By def aul t , t he print st at ement sends out put t o t he st andar d out put f il e, which means
t hat it sends t he out put t o t he f il e associat ed wit h STDOUT. As a consequence, t he
f ol l owing st at ement s ar e equival ent :
print ("Here is a line of output.\n");
print STDOUT ("Here is a line of output.\n");
NOTE
You do not need t o open STDOUT because Per l
aut omat ical l y opens it f or you.
Merging Two Files into One
In Per l , you can open as many f il es as you l ike, pr ovided you def ine a dif f er ent f il e
var iabl e f or each one. (Act ual l y, t her e is an upper l imit on t he number of f il es you can
open, but it 's f air l y l ar ge and al so syst em-dependent .) For an exampl e of a pr ogr am t hat
has mul t ipl e f il es open at one t ime, t ake a l ook at List ing 6.5. This pr ogr am mer ges t wo
f il es by cr eat ing an out put f il e consist ing of one l ine f r om t he f ir st f il e, one l ine f r om
t he second f il e, anot her l ine f r om t he f ir st f il e, and so on. For exampl e, if an input f il e
named merge1 cont ains t he l ines
a1
a2
a3
and anot her f il e, merge2, cont ains t he l ines
b1
b2
b3
t hen t he r esul t ing out put f il e consist s of
a1
b1
a2
b2
a3
b3

List ing 6.5. A pr ogr am t hat mer ges t wo f il es.
1: #!/usr/local/bin/perl
2:
3: open (INFILE1, "merge1") ||
4: die ("Cannot open input file merge1\n");
5: open (INFILE2, "merge2") ||
6: die ("Cannot open input file merge2\n");
7: $line1 = <INFILE1>;
8: $line2 = <INFILE2>;
9: while ($line1 ne "" || $line2 ne "") {
10: if ($line1 ne "") {
11: print ($line1);
12: $line1 = <INFILE1>;
13: }
14: if ($line2 ne "") {
15: print ($line2);
16: $line2 = <INFILE2>;
17: }
18: }

$ program6_5
a1
b1
a2
b2
a3
b3
$
Lines 3 and 4 show anot her way t o wr it e a st at ement t hat eit her opens a f il e
or cal l s die if t he open f ail s. Recal l t hat t he || oper at or f ir st eval uat es it s l ef t
oper and; if t he l ef t oper and eval uat es t o t r ue (a nonzer o val ue), t he r ight oper and is
not eval uat ed because t he r esul t of t he expr ession is t r ue.
Because of t his, t he r ight oper and, t he cal l t o die, is eval uat ed onl y when t he l ef t
oper and is f al se-which happens onl y when t he cal l t o open f ail s and t he f il e merge1
cannot be opened.
Lines 5 and 6 r epeat t he pr eceding pr ocess f or t he f il e merge2. Again, eit her t he f il e is
opened successf ul l y or t he pr ogr am abor t s by cal l ing die.
The pr ogr am t hen l oops r epeat edl y, r eading a l ine of input f r om each f il e each t ime. The
l oop t er minat es onl y when bot h f il es have been exhaust ed. If one f il e is empt y but t he
ot her is not , t he pr ogr am just copies t he l ine f r om t he non-empt y f il e t o t he st andar d
out put f il e.
Not e t hat t he out put f r om t his pr ogr am is pr int ed on t he scr een. If you decide t hat you
want t o send t his out put t o a f il e, you can do one of t wo t hings:
G You can modif y t he pr ogr am t o wr it e it s out put t o a dif f er ent f il e. To do t his, open
t he f il e in wr it e mode and associat e it wit h a f il e var iabl e. Then, change t he print
st at ement s t o r ef er t o t his f il e var iabl e.
G You can r edir ect t he st andar d out put f il e on t he command l ine.
For a discussion of t he second met hod, see t he f ol l owing sect ion.
Redirecting Standard Input and Standard Output
When you r un pr ogr ams on UNIX, you can r edir ect input and out put using < and >,
r espect ivel y, as f ol l ows:
myprog <input >output
Her e, when you r un t he pr ogr am cal l ed myprog, t he input f or t he pr ogr am is t aken f r om
t he f il e specif ied by input inst ead of f r om t he keyboar d, and t he out put f or t he pr ogr am
is sent t o t he f il e specif ied by output inst ead of t o t he scr een.
When you r un a Per l pr ogr am and r edir ect input using <, t he st andar d input f il e
var iabl e STDIN now r epr esent s t he f il e specif ied wit h <. For exampl e, consider t he
f ol l owing simpl e pr ogr am:
#!/usr/local/bin/perl
$line = <STDIN>;
print ($line);
Suppose t his pr ogr am is named myperlprog and is cal l ed wit h t he command
myperlprog <file1
In t his case, t he st at ement
$line = <STDIN>;
r eads a l ine of input f r om file1 because t he f il e var iabl e STDIN r epr esent s file1.
Simil ar l y, specif ying > on t he command f il e r edir ect s t he st andar d out put f il e f r om t he
scr een t o t he specif ied f il e. For exampl e, consider t his command:
myperlprog <file1 >outfile
It r edir ect s out put f r om t he st andar d out put f il e t o t he f il e cal l ed outfile. Now, t he
f ol l owing st at ement wr it es a l ine of dat a t o outfile:
print ($line);
The Standard Error File
Besides t he st andar d input f il e and t he st andar d out put f il e, Per l al so def ines a t hir d
buil t -in f il e var iabl e, STDERR, which r epr esent s t he st andar d er r or f il e. By def aul t , t ext
sent t o t his f il e is wr it t en t o t he scr een. This enabl es t he pr ogr am t o send messages t o
t he scr een even when t he st andar d out put f il e has been r edir ect ed t o wr it e t o a f il e. As
wit h STDIN and STDOUT, you do not need t o open STDERR because it aut omat ical l y is
opened f or you.
List ing 6.6 pr ovides a simpl e exampl e of t he use of STDERR. The out put shown in t he input -
out put exampl e assumes t hat t he st andar d input f il e and st andar d out put f il e have been
r edir ect ed t o f il es using < and >, as in
myprog <infile >outfile
Ther ef or e, t he onl y out put you see is what is wr it t en t o STDERR.

List ing 6.6. A pr ogr am t hat wr it es t o t he st andar d er r or f il e.
1: #!/usr/local/bin/perl
2:
3: open(MYFILE, "file1") ||
4: die ("Unable to open input file file1\n");
5: print STDERR ("File file1 opened successfully.\n");
6: $line = <MYFILE>;
7: while ($line ne "") {
8: chop ($line);
9: print ("\U$line\E\n");
10: $line = <MYFILE>;
11: }

$ program6_6
File file1 opened successfully.
$
This pr ogr am conver t s t he cont ent s of a f il e int o upper case and sends t he
conver t ed cont ent s t o t he st andar d out put f il e.
Line 3 t r ies t o open file1. If t he f il e cannot be opened, l ine 4 is execut ed. This cal l s die,
which pr int s t he f ol l owing message and t er minat es:
Unable to open input file file1
NOTE
The f unct ion die sends it s messages t o t he st andar d
er r or f il e, not t he st andar d out put f il e. This means t hat
when a pr ogr am t er minat es, t he message pr int ed by die
al ways appear s on your scr een, even when you have
r edir ect ed out put t o a f il e.
If t he f il e is opened successf ul l y, l ine 5 wr it es a message t o t he st andar d er r or f il e,
which indicat es t hat t he f il e has been opened. As you can see, t he st andar d er r or f il e is
not r eser ved sol el y f or er r or s. You can wr it e anyt hing you want t o STDERR at any t ime.
Lines 6-11 r ead one l ine of file1 at a t ime and wr it e it out in upper case (using t he escape
char act er s \U and \E, which you l ear ned about on Day 3, "Under st anding Scal ar
Val ues").
Closing a File
When you ar e f inished r eading f r om or wr it ing t o a f il e, you can t el l t he Per l
int er pr et er t hat you ar e f inished by cal l ing t he l ibr ar y f unct ion close.
The synt ax f or t he close l ibr ar y f unct ion is
close (filevar);
close r equir es one ar gument : t he f il e var iabl e r epr esent ing t he f il e you want t o cl ose.
Once you have cl osed t he f il e, you cannot r ead f r om it or wr it e t o it wit hout invoking
open again.
Not e t hat you do not have t o cal l close when you ar e f inished wit h a f il e: Per l
aut omat ical l y cl oses t he f il e when t he pr ogr am t er minat es or when you open anot her
f il e using a pr eviousl y def ined f il e var iabl e. For exampl e, consider t he f ol l owing
st at ement s:
open (MYFILE, ">file1");
print MYFILE ("Here is a line of output.\n");
open (MYFILE, ">file2");
print MYFILE ("Here is another line of output.\n");
Her e, when file2 is opened f or wr it ing, file1 aut omat ical l y is cl osed. The f il e var iabl e
MYFILE is now associat ed wit h file2. This means t hat t he second print st at ement sends
t he f ol l owing t o file2:
Here is another line of output.
DO use t he <> oper at or , which is an easy way t o r ead
input f r om sever al f il es in succession. See t he sect ion
t it l ed "Reading f r om a Sequence of Fil es," l at er in t his
l esson, f or mor e inf or mat ion on t he <> oper at or .
DON' T use t he same f il e var iabl e t o r epr esent mul t ipl e
f il es unl ess it is absol ut el y necessar y. It is t oo easy t o
l ose t r ack of which f il e var iabl e bel ongs t o which f il e,
especial l y if your pr ogr am is l ar ge or has many nest ed
condit ional st at ement s.
Determining the Status of a File
Many of t he exampl e pr ogr ams in t oday's l esson cal l open and t est t he r et ur ned r esul t
t o see whet her t he f il e has been opened successf ul l y. If open f ail s, it might be usef ul t o
f ind out exact l y why t he f il e coul d not be opened. To do t his, use one of t he file-test
operators.
List ing 6.7 pr ovides an exampl e of t he use of a f il e-t est oper at or . This pr ogr am is a sl ight
modif icat ion of List ing 6.6, which is an upper case conver sion pr ogr am.

List ing 6.7. A pr ogr am t hat checks whet her an unopened f il e act ual l y
exist s.
1: #!/usr/local/bin/perl
2:
3: unless (open(MYFILE, "file1")) {
4: if (-e "file1") {
5: die ("File file1 exists, but cannot be opened.\n");
6: } else {
7: die ("File file1 does not exist.\n");
8: }
9: }
10: $line = <MYFILE>;
11: while ($line ne "") {
12: chop ($line);
13: print ("\U$line\E\n");
14: $line = <MYFILE>;
15: }

$ program6_7
File file1 does not exist.
$
Line 3 at t empt s t o open t he f il e file1 f or r eading. If file1 cannot be opened,
t he pr ogr am execut es t he if st at ement st ar t ing in l ine 4.
Line 4 is an exampl e of a f il e-t est oper at or . This f il e-t est oper at or , -e, t est s whet her it s
oper and, a f il e, act ual l y exist s. If t he f il e file1 exist s, t he expr ession -e "file1"
r et ur ns t r ue, t he message File file1 exists, but cannot be opened. is displ ayed, and
t he pr ogr am exit s. If file1 does not exist , -e "file1" is f al se, and t he l ibr ar y f unct ion
die pr int s t he f ol l owing message bef or e exit ing:
File file1 does not exist.
File-Test Operator Syntax
Al l f il e-t est oper at or s have t he same synt ax as t he -e oper at or used in List ing 6.7.
The synt ax f or t he f il e-t est oper at or s is
-x expr
Her e, x is an al phabet ic char act er and expr is any expr ession. The val ue of expr is
assumed t o be a st r ing t hat cont ains t he name of t he f il e t o be t est ed.
Because t he oper and f or a f il e-t est oper at or can be any expr ession, you can use scal ar
var iabl es and st r ing oper at or s in t he expr ession if you l ike. For exampl e:
$var = "file1";
if (-e $var) {
print STDERR ("File file1 exists.\n");
}
if (-e $var . "a") {
print STDERR ("File file1a exists.\n");
}
In t he f ir st use of -e, t he cont ent s of $var, file1, ar e assumed t o be t he name of a f il e,
and t his f il e is t est ed f or exist ence. In t he second case, a is appended t o t he cont ent s of
file1, pr oducing t he st r ing file1a. The -e oper at or t hen t est s whet her a f il e named
file1a exist s.
NOTE
The Per l int er pr et er does not get conf used by t he
expr ession
-e $var . "a"
because t he . oper at or has higher pr ecedence t han t he -
e oper at or . This means t hat t he st r ing concat enat ion is
per f or med f ir st .
The f il e-t est oper at or s have higher pr ecedence t han t he
compar ison oper at or s but l ower pr ecedence t han t he
shif t oper at or s. To see a compl et e l ist of t he Per l
oper at or s and t heir pr ecedences, r ef er t o Day 4, "Mor e
Oper at or s."
The st r ing can be a compl et e pat h name, if you l ike. The f ol l owing is an exampl e:
if (-e "/u/jqpublic/file1") {
print ("The file exists.\n");
}
This if st at ement t est s f or t he exist ence of t he f il e /u/jqpublic/file1.
Available File-Test Operators
Tabl e 6.1 pr ovides a compl et e l ist of t he f il e-t est oper at or s avail abl e in Per l . In t his
t abl e, name is a pl acehol der f or t he name of t he oper and being t est ed.
Tabl e 6.1. The f il e-t est oper at or s.
Oper at or Descr ipt ion
-b
Is name a bl ock device?
-c
Is name a char act er device?
-d
Is name a dir ect or y?
-e
Does name exist ?
-f
Is name an or dinar y f il e?
-g
Does name have it s setgid bit set ?
-k
Does name have it s "st icky bit " set ?
-l
Is name a symbol ic l ink?
-o
Is name owned by t he user ?
-p
Is name a named pipe?
-r
Is name a r eadabl e f il e?
-s
Is name a non-empt y f il e?
-t
Does name r epr esent a t er minal ?
-u
Does name have it s setuid bit set ?
-w
Is name a wr it abl e f il e?
-x
Is name an execut abl e f il e?
-z
Is name an empt y f il e?
-A
How l ong since name accessed?
-B
Is name a binar y f il e?
-C
How l ong since name's inode accessed?
-M
How l ong since name modif ied?
-O
Is name owned by t he "r eal user " onl y?*
-R
Is name r eadabl e by t he "r eal user " onl y?*
-S
Is name a socket ?
-T
Is name a t ext f il e?
-W
Is name wr it abl e by t he "r eal user " onl y?*
-X
Is name execut abl e by t he "r eal user " onl y?*
* In t his case, t he "r eal user " is t he userid specif ied at l ogin, as
opposed t o t he ef f ect ive user ID, which is t he userid under which you
cur r ent l y ar e wor king. (On some syst ems, a command such as
/user/local/etc/suid enabl es you t o change your ef f ect ive user ID.)
The f ol l owing sect ions descr ibe some of t he mor e common f il e-t est oper at or s and show
you how t hey can be usef ul . (You'l l al so l ear n about mor e of t hese oper at or s on Day 12,
"Wor king wit h t he Fil e Syst em.")
More on the -e Operator
When a Per l pr ogr am opens a f il e f or wr it ing, it dest r oys anyt hing t hat al r eady exist s
in t he f il e. This might not be what you want . Ther ef or e, you might want t o make sur e
t hat your pr ogr am opens a f il e onl y if t he f il e does not al r eady exist .
You can use t he -e f il e-t est oper at or t o t est whet her or not t o open a f il e f or wr it ing.
List ing 6.8 is an exampl e of a pr ogr am t hat does t his.

List ing 6.8. A pr ogr am t hat t est s whet her a f il e exist s bef or e opening it
f or wr it ing.
1: #!/usr/local/bin/perl
2:
3: unless (open(INFILE, "infile")) {
4: die ("Input file infile cannot be opened.\n");
5: }
6: if (-e "outfile") {
7: die ("Output file outfile already exists.\n");
8: }
9: unless (open(OUTFILE, ">outfile")) {
10: die ("Output file outfile cannot be opened.\n");
11: }
12: $line = <INFILE>;
13: while ($line ne "") {
14: chop ($line);
15: print OUTFILE ("\U$line\E\n");
16: $line = <INFILE>;
17: }

$ program6_8
Output file outfile already exists.
$
This pr ogr am is t he upper case conver sion pr ogr am again; most of it shoul d be
f amil iar t o you.
The onl y dif f er ence is l ines 6-8, which use t he -e f il e-t est oper at or t o check whet her
t he out put f il e outfile exist s. If outfile exist s, t he pr ogr am abor t s, which ensur es t hat
t he exist ing cont ent s of outfile ar e not l ost .
If outfile does not exist , t he f ol l owing expr ession f ail s:
-e "outfile"
and t he pr ogr am knows t hat it is saf e t o open outfile because it does not al r eady exist .
Using File-Test Operators in Expressions
If you don't need t o know exact l y why your pr ogr am is f ail ing, you can combine al l of
t he t est s in List ing 6.8 int o a singl e st at ement , as f ol l ows:
open(INFILE, "infile") && !(-e "outfile") &&
open(OUTFILE, ">outfile") || die("Cannot open files\n");
Can you see how t his wor ks? Her e's what is happening: The && oper at or , l ogical AND, is
t r ue onl y if bot h of it s oper ands ar e t r ue. In t his case, t he t wo && oper at or s indicat e
t hat t he subexpr ession up t o, but not incl uding, t he || is t r ue onl y if al l t hr ee of t he
f ol l owing ar e t r ue:
open(INFILE, "infile")
!(-e "outfile")
open(OUTFILE, ">outfile")
Al l t hr ee ar e t r ue onl y when t he f ol l owing condit ions ar e met :
G The input f il e infile can be opened.
G The out put f il e outfile does not al r eady exist .
G The out put f il e outfile can be opened.
If any of t hese subexpr essions is f al se, t he ent ir e expr ession up t o t he || is f al se. This
means t hat t he subexpr ession af t er t he || (t he cal l t o die) is execut ed, and t he pr ogr am
abor t s.
Not e t hat each of t he t hr ee subexpr essions associat ed wit h t he && oper at or s is
eval uat ed in t ur n. This means t hat t he subexpr ession
!(-e "outfile")
is eval uat ed onl y if
open(INFILE, "infile")
is t r ue, and t hat t he subexpr ession
open(OUTFILE, ">outfile")
is eval uat ed onl y if
!(-e "outfile")
is t r ue. This is exact l y t he same l ogic t hat List ing 6.8 uses.
If any of t he subexpr essions is f al se, t he Per l int er pr et er doesn't eval uat e t he r est of
t hem because it knows t hat t he f inal r esul t of
open(INFILE, "infile") && !(-e "outfile") &&
open(OUTFILE, ">outfile")
is going t o be f al se. Inst ead, it goes on t o eval uat e t he subexpr ession t o t he r ight of t he
||, which is t he cal l t o die.
This pr ogr am l ogic is somewhat compl icat ed, and you shoul dn't use it unl ess you f eel
r eal l y comf or t abl e wit h it . The if st at ement s in List ing 6.8 do t he same t hing and ar e
easier t o under st and; however , it 's usef ul t o know how compl icat ed st at ement s such as
t he f ol l owing one wor k because many Per l pr ogr ammer s l ike t o wr it e code t hat wor ks in
t his way:
open(INFILE, "infile") && !(-e "outfile") &&
open(OUTFILE, ">outfile") || die("Cannot open files\n");
In t he next f ew days, you'l l see sever al mor e exampl es of code t hat expl oit s how
expr essions wor k in Per l . "Per l hacker s"-exper ienced Per l pr ogr ammer s-of t en enjoy
compr essing mul t ipl e st at ement s int o shor t er ones, and t hey del ight in compl exit y. Be
war ned.
Testing for Read Permission-the -r Operator
Bef or e you can open a f il e f or r eading, you must have per mission t o r ead t he f il e. The -r
f il e-t est oper at or t est s whet her you have per mission t o r ead a f il e.
List ing 6.9 checks whet her t he per son r unning t he pr ogr am has per mission t o access a
par t icul ar f il e.

List ing 6.9. A pr ogr am t hat t est s f or r ead per mission on a f il e.
1: #!/usr/local/bin/perl
2:
3: unless (open(MYFILE, "file1")) {
4: if (!(-e "file1")) {
5: die ("File file1 does not exist.\n");
6: } elsif (!(-r "file1")) {
7: die ("You are not allowed to read file1.\n");
8: } else {
9: die ("File1 cannot be opened\n");
10: }
11: }

$ program6_9
You are not allowed to read file1.
$
Line 3 of t his pr ogr am t r ies t o open file1. If t he cal l t o open f ail s, t he
pr ogr am t r ies t o f ind out why.
Fir st , l ine 4 t est s whet her t he f il e act ual l y exist s. If t he f il e exist s, t he Per l
int er pr et er execut es l ine 6, which t est s whet her t he f il e has t he pr oper r ead per mission.
If it does not , die is cal l ed; it t hen pr int s t he f ol l owing message and exit s:
You are not allowed to read file1.
NOTE
You do not need t o use t he -e f il e-t est oper at or bef or e
using t he -r f il e-t est oper at or . If t he f il e does not exist , -
r r et ur ns f al se because you can't r ead a f il e t hat isn't
t her e.
The onl y r eason t o use bot h -e and -r is t o enabl e your
pr ogr am t o det er mine exact l y what is wr ong.
Checking for Other Permissions
You can use f il e-t est oper at or s t o t est f or ot her per missions as wel l . To check whet her
you have wr it e per mission on a f il e, use t he -w f il e-t est oper at or .
if (-w "file1") {
print STDERR ("I can write to file1.\n");
} else {
print STDERR ("I can't write to file1.\n");
}
The -x f il e-t est oper at or checks whet her you have execut e per mission on t he f il e (in
ot her wor ds, whet her t he syst em t hinks t his is an execut abl e pr ogr am, and whet her you
have per mission t o r un it if it is), as il l ust r at ed her e:
if (-x "file1") {
print STDERR ("I can run file1.\n");
} else {
print STDERR ("I can't run file1.\n");
}
NOTE
If you ar e t he syst em administ r at or (f or exampl e, you ar e
r unning as user ID root) and have per mission t o access
any f il e, t he -r and -w f il e-t est oper at or s al ways r et ur n
t r ue if t he f il e exist s. Al so, t he -x t est oper at or al ways
r et ur ns t r ue if t he f il e is an execut abl e pr ogr am.
Checking for Empty Files
The -z f il e-t est oper at or t est s whet her a f il e is empt y. This pr ovides a mor e r ef ined t est
f or whet her or not t o open a f il e f or wr it ing: if t he f il e exist s but is empt y, no
inf or mat ion is l ost if you over wr it e t he exist ing f il e.
List ing 6.10 shows how t o use -z.

List ing 6.10. A pr ogr am t hat t est s whet her t he f il e is empt y bef or e
opening it f or wr it ing.
1: #!/usr/local/bin/perl
2:
3: if (-e "outfile") {
4: if (!(-w "outfile")) {
5: die ("Missing write permission for outfile.\n");
6: }
7: if (!(-z "outfile")) {
8: die ("File outfile is non-empty.\n");
9: }
10: }
11: # at this point, the file is either empty or doesn't exist,
12: # and we have permission to write to it if it exists

$ program6_10
File outfile is non-empty.
$
Line 3 checks whet her t he f il e outfile exist s using -e. If it exist s, it can onl y
be opened if t he pr ogr am has per mission t o wr it e t o t he f il e; l ine 4 checks f or t his using -
w.
Line 7 uses -z t o t est whet her t he f il e is empt y. If it is not , l ine 7 cal l s die t o t er minat e
pr ogr am execut ion.
The opposit e of -z is t he -s f il e-t est oper at or , which r et ur ns a nonzer o val ue if t he f il e
is not empt y.
$size = -s "outfile";
if ($size == 0) {
print ("The file is empty.\n");
} else {
print ("The file is $size bytes long.\n");
}
The -s f il e-t est oper at or act ual l y r et ur ns t he size of t he f il e in byt es. It can st il l be
used in condit ional expr essions, t hough, because any nonzer o val ue (indicat ing t hat t he
f il e is not empt y) is t r eat ed as t r ue.
List ing 6.11 uses -s t o r et ur n t he size of a f il e t hat has a name which is suppl ied via t he
st andar d input f il e.

List ing 6.11. A pr ogr am t hat pr int s t he size of a f il e in byt es.
1: #!/usr/local/bin/perl
2:
3: print ("Enter the name of the file:\n");
4: $filename = <STDIN>;
5: chop ($filename);
6: if (!(-e $filename)) {
7: print ("File $filename does not exist.\n");
8: } else {
9: $size = -s $filename;
10: print ("File $filename contains $size bytes.\n");
11: }

$ program6_11
Enter the name of the file:
file1
File file1 contains 128 bytes.
$
Lines 3-5 obt ain t he name of t he f il e and r emove t he t r ail ing newl ine
char act er .
Line 6 t est s whet her t he f il e exist s. If t he f il e doesn't exist , t he pr ogr am indicat es t his.
Line 9 st or es t he size of t he f il e in t he scal ar var iabl e $size. The size is measur ed in
byt es (one byt e is equival ent t o one char act er in a char act er st r ing).
Line 10 pr int s out t he number of byt es in t he f il e.
Using File-Test Operators with File Variables
You can use f il e-t est oper at or s on f il e var iabl es as wel l as char act er st r ings. In t he
f ol l owing exampl e t he f il e-t est oper at or -z t est s t he f il e r epr esent ed by t he f il e
var iabl e MYFILE:
if (-z MYFILE) {
print ("This file is empty!\n");
}
As bef or e, t his f il e-t est oper at or r et ur ns t r ue if t he f il e is empt y and f al se if it is not .
Remember t hat f il e var iabl es can be used onl y af t er you
open t he f il e. If you need t o t est a par t icul ar condit ion
bef or e opening t he f il e (such as whet her t he f il e is
nonzer o), t est it using t he name of t he f il e.
Reading from a Sequence of Files
Many UNIX ut il it y pr ogr ams ar e invoked using t he f ol l owing command synt ax:
programname file1 file2 file3 ...
A pr ogr am t hat uses t his command synt ax oper at es on al l of t he f il es specif ied on t he
command l ine in or der , st ar t ing wit h file1. When file1 has been pr ocessed, t he pr ogr am
t hen pr oceeds on t o file2, and so on unt il al l of t he f il es have been exhaust ed.
In Per l , it 's easy t o wr it e pr ogr ams t hat pr ocess an ar bit r ar y number of f il es because
t her e is a special oper at or , t he <> oper at or , t hat does al l of t he f il e-handl ing wor k f or
you.
To under st and how t he <> oper at or wor ks, r ecal l what happens when you put < and >
ar ound a f il e var iabl e:
$list = <MYFILE>;
This st at ement r eads a l ine of input f r om t he f il e r epr esent ed by t he f il e var iabl e MYFILE
and st or es it in t he scal ar var iabl e $list. Simil ar l y, t he st at ement
$list = <>;
r eads a l ine of input and st or es it in t he scal ar var iabl e $list; however , t he f il e f r om
which it r eads is cont ained on t he command l ine. Suppose, f or exampl e, a pr ogr am
cont aining a st at ement using t he <> oper at or , such as t he st at ement
$list = <>;
is cal l ed myprog and is cal l ed using t he command
$ myprog file1 file2 file3
In t his case, t he f ir st occur r ence of t he <> oper at or r eads t he f ir st l ine of input f r om
file1. Successive occur r ences of <> r ead mor e l ines f r om file1. When file1 is exhaust ed,
<> r eads t he f ir st l ine f r om file2, and so on. When t he l ast f il e, file3, is exhaust ed, <>
r et ur ns an empt y st r ing, which indicat es t hat al l t he input has been r ead.
NOTE
If a pr ogr am cont aining a <> oper at or is cal l ed wit h no
command-l ine ar gument s, t he <> oper at or r eads input
f r om t he st andar d input f il e. In t his case, t he <>
oper at or is equival ent t o <STDIN>.
If a f il e named in a command-l ine ar gument does not
exist , t he Per l int er pr et er wr it es t he f ol l owing message
t o t he st andar d er r or f il e:
Can't open name: No such file or directory
Her e, name is a pl acehol der f or t he name of t he f il e t hat
t he Per l int er pr et er cannot f ind. In t his case, t he Per l
int er pr et er ignor es name and cont inues on wit h t he next
f il e in t he command l ine.
To see how t he <> oper at or wor ks, l ook at List ing 6.12, which displ ays t he cont ent s of
t he f il es specif ied on t he command l ine. (If you ar e f amil iar wit h UNIX, you wil l
r ecognize t his as t he behavior of t he UNIX ut il it y cat.) The out put f r om List ing 6.12
assumes t hat f il es file1 and file2 ar e specif ied on t he command l ine and t hat each f il e
cont ains one l ine.

List ing 6.12. A pr ogr am t hat displ ays t he cont ent s of one or mor e f il es.
1: #!/usr/local/bin/perl
2:
3: while ($inputline = <>) {
4: print ($inputline);
5: }

$ program6_12 file1 file2
This is a line from file1.
This is a line from file2.
$
Once again, you can see how power f ul and usef ul Per l is. This ent ir e pr ogr am
consist s of onl y f ive l ines, incl uding t he header comment and a bl ank l ine.
Line 3 bot h r eads a l ine f r om a f il e and t est s t o see whet her t he l ine is t he empt y st r ing.
Because t he assignment oper at or = r et ur ns t he val ue assigned, t he expr ession
$inputline = <>
has t he val ue "" (t he nul l st r ing) if and onl y if <> r et ur ns t he nul l st r ing, which
happens onl y when t her e ar e no mor e l ines t o r ead f r om any of t he input f il es. This is
exact l y t he point at which t he pr ogr am want s t o st op l ooping. (Recal l t hat a "bl ank
l ine" in a f il e is not t he same as t he nul l st r ing because t he bl ank l ine cont ains t he
newl ine char act er .) Because t he nul l st r ing is equival ent t o f al se in a condit ional
expr ession, t her e is no need t o use a condit ional oper at or such as ne.
When l ine 3 is execut ed f or t he f ir st t ime, t he f ir st l ine in t he f ir st input f il e, file1, is
r ead and st or ed in t he scal ar var iabl e $inputline. Because file1 cont ains onl y one
l ine, t he second pass t hr ough t he l oop, and t he second execut ion of l ine 3, r eads t he
f ir st l ine of t he second input f il e, file2.
Af t er t his, t her e ar e no mor e l ines in eit her file1 or file2, so l ine 3 assigns t he nul l
st r ing t o $inputline, which t er minat es t he l oop.
When it r eaches t he end of t he l ast f il e on t he command
l ine, t he <> oper at or r et ur ns t he empt y st r ing. However ,
if you use t he <> oper at or af t er it has r et ur ned t he
empt y st r ing, t he Per l int er pr et er assumes t hat you
want t o st ar t r eading input f r om t he st andar d input
f il e. (Recal l t hat <> r eads f r om t he st andar d input f il e
if t her e ar e no f il es on t he command l ine.)
This means t hat you have t o be a l it t l e mor e car ef ul
when you use <> t han when you ar e r eading using
<MYFILE> (wher e MYFILE is a f il e var iabl e). If MYFILE has
been exhaust ed, r epeat ed at t empt s t o r ead using
<MYFILE> cont inue t o r et ur n t he nul l st r ing because
t her e isn't anyt hing l ef t t o r ead.
Reading into an Array Variable
As you have seen, if you r ead f r om a f il e using <STDIN> or <MYFILE> in an assignment t o
an ar r ay var iabl e, t he Per l int er pr et er r eads t he ent ir e cont ent s of t he f il e int o t he
ar r ay, as f ol l ows:
@array = <MYFILE>;
This wor ks al so wit h <>. For exampl e, t he st at ement
@array = <>;
r eads al l t he cont ent s al l of t he f il es on t he command l ine int o t he ar r ay var iabl e
@array.
As al ways, be car ef ul when you use t his because you might end up wit h a ver y l ar ge
ar r ay.
Using Command-Line Arguments as Values
As you've seen, t he <> oper at or assumes t hat it s command-l ine ar gument s ar e f il es. For
exampl e, if you st ar t up t he pr ogr am shown in List ing 6.12 wit h t he command
$ program6_12 myfile1 myfile2
t he Per l int er pr et er assumes t hat t he command-l ine ar gument s myfile1 and myfile2 ar e
f il es and displ ays t heir cont ent s.
Per l enabl es you t o use t he command-l ine ar gument s any way you want by def ining a
special ar r ay var iabl e cal l ed @ARGV. When a Per l pr ogr am st ar t s up, t his var iabl e
cont ains a l ist consist ing of t he command-l ine ar gument s. For exampl e, t he command
$ program6_12 myfile1 myfile2
set s @ARGV t o t he l ist
("myfile1", "myfile2")
NOTE
The shel l you ar e r unning (sh, csh, or what ever you ar e
using) is r esponsibl e f or t ur ning a command l ine such as
program6_12 myfile1 myfile2
int o ar gument s. Nor mal l y, any spaces or t ab char act er s
ar e assumed t o be separ at or s t hat indicat e wher e one
command-l ine ar gument st ops and t he next begins. For
exampl e, t he f ol l owing ar e ident ical :
program6_12 myfile1 myfile2
program6_12 myfile1 myfile2
In each case, t he command-l ine ar gument s ar e myfile1
and myfile2.
See your shel l document at ion f or det ail s on how t o put
bl ank spaces or t ab char act er s int o your command-l ine
ar gument s.
As wit h al l ot her ar r ay var iabl es, you can access individual el ement s of @ARGV. For
exampl e, t he st at ement
$var = $ARGV[0];
assigns t he f ir st el ement of @ARGV t o t he scal ar var iabl e $var.
You even can assign t o some or al l of @ARGV if you l ike. For exampl e:
$ARGV[0] = 43;
If you assign t o any or al l of @ARGV, you over wr it e what was al r eady t her e, which means
t hat any command-l ine ar gument s over wr it t en ar e l ost .
To det er mine t he number of command-l ine ar gument s, assign t he ar r ay var iabl e t o a
scal ar var iabl e, as f ol l ows:
$numargs = @ARGV;
As wit h al l ar r ay var iabl es, using an ar r ay var iabl e in a pl ace wher e t he Per l
int er pr et er expect s a scal ar var iabl e means t hat t he l engt h of t he ar r ay is used. In t his
case, $numargs is assigned t he number of command-l ine ar gument s.
C pr ogr ammer s shoul d t ake not e t hat t he f ir st el ement
of @ARGV, unl ike argv[0] in C, does not cont ain t he name
of t he pr ogr am. In Per l , t he f ir st el ement of @ARGV is t he
f ir st command-l ine ar gument .
To get t he name of t he pr ogr am, use t he syst em var iabl e
$0, which is discussed on Day 17, "Syst em Var iabl es."
To see how you can use @ARGV in a pr ogr am, examine List ing 6.13. This pr ogr am assumes
t hat it s f ir st ar gument is a wor d t o l ook f or . The r emaining ar gument s ar e assumed t o be
f il es in which t o l ook f or t he wor d. The pr ogr am pr int s out t he sear ched-f or wor d, t he
number of occur r ences in each f il e, and t he t ot al number of occur r ences.
This exampl e assumes t hat t he f il es file1 and file2 ar e def ined and t hat each f il e
cont ains t he singl e l ine
This file contains a single line of input.
This exampl e is t hen r un wit h t he command
$ programname single file1 file2
wher e programname is a pl acehol der f or t he name of t he pr ogr am. (If you ar e r unning t he
pr ogr am your sel f , you can name t he pr ogr am anyt hing you l ike.)

List ing 6.13. A wor d-sear ch and count ing pr ogr am.
1: #!/usr/local/bin/perl
2:
3: print ("Word to search for: $ARGV[0]\n");
4: $filecount = 1;
5: $totalwordcount = 0;
6: while ($filecount <= @ARGV-1) {
7: unless (open (INFILE, $ARGV[$filecount])) {
8: die ("Can't open input file $ARGV[$filecount]\n");
9: }
10: $wordcount = 0;
11: while ($line = <INFILE>) {
12: chop ($line);
13: @words = split(/ /, $line);
14: $w = 1;
15: while ($w <= @words) {
16: if ($words[$w-1] eq $ARGV[0]) {
17: $wordcount += 1;
18: }
19: $w++;
20: }
21: }
22: print ("occurrences in file $ARGV[$filecount]: ");
23: print ("$wordcount\n");
24: $filecount++;
25: $totalwordcount += $wordcount;
26: }
27: print ("total number of occurrences: $totalwordcount\n");

$ program6_13 single file1 file2
Word to search for: single
occurrences in file file1: 1
occurrences in file file2: 1
total number of occurrences: 2
$
Line 3 pr int s t he wor d t o sear ch f or . The pr ogr am assumes t hat t his wor d is
t he f ir st ar gument in t he command l ine and, t her ef or e, is t he f ir st el ement of t he ar r ay
@ARGV.
Lines 7-9 open a f il e named on t he command l ine. The f ir st t ime l ine 7 is execut ed, t he
var iabl e $filecount has t he val ue 1, and t he f il e whose name is in $ARGV[1] is opened.
The next t ime t hr ough, $filecount is 2 and t he f il e named in $ARGV[2] is opened, and so
on. If a f il e cannot be opened, t he pr ogr am t er minat es.
Line 11 r eads a l ine f r om a f il e. As bef or e, t he condit ional expr ession
$line = <INFILE>
r eads a l ine f r om t he f il e r epr esent ed by t he f il e INFILE and assigns it t o $line. If t he
f il e is empt y, $line is assigned t he nul l st r ing, t he condit ional expr ession is f al se, and
t he l oop in l ines 11-21 is t er minat ed.
Line 13 spl it s t he l ine int o wor ds, and l ines 15-20 compar e each wor d wit h t he sear ch
wor d. If t he wor d mat ches, t he wor d count f or t his f il e is incr ement ed. This wor d count
is r eset when a new f il e is opened.
ARGV and the <> Operator
In Per l , t he <> oper at or act ual l y cont ains a hidden r ef er ence t o t he ar r ay @ARGV. Her e's
how it wor ks:
1. When t he Per l int er pr et er sees t he <> f or t he f ir st t ime, it opens t he f il e whose
name is st or ed in $ARGV[0].
2. Af t er opening t he f il e, t he Per l int er pr et er execut es t he f ol l owing l ibr ar y
f unct ion:
shift(@ARGV);
This l ibr ar y f unct ion get s r id of t he f ir st el ement of @ARGV and moves ever y ot her
el ement over one. This means t hat el ement x of @ARGV becomes el ement x-1.
3. The <> oper at or t hen r eads al l of t he l ines of t he f il e opened in st ep 1.
4. When t he <> oper at or exhaust s an input f il e, t he Per l int er pr et er goes back t o
st ep 1 and r epeat s t he cycl e again.
If you l ike, you can modif y your pr ogr am t o r et r ieve a val ue f r om t he command l ine and
t hen f ix @ARGV so t hat t he <> oper at or can wor k pr oper l y. If you modif y List ing 6.13 t o do
t his, t he r esul t is List ing 6.14.

List ing 6.14. A wor d-sear ch and count ing pr ogr am t hat uses <>.
1: #!/usr/local/bin/perl
2:
3: $searchword = $ARGV[0];
4: print ("Word to search for: $searchword\n");
5: shift (@ARGV);
6: $totalwordcount = $wordcount = 0;
7: $filename = $ARGV[0];
8: while ($line = <>) {
9: chop ($line);
10: @words = split(/ /, $line);
11: $w = 1;
12: while ($w <= @words) {
13: if ($words[$w-1] eq $searchword) {
14: $wordcount += 1;
15: }
16: $w++;
17: }
18: if (eof) {
19: print ("occurrences in file $filename: ");
20: print ("$wordcount\n");
21: $totalwordcount += $wordcount;
22: $wordcount = 0;
23: $filename = $ARGV[0];
24: }
25: }
26: print ("total number of occurrences: $totalwordcount\n");

$ program6_14 single file1 file2
Word to search for: single
occurrences in file file1: 1
occurrences in file file2: 1
total number of occurrences: 2
$
Line 3 assigns t he f ir st command-l ine ar gument , t he sear ch wor d, t o t he
scal ar var iabl e $searchword. This is necessar y because t he cal l t o shift in l ine 5
dest r oys t he init ial val ue of $ARGV[0].
Line 5 adjust s t he ar r ay @ARGV so t hat t he <> oper at or can use it . To do t his, it cal l s t he
l ibr ar y f unct ion shift. This f unct ion "shif t s" t he el ement s of t he l ist st or ed in @ARGV.
The el ement in $ARGV[1] is moved t o $ARGV[0], t he el ement in $ARGV[2] is moved t o
$ARGV[1], and so on. Af t er shift is cal l ed, @ARGV cont ains t he f il es t o be sear ched, which
is exact l y what t he <> oper at or is l ooking f or .
Line 7 assigns t he cur r ent val ue of $ARGV[0] t o t he scal ar var iabl e $filename. Because
t he <> oper at or in l ine 8 cal l s shift, t he val ue of $ARGV[0] is l ost unl ess t he pr ogr am
does t his.
Line 8 uses t he <> oper at or t o open t he f il e named in $ARGV[0] and t o r ead a l ine f r om
t he f il e. The ar r ay var iabl e @ARGV is shif t ed at t his point .
Lines 9-16 behave as in List ing 6.13. The onl y dif f er ence is t hat t he sear ch wor d is now in
$searchword, not in $ARGV[0].
Line 18 int r oduces t he l ibr ar y f unct ion eof. This f unct ion indicat es whet her t he
pr ogr am has r eached t he end of t he f il e being r ead by <>. If eof r et ur ns t r ue, t he next
use of <> opens a new f il e and shif t s @ARGV again.
Lines 19-23 pr epar e f or t he opening of a new f il e. The number of occur r ences of t he
sear ch wor d is pr int ed, t he cur r ent wor d count is added t o t he t ot al wor d count , and
t he wor d count is r eset t o 0. Because t he new f il ename t o be opened is in $ARGV[0], l ine
23 pr eser ves t his f il ename by assigning it t o $filename.
NOTE
You can use t he <> oper at or t o open and r ead any f il e
you l ike by set t ing t he val ue of @ARGV your sel f . For
exampl e:
@ARGV = ("myfile1", "myfile2");
while ($line = <>) {
...
}
Her e, when t he st at ement cont aining t he <> is execut ed
f or t he f ir st t ime, t he f il e myfile1 is opened and it s f ir st
l ine is r ead. Subsequent execut ions of <> each r ead
anot her l ine of input f r om myfile1. When myfile1 is
exhaust ed, myfile2 is opened and r ead one l ine at a t ime.
Opening Pipes
On machines r unning t he UNIX oper at ing syst em, t wo commands can be l inked using a
pipe. In t his case, t he st andar d out put f r om t he f ir st command is l inked, or piped, t o t he
st andar d input t o t he second command.
Per l enabl es you t o est abl ish a pipe t hat l inks a Per l out put f il e t o t he st andar d input
f il e of anot her command. To do t his, associat e t he f il e wit h t he command by cal l ing
open, as f ol l ows:
open (MYPIPE, "| cat >hello");
The | char act er t el l s t he Per l int er pr et er t o est abl ish a pipe. When MYPIPE is opened,
out put sent t o MYPIPE becomes input t o t he command
cat >hello
Because t he cat command displ ays t he cont ent s of t he st andar d input f il e when cal l ed
wit h no ar gument s, and >hello r edir ect s t he st andar d out put f il e t o t he f il e hello, t he
open st at ement given her e is ident ical t o t he st at ement
open (MYPIPE, ">hello");
You can use a pipe t o send mail f r om wit hin a Per l pr ogr am. For exampl e:
open (MESSAGE, "| mail dave");
print MESSAGE ("Hi, Dave! Your Perl program sent this!\n");
close (MESSAGE);
The cal l t o open est abl ishes a pipe t o t he command mail dave. The f il e var iabl e MESSAGE
is now associat ed wit h t his pipe. The cal l t o print adds t he l ine
Hi, Dave! Your Perl program sent this!
t o t he message t o be sent t o user ID dave.
The cal l t o close cl oses t he pipe r ef er enced by MESSAGE, which t el l s t he syst em t hat t he
message is compl et e and can be sent . As you can see, t he cal l t o close is usef ul her e
because you can cont r ol exact l y when t he message is t o be sent . (If you do not cal l
close, MESSAGE is cl osed-and t he message is sent -when t he pr ogr am t er minat es.)
Summary
Per l accesses f il es by means of f il e var iabl es. Fil e var iabl es ar e associat ed wit h f il es by
t he open st at ement .
Fil es can be opened in any of t hr ee modes: r ead mode, wr it e mode, and append mode. A f il e
opened in r ead mode cannot be wr it t en t o; a f il e opened in eit her of t he ot her modes
cannot be r ead. Opening a f il e in wr it e mode dest r oys t he exist ing cont ent s of t he f il e.
To r ead f r om an opened f il e, r ef er ence it using <name>, wher e name is a pl acehol der f or
t he name of t he f il e var iabl e associat ed wit h t he f il e. To wr it e t o a f il e, specif y it s f il e
var iabl e when cal l ing print.
Per l def ines t hr ee buil t -in f il e var iabl es:
G STDIN, which r epr esent s t he st andar d input f il e
G STDOUT, which r epr esent s t he st andar d out put f il e
G STDERR, which r epr esent s t he st andar d er r or f il e
You can r edir ect STDIN and STDOUT by specif ying < and >, r espect ivel y, on t he command
l ine. Messages sent t o STDERR appear on t he scr een even if STDOUT is r edir ect ed t o a f il e.
The close f unct ion cl oses t he f il e associat ed wit h a par t icul ar f il e var iabl e. close
never needs t o be cal l ed unl ess you want t o cont r ol exact l y when a f il e is t o be made
inaccessibl e.
The f il e-t est oper at or s pr ovide a way of r et r ieving inf or mat ion on a par t icul ar f il e. The
most common f il e-t est oper at or s ar e
G -e, which t est s whet her a f il e exist s
G -r, -w, and -x, which t est whet her a f il e has r ead, wr it e, and execut e per mission,
r espect ivel y
G -z, which t est s whet her a f il e is empt y
G -s, which r et ur ns t he size of a f il e
You can use -w and -z t o ensur e t hat you do not over wr it e a non-empt y f il e.
The <> oper at or enabl es you t o r ead dat a f r om f il es specif ied on t he command l ine. This
oper at or uses t he buil t -in ar r ay var iabl e @ARGV, whose el ement s consist of t he it ems
specif ied on t he command l ine.
Per l enabl es you t o open pipes. A pipe l inks t he out put f r om your Per l pr ogr am t o t he
input t o anot her pr ogr am.
Q&A
Q: How many f il es can I have open at one t ime?
A: Basical l y, as many as you l ike. The act ual l imit depends on t he l imit at ions of
your oper at ing syst em.
Q: Why does adding a cl osing newl ine char act er t o t he t ext st r ing af f ect how
die behaves?
A: Per l enabl es you t o choose whet her you want t he f il ename and l ine number of
t he er r or message t o appear . If you add a cl osing newl ine char act er t o t he
st r ing, t he Per l int er pr et er assumes t hat you want t o cont r ol how your er r or
message is t o appear .
Q: Which is bet t er : t o use <>, or t o use @ARGV and shift when appr opr iat e?
A: As is of t en t he case, t he answer is "It depends." If your pr ogr am t r eat s al most al l
of t he command-l ine ar gument s as f il es, it is bet t er t o use <> because t he
mechanics of opening and cl osing f il es ar e t aken car e of f or you. If you ar e doing
a l ot of unusual t hings wit h @ARGV, it is bet t er not t o manipul at e it t o use <>,
because t hings can get compl icat ed and conf using.
Q: Can I open mor e t han one pipe at a t ime?
A: Yes. Your oper at ing syst em keeps al l of t he var ious commands and pr ocesses
or ganized and keeps t r ack of which out put goes wit h which input .
Q: Can I r edir ect STDERR?
A: Yes, but t her e is (nor mal l y) no r eason why you shoul d. STDERR's job is t o r epor t
ext r aor dinar y condit ions, and you usual l y want t o see t hese, not have t hem
bur ied in a f il e somewher e.
Q: How many command-l ine ar gument s can I specif y?
A: Basical l y, as many as your command-l ine shel l can handl e.
Q: Can I wr it e t o a f il e and t hen r ead f r om it l at er ?
A: Yes, but you can't do bot h at t he same t ime. To r ead f r om a f il e you have wr it t en
t o, cl ose t he f il e by cal l ing close and t hen open t he f il e in r ead mode.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. Def ine t he f ol l owing t er ms:
a. f il e var iabl e
b. r eser ved wor d
c. f il e mode
d. append mode
e. pipe
2. Fr om wher e does t he <> oper at or r ead it s dat a?
3. What do t he f ol l owing f il e-t est oper at or s do?
a. -r
b. -x
c. -s
4. What ar e t he cont ent s of t he ar r ay @ARGV when t he f ol l owing Per l pr ogr am is
execut ed?
$ myprog file1 file2 file3
5. How do you indicat e t hat a f il e is t o be opened:
a. In wr it e mode?
b. In append mode?
c. In r ead mode?
d. As a pipe?
6. What is t he r el at ionship bet ween @ARGV and t he <> oper at or ?
Exercises
1. Wr it e a pr ogr am t hat t akes t he val ues on t he command l ine, adds t hem t oget her ,
and pr int s t he r esul t .
2. Wr it e a pr ogr am t hat t akes a l ist of f il es f r om t he command l ine and examines
t heir size. If a f il e is bigger t han 10,000 byt es, pr int
File name is a big file!
wher e name is a pl acehol der f or t he name of t he big f il e.
3. Wr it e a pr ogr am t hat copies a f il e named file1 t o file2, and t hen appends anot her
copy of file1 t o file2.
4. Wr it e a pr ogr am t hat count s t he t ot al number of wor ds in t he f il es specif ied on
t he command l ine. When it has count ed t he wor ds, it sends a message t o user ID
dave indicat ing t he t ot al number of wor ds.
5. Wr it e a pr ogr am t hat t akes a l ist of f il es and indicat es, f or each f il e, whet her t he
user has r ead, wr it e, or execut e per mission.
6. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
open (OUTFILE, "outfile");
print OUTFILE ("This is my message\n");

Chapter 7
Pattern Matching
CONTENTS
G Int r oduct ion
G The Mat ch Oper at or s
H Mat ch-Oper at or Pr ecedence
G Special Char act er s in Pat t er ns
H The + Char act er
H The [] Special Char act er s
H The * and ? Special Char act er s
H Escape Sequences f or Special Char act er s
H Mat ching Any Let t er or Number
H Anchor ing Pat t er ns
H Var iabl e Subst it ut ion in Pat t er ns
H Excl uding Al t er nat ives
H Char act er -Range Escape Sequences
H Mat ching Any Char act er
H Mat ching a Specif ied Number of Occur r ences
H Specif ying Choices
H Reusing Por t ions of Pat t er ns
H Pat t er n-Sequence Scal ar Var iabl es
H Special -Char act er Pr ecedence
H Specif ying a Dif f er ent Pat t er n Del imit er
G Pat t er n-Mat ching Opt ions
H Mat ching Al l Possibl e Pat t er ns
H Ignor ing Case
H Tr eat ing t he St r ing as Mul t ipl e Lines
H Eval uat ing a Pat t er n Onl y Once
H Tr eat ing t he St r ing as a Singl e Line
H Using Whit e Space in Pat t er ns
G The Subst it ut ion Oper at or
H Using Pat t er n-Sequence Var iabl es in Subst it ut ions
H Opt ions f or t he Subst it ut ion Oper at or
H Eval uat ing a Pat t er n Onl y Once
H Tr eat ing t he St r ing as Singl e or Mul t ipl e Lines
H Using Whit e Space in Pat t er ns
H Specif ying a Dif f er ent Del imit er
G The Tr ansl at ion Oper at or
H Opt ions f or t he Tr ansl at ion Oper at or
G Ext ended Pat t er n-Mat ching
H Par ent hesizing Wit hout Saving in Memor y
H Embedding Pat t er n Opt ions
H Posit ive and Negat ive Look-Ahead
H Pat t er n Comment s
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
This l esson descr ibes t he pat t er n-mat ching f eat ur es of Per l . Today, you l ear n about t he
f ol l owing:
G How pat t er n mat ching wor ks
G The pat t er n-mat ching oper at or s
G Special char act er s suppor t ed in pat t er n mat ching
G Pat t er n-mat ching opt ions
G Pat t er n subst it ut ion
G Tr ansl at ion
G Ext ended pat t er n-mat ching f eat ur es
Introduction
A pattern is a sequence of char act er s t o be sear ched f or in a char act er st r ing. In Per l ,
pat t er ns ar e nor mal l y encl osed in sl ash char act er s:
/def/
This r epr esent s t he pat t er n def.
If t he pat t er n is f ound, a mat ch occur s. For exampl e, if you sear ch t he st r ing redefine
f or t he pat t er n /def/, t he pat t er n mat ches t he t hir d, f our t h, and f if t h char act er s.
redefine
You al r eady have seen a simpl e exampl e of pat t er n mat ching in t he l ibr ar y f unct ion
split.
@array = split(/ /, $line);
Her e t he pat t er n / / mat ches a singl e space, which spl it s a l ine int o wor ds.
The Match Operators
Per l def ines special oper at or s t hat t est whet her a par t icul ar pat t er n appear s in a
char act er st r ing.
The =~ oper at or t est s whet her a pat t er n is mat ched, as shown in t he f ol l owing:
$result = $var =~ /abc/;
The r esul t of t he =~ oper at ion is one of t he f ol l owing:
G A nonzer o val ue, or t r ue, if t he pat t er n is f ound in t he st r ing
G 0, or f al se, if t he pat t er n is not mat ched
In t his exampl e, t he val ue st or ed in t he scal ar var iabl e $var is sear ched f or t he pat t er n
abc. If abc is f ound, $result is assigned a nonzer o val ue; ot her wise, $result is set t o
zer o.
The !~ oper at or is simil ar t o =~, except t hat it checks whet her a pat t er n is not mat ched.
$result = $var !~ /abc/;
Her e, $result is set t o 0 if abc appear s in t he st r ing assigned t o $var, and t o a nonzer o
val ue if abc is not f ound.
Because =~ and !~ pr oduce eit her t r ue or f al se as t heir r esul t , t hese oper at or s ar e
ideal l y suit ed f or use in condit ional expr essions. List ing 7.1 is a simpl e pr ogr am t hat uses
t he =~ oper at or t o t est whet her a par t icul ar sequence of char act er s exist s in a
char act er st r ing.

List ing 7.1. A pr ogr am t hat il l ust r at es t he use of t he mat ching
oper at or .
1: #!/usr/local/bin/perl
2:
3: print ("Ask me a question politely:\n");
4: $question = <STDIN>;
5: if ($question =~ /please/) {
6: print ("Thank you for being polite!\n");
7: } else {
8: print ("That was not very polite!\n");
9: }

$ program7_1
Ask me a question politely:
May I have a glass of water, please?
Thank you for being polite!
$
Line 5 is an exampl e of t he use of t he mat ch oper at or =~ in a condit ional
expr ession. The f ol l owing expr ession is t r ue if t he val ue st or ed in $question cont ains
t he wor d please, and it is f al se if it does not :
$question =~ /please/
Match-Operator Precedence
Like al l oper at or s, t he mat ch oper at or s have a def ined pr ecedence. By def init ion, t he =~
and !~ oper at or s have higher pr ecedence t han mul t ipl icat ion and division, and l ower
pr ecedence t han t he exponent iat ion oper at or **.
For a compl et e l ist of Per l oper at or s and t heir pr ecedence, see Day 4, "Mor e Oper at or s."
Special Characters in Patterns
Per l suppor t s a var iet y of special char act er s inside pat t er ns, which enabl es you t o
mat ch any of a number of char act er st r ings. These special char act er s ar e what make
pat t er ns usef ul .
The + Character
The special char act er + means "one or mor e of t he pr eceding char act er s." For exampl e,
t he pat t er n /de+f/ mat ches any of t he f ol l owing:
def
deef
deeef
deeeeeeef
NOTE
Pat t er ns cont aining + al ways t r y t o mat ch as many
char act er s as possibl e. For exampl e, if t he pat t er n
/ab+/
is sear ching in t he st r ing
abbc
it mat ches abb, not ab.
The + special char act er makes it possibl e t o def ine a bet t er way t o spl it l ines int o wor ds.
So f ar , t he sampl e pr ogr ams you have seen have used
@words = split (/ /, $line);
t o br eak an input l ine int o wor ds. This wor ks wel l if t her e is exact l y one space bet ween
wor ds. However , if an input l ine cont ains mor e t han one space bet ween wor ds, as in
Here's multiple spaces.
t he cal l t o split pr oduces t he f ol l owing l ist :
("Here's", "", "multiple", "", "spaces.")
The pat t er n / / t el l s split t o st ar t a new wor d whenever it sees a space. Because t her e
ar e t wo spaces bet ween each wor d, split st ar t s a wor d when it sees t he f ir st space, and
t hen st ar t s anot her wor d when it sees t he second space. This means t hat t her e ar e now
"empt y wor ds" in t he l ine.
The + special char act er get s ar ound t his pr obl em. Suppose t he cal l t o split is changed
t o t his:
@array = split (/ +/, $line);
Because t he pat t er n / +/ t r ies t o mat ch as many bl ank char act er s as possibl e, t he l ine
Here's multiple spaces.
pr oduces t he f ol l owing l ist :
("Here's", "multiple", "spaces")
List ing 7.2 shows how you can use t he / +/ pat t er n t o pr oduce a count of t he number of
wor ds in a f il e.

List ing 7.2. A wor d-count pr ogr am t hat handl es mul t ipl e spaces
bet ween wor ds.
1: #!/usr/local/bin/perl
2:
3: $wordcount = 0;
4: $line = <STDIN>;
5: while ($line ne "") {
6: chop ($line);
7: @words = split(/ +/, $line);
8: $wordcount += @words;
9: $line = <STDIN>;
10: }
11: print ("Total number of words: $wordcount\n");

$ program7_2
Here is some input.
Here are some more words.
Here is my last line.
^D
Total number of words: 14
$
This is t he same wor d-count pr ogr am you saw in List ing 5.15, wit h onl y one
change: The pat t er n / +/ is being used t o br eak t he l ine int o wor ds. As you can see, t his
handl es spaces bet ween wor ds pr oper l y.
You might have not iced t he f ol l owing pr obl ems wit h t his wor d-count pr ogr am:
G Spaces at t he beginning of a l ine ar e count ed as a wor d, because split al ways
st ar t s a new wor d when it sees a space.
G Tab char act er s ar e count ed as a wor d.
For an exampl e of t he f ir st pr obl em, t ake a l ook at t he f ol l owing input l ine:
This line contains leading spaces.
The cal l t o split in l ine 7 br eaks t he pr eceding int o t he f ol l owing l ist :
("", "This", "line", "contains", "leading", "spaces")
This yiel ds a wor d count of 6, not t he expect ed 5.
Ther e can be at most one empt y wor d pr oduced f r om a l ine, no mat t er how many l eading
spaces t her e ar e, because t he pat t er n / +/ mat ches as many spaces as possibl e. Not e al so
t hat t he pr ogr am can dist inguish bet ween l ines cont aining wor ds and l ines t hat ar e
bl ank or cont ain just spaces. If a l ine is bl ank or cont ains onl y spaces, t he l ine
@words = split(/ +/, $line);
assigns t he empt y l ist t o @words. Because of t his, you can f ix t he pr obl em of l eading
spaces in l ines by modif ying l ine 8 as f ol l ows:
$wordcount += (@words > 0 && $words[0] eq "" ?
@words-1 : @words);
This checks f or l ines cont aining l eading spaces; if a l ine cont ains l eading spaces, t he
f ir st "wor d" (which is t he empt y st r ing) is not added t o t he wor d count .
To f ind out how t o modif y t he pr ogr am t o deal wit h t ab char act er s as wel l as spaces, see
t he f ol l owing sect ion.
The [] Special Characters
The [] special char act er s enabl e you t o def ine pat t er ns t hat mat ch one of a gr oup of
al t er nat ives. For exampl e, t he f ol l owing pat t er n mat ches def or dEf:
/d[eE]f/
You can specif y as many al t er nat ives as you l ike.
/a[0123456789]c/
This mat ches a, f ol l owed by any digit , f ol l owed by c.
You can combine [] wit h + t o mat ch a sequence of char act er s of any l engt h.
/d[eE]+f/
This mat ches al l of t he f ol l owing:
def
dEf
deef
dEef
dEEEeeeEef
Any combinat ion of E and e, in any or der , is mat ched by [eE]+.
You can use [] and + t oget her t o modif y t he wor d-count pr ogr am you've just seen t o
accept eit her t ab char act er s or spaces. List ing 7.3 shows how you can do t his.

List ing 7.3. A wor d-count pr ogr am t hat handl es mul t ipl e spaces and
t abs bet ween wor ds.
1: #!/usr/local/bin/perl
2:
3: $wordcount = 0;
4: $line = <STDIN>;
5: while ($line ne "") {
6: chop ($line);
7: @words = split(/[\t ]+/, $line);
8: $wordcount += @words;
9: $line = <STDIN>;
10: }
11: print ("Total number of words: $wordcount\n");

$ program7_3
Here is some input.
Here are some more words.
Here is my last line.
^D
Total number of words: 14
$
This pr ogr am is ident ical t o List ing 7.2, except t hat t he pat t er n is now /[\t
]+/.
The \t special -char act er sequence r epr esent s t he t ab char act er , and t his pat t er n
mat ches any combinat ion or quant it y of spaces and t abs.
NOTE
Any escape sequence t hat is suppor t ed in doubl e-quot ed
st r ings is suppor t ed in pat t er ns. See Day 3,
"Under st anding Scal ar Val ues," f or a l ist of t he escape
sequences t hat ar e avail abl e.
The * and ? Special Characters
As you have seen, t he + char act er mat ches one or mor e occur r ences of a char act er . Per l
al so def ines t wo ot her special char act er s t hat mat ch a var ying number of char act er s: *
and ?.
The * special char act er mat ches zer o or mor e occur r ences of t he pr eceding char act er .
For exampl e, t he pat t er n
/de*f/
mat ches df, def, deef, and so on.
This char act er can al so be used wit h t he [] special char act er .
/[eE]*/
This mat ches t he empt y st r ing as wel l as any combinat ion of E or e in any or der .
Be sur e not t o conf use t he * special char act er wit h t he
+ special char act er . If you use t he wr ong special
char act er , you might not get t he r esul t s t hat you want .
For exampl e, suppose t hat you modif y List ing 7.3 t o cal l
split as f ol l ows:
@words = split (/[\t ]*/, $list);
This mat ches zer o or mor e occur r ences of t he space or
t ab char act er . When you r un t his wit h t he input
a line
her e's t he l ist t hat is assigned t o @words:
("a", "l", "i", "n", "e")
Because t he pat t er n /[\t ]*/ mat ches on zer o
occur r ences of t he space or t ab char act er , it mat ches
af t er ever y char act er . This means t hat split st ar t s a
wor d af t er ever y char act er t hat is not a space or t ab. (It
skips spaces and t abs because /[\t ]*/ mat ches t hem.)
The best way t o avoid pr obl ems such as t his one is t o use
t he * special char act er onl y when t her e is anot her
char act er appear ing in t he pat t er n. Pat t er ns such as
/b*[c]/
never mat ch t he nul l st r ing, because t he mat ched
sequence has t o cont ain at l east t he char act er c.
The ? char act er mat ches zer o or one occur r ence of t he pr eceding char act er . For
exampl e, t he pat t er n
/de?f/
mat ches eit her df or def. Not e t hat it does not mat ch deef, because t he ? char act er does
not mat ch t wo occur r ences of a char act er .
Escape Sequences for Special Characters
If you want your pat t er n t o incl ude a char act er t hat is nor mal l y t r eat ed as a special
char act er , pr ecede t he char act er wit h a backsl ash \. For exampl e, t o check f or one or
mor e occur r ences of * in a st r ing, use t he f ol l owing pat t er n:
/\*+/
The backsl ash pr eceding t he * t el l s t he Per l int er pr et er t o t r eat t he * as an or dinar y
char act er , not as t he special char act er meaning "zer o or mor e occur r ences."
To incl ude a backsl ash in a pat t er n, specif y t wo backsl ashes:
/\\+/
This pat t er n t est s f or one or mor e occur r ences of \ in a st r ing.
If you ar e r unning Per l 5, anot her way t o t el l Per l t hat a special char act er is t o be
t r eat ed as a nor mal char act er is t o pr ecede it wit h t he \Q escape sequence. When t he
Per l int er pr et er sees \Q, ever y char act er f ol l owing t he \Q is t r eat ed as a nor mal
char act er unt il \E is seen. This means t hat t he pat t er n
/\Q^ab*/
mat ches any occur r ence of t he st r ing ^ab*, and t he pat t er n
/\Q^ab\E*/
mat ches ^a f ol l owed by zer o or mor e occur r ences of b.
For a compl et e l ist of special char act er s in pat t er ns t hat r equir e \ t o be given t heir
nat ur al meaning, see t he sect ion t it l ed "Special -Char act er Pr ecedence," which cont ains
a t abl e t hat l ist s t hem.
TIP
In Per l , any char act er t hat is not a l et t er or a digit can
be pr eceded by a backsl ash. If t he char act er isn't a
special char act er in Per l , t he backsl ash is ignor ed.
If you ar e not sur e whet her a par t icul ar char act er is a
special char act er , pr eceding it wit h a backsl ash wil l
ensur e t hat your pat t er n behaves t he way you want it
t o.
Matching Any Letter or Number
As you have seen, t he pat t er n
/a[0123456789]c/
mat ches a, f ol l owed by any digit , f ol l owed by c. Anot her way of wr it ing t his is as
f ol l ows:
/a[0-9]c/
Her e, t he r ange [0-9] r epr esent s any digit bet ween 0 and 9. This pat t er n mat ches a0c,
a1c, a2c, and so on up t o a9c.
Simil ar l y, t he r ange [a-z] mat ches any l ower case l et t er , and t he r ange [A-Z] mat ches
any upper case l et t er . For exampl e, t he pat t er n
/[A-Z][A-Z]/
mat ches any t wo upper case l et t er s.
To mat ch any upper case l et t er , l ower case l et t er , or digit , use t he f ol l owing r ange:
/[0-9a-zA-Z]/
List ing 7.4 pr ovides an exampl e of t he use of r anges wit h t he [] special char act er s. This
pr ogr am checks whet her a given input l ine cont ains a l egal Per l scal ar , ar r ay, or f il e-
var iabl e name. (Not e t hat t his pr ogr am handl es onl y simpl e input l ines. Lat er exampl es
wil l sol ve t his pr obl em in a bet t er way.)

List ing 7.4. A simpl e var iabl e-name val idat ion pr ogr am.
1: #!/usr/local/bin/perl
2:
3: print ("Enter a variable name:\n");
4: $varname = <STDIN>;
5: chop ($varname);
6: if ($varname =~ /\$[A-Za-z][_0-9a-zA-Z]*/) {
7: print ("$varname is a legal scalar variable\n");
8: } elsif ($varname =~ /@[A-Za-z][_0-9a-zA-Z]*/) {
9: print ("$varname is a legal array variable\n");
10: } elsif ($varname =~ /[A-Za-z][_0-9a-zA-Z]*/) {
11: print ("$varname is a legal file variable\n");
12: } else {
13: print ("I don't understand what $varname is.\n");
14: }

$ program7_4
Enter a variable name:
$result
$result is a legal scalar variable
$
Line 6 checks whet her t he input l ine cont ains t he name of a l egal scal ar
var iabl e. Recal l t hat a l egal scal ar var iabl e consist s of t he f ol l owing:
G A $ char act er
G An upper case or l ower case l et t er
G Zer o or mor e l et t er s, digit s, or under scor e char act er s
Each par t of t he pat t er n t est ed in l ine 6 cor r esponds t o one of t he af or ement ioned
condit ions given. The f ir st par t of t he pat t er n, \$, ensur es t hat t he pat t er n mat ches
onl y if it begins wit h a $ char act er .
NOTE
The $ is pr eceded by a backsl ash, because $ is a special
char act er in pat t er ns. See t he f ol l owing sect ion,
"Anchor ing Pat t er ns," f or mor e inf or mat ion on t he $
special char act er .
The second par t of t he pat t er n,
[A-Za-z]
mat ches exact l y one upper case or l ower case l et t er . The f inal par t of t he pat t er n,
[_0-9a-zA-Z]*
mat ches zer o or mor e under scor es, digit s, or l et t er s in any or der .
The pat t er ns in l ine 8 and l ine 10 ar e ver y simil ar t o t he one in l ine 6. The onl y
dif f er ence in l ine 8 is t hat t he pat t er n t her e mat ches a st r ing whose f ir st char act er is @,
not $. In l ine 10, t his f ir st char act er is omit t ed compl et el y.
The pat t er n in l ine 8 cor r esponds t o t he def init ion of a l egal ar r ay-var iabl e name, and
t he pat t er n in l ine 10 cor r esponds t o t he def init ion of a l egal f il e-var iabl e name.
Anchoring Patterns
Al t hough List ing 7.4 can det er mine whet her a l ine of input cont ains a l egal Per l
var iabl e name, it cannot det er mine whet her t her e is ext r aneous input on t he l ine. For
exampl e, it can't t el l t he dif f er ence bet ween t he f ol l owing t hr ee l ines of input :
$result
junk$result
$result#junk
In al l t hr ee cases, t he pat t er n
/\$[a-zA-Z][_0-9a-zA-Z]*/
f inds t he st r ing $result and mat ches successf ul l y; however , onl y t he f ir st l ine is a
l egal Per l var iabl e name.
To f ix t his pr obl em, you can use pattern anchors. Tabl e 7.1 l ist s t he pat t er n anchor s
def ined in Per l .
Tabl e 7.1. Pat t er n anchor s in Per l .
Anchor Descr ipt ion
^ or \A Mat ch at beginning of st r ing
onl y
$ or \Z Mat ch at end of st r ing onl y
\b
Mat ch on wor d boundar y
\B
Mat ch inside wor d
These pat t er n anchor s ar e descr ibed in t he f ol l owing sect ions.
The ^ and $ Pattern Anchors
The pat t er n anchor s ^ and $ ensur e t hat t he pat t er n is mat ched onl y at t he beginning
or t he end of a st r ing. For exampl e, t he pat t er n
/^def/
mat ches def onl y if t hese ar e t he f ir st t hr ee char act er s in t he st r ing. Simil ar l y, t he
pat t er n
/def$/
mat ches def onl y if t hese ar e t he l ast t hr ee char act er s in t he st r ing.
You can combine ^ and $ t o f or ce mat ching of t he ent ir e st r ing, as f ol l ows:
/^def$/
This mat ches onl y if t he st r ing is def.
In most cases, t he escape sequences \A and \Z (def ined in Per l 5) ar e equival ent t o ^ and
$, r espect ivel y:
/\Adef\Z/
This al so mat ches onl y if t he st r ing is def.
NOTE
\A and \Z behave dif f er ent l y f r om ^ and $ when t he
mul t ipl e-l ine pat t er n-mat ching opt ion is specif ied.
Pat t er n-mat ching opt ions ar e descr ibed l at er t oday.
List ing 7.5 shows how you can use pat t er n anchor s t o ensur e t hat a l ine of input is, in
f act , a l egal Per l scal ar -, ar r ay-, or f il e-var iabl e name.

List ing 7.5. A bet t er var iabl e-name val idat ion pr ogr am.
1: #!/usr/local/bin/perl
2:
3: print ("Enter a variable name:\n");
4: $varname = <STDIN>;
5: chop ($varname);
6: if ($varname =~ /^\$[A-Za-z][_0-9a-zA-Z]*$/) {
7: print ("$varname is a legal scalar variable\n");
8: } elsif ($varname =~ /^@[A-Za-z][_0-9a-zA-Z]*$/) {
9: print ("$varname is a legal array variable\n");
10: } elsif ($varname =~ /^[A-Za-z][_0-9a-zA-Z]*$/) {
11: print ("$varname is a legal file variable\n");
12: } else {
13: print ("I don't understand what $varname is.\n");
14: }

$ program7_5
Enter a variable name:
x$result
I don't understand what x$result is.
$
The onl y dif f er ence bet ween t his pr ogr am and t he one in List ing 7.4 is t hat
t his pr ogr am uses t he pat t er n anchor s ^ and $ in t he pat t er ns in l ines 6, 8, and 10. These
anchor s ensur e t hat a val id pat t er n consist s of onl y t hose char act er s t hat make up a
l egal Per l scal ar , ar r ay, or f il e var iabl e.
In t he sampl e out put given her e, t he input
x$result
is r eject ed, because t he pat t er n in l ine 6 is mat ched onl y when t he $ char act er appear s
at t he beginning of t he l ine.
Word-Boundary Pattern Anchors
The wor d-boundar y pat t er n anchor s, \b and \B, specif y whet her a mat ched pat t er n must
be on a wor d boundar y or inside a wor d boundar y. (A wor d boundar y is t he beginning or
end of a wor d.)
The \b pat t er n anchor specif ies t hat t he pat t er n must be on a wor d boundar y. For
exampl e, t he pat t er n
/\bdef/
mat ches onl y if def is t he beginning of a wor d. This means t hat def and defghi mat ch
but abcdef does not .
You can al so use \b t o indicat e t he end of a wor d. For exampl e,
/def\b/
mat ches def and abcdef, but not defghi. Final l y, t he pat t er n
/\bdef\b/
mat ches onl y t he wor d def, not abcdef or defghi.
NOTE
A wor d is assumed t o cont ain l et t er s, digit s, and
under scor e char act er s, and not hing el se. This means
t hat
/\bdef/
mat ches $defghi: because $ is not assumed t o be par t of a
wor d, def is t he beginning of t he wor d defghi, and
/\bdef/ mat ches it .
The \B pat t er n anchor is t he opposit e of \b. \B mat ches onl y if t he pat t er n is cont ained
in a wor d. For exampl e, t he pat t er n
/\Bdef/
mat ches abcdef, but not def. Simil ar l y, t he pat t er n
/def\B/
mat ches defghi, and
/\Bdef\B/
mat ches cdefg or abcdefghi, but not def, defghi, or abcdef.
The \b and \B pat t er n anchor s enabl e you t o sear ch f or wor ds in an input l ine wit hout
having t o br eak up t he l ine using split. For exampl e, List ing 7.6 uses \b t o count t he
number of l ines of an input f il e t hat cont ain t he wor d the.

List ing 7.6. A pr ogr am t hat count s t he number of input l ines cont aining
t he wor d the.
1: #!/usr/local/bin/perl
2:
3: $thecount = 0;
4: print ("Enter the input here:\n");
5: $line = <STDIN>;
6: while ($line ne "") {
7: if ($line =~ /\bthe\b/) {
8: $thecount += 1;
9: }
10: $line = <STDIN>;
11: }
12: print ("Number of lines containing 'the': $thecount\n");

$ program7_6
Enter the input here:
Now is the time
for all good men
to come to the aid
of the party.
^D
Number of lines containing 'the': 3
$
This pr ogr am checks each l ine in t ur n t o see if it cont ains t he wor d the, and
t hen pr int s t he t ot al number of l ines t hat cont ain t he wor d.
Line 7 per f or ms t he act ual checking by t r ying t o mat ch t he pat t er n
/\bthe\b/
If t his pat t er n mat ches, t he l ine cont ains t he wor d the, because t he pat t er n checks f or
wor d boundar ies at eit her end.
Not e t hat t his pr ogr am doesn't check whet her t he wor d the appear s on a l ine mor e t han
once. It is not dif f icul t t o modif y t he pr ogr am t o do t his; in f act , you can do it in sever al
dif f er ent ways.
The most obvious but most l abor ious way is t o br eak up l ines t hat you know cont ain the
int o wor ds, and t hen check each wor d, as f ol l ows:
if ($line =~ /\bthe\b/) {
@words = split(/[\t ]+/, $line);
$count = 1;
while ($count <= @words) {
if ($words[$count-1] eq "the") {
$thecount += 1;
}
$count++;
}
}
A cut e way t o accompl ish t he same t hing is t o use t he pat t er n it sel f t o br eak t he l ine
int o wor ds:
if ($line =~ /\bthe\b/) {
@words = split(/\bthe\b/, $line);
$thecount += @words - 1;
}
In f act , you don't even need t he if st at ement .
@words = split(/\bthe\b/, $line);
$thecount += @words - 1;
Her e's why t his wor ks: Ever y t ime split sees t he wor d the, it st ar t s a new wor d.
Ther ef or e, t he number of occur r ences of the is equal t o one l ess t han t he number of
el ement s in @words. If t her e ar e no occur r ences of the, @words has t he l engt h 1, and
$thecount is not changed.
This t r ick wor ks onl y if you know t hat t her e is at l east
one wor d on t he l ine.
Consider t he f ol l owing code, which t r ies t o use t he
af or ement ioned t r ick on a l ine t hat has had it s newl ine
char act er r emoved using chop:
$line = <STDIN>;
chop ($line);
@words = split(/\bthe\b/, $line);
$thecount += @words - 1;
This code act ual l y subt r act s 1 f r om $thecount if t he l ine
is bl ank or consist s onl y of t he wor d the, because in
t hese cases @words is t he empt y l ist and t he l engt h of
@words is 0.
Leaving of f t he cal l t o chop pr ot ect s against t his
pr obl em, because t her e wil l al ways be at l east one
"wor d" in ever y l ine (consist ing of t he newl ine
char act er ).
Variable Substitution in Patterns
If you l ike, you can use t he val ue of a scal ar var iabl e in a pat t er n. For exampl e, t he
f ol l owing code spl it s t he l ine $line int o wor ds:
$pattern = "[\\t ]+";
@words = split(/$pattern/, $line);
Because you can use a scal ar var iabl e in a pat t er n, t her e is not hing t o st op you f r om
r eading t he pat t er n f r om t he st andar d input f il e. List ing 7.7 accept s a sear ch pat t er n
f r om a f il e and t hen sear ches f or t he pat t er n in t he input f il es l ist ed on t he command
l ine. If it f inds t he pat t er n, it pr int s t he f il ename and l ine number of t he mat ch; at t he
end, it pr int s t he t ot al number of mat ches.
This exampl e assumes t hat t wo f il es exist , file1 and file2. Each f il e cont ains t he
f ol l owing:
This is a line of input.
This is another line of input.
If you r un t his pr ogr am wit h command-l ine ar gument s file1 and file2 and sear ch f or
t he pat t er n another, you get t he out put shown.

List ing 7.7. A simpl e pat t er n-sear ch pr ogr am.
1: #!/usr/local/bin/perl
2:
3: print ("Enter the search pattern:\n");
4: $pattern = <STDIN>;
5: chop ($pattern);
6: $filename = $ARGV[0];
7: $linenum = $matchcount = 0;
8: print ("Matches found:\n");
9: while ($line = <>) {
10: $linenum += 1;
11: if ($line =~ /$pattern/) {
12: print ("$filename, line $linenum\n");
13: @words = split(/$pattern/, $line);
14: $matchcount += @words - 1;
15: }
16: if (eof) {
17: $linenum = 0;
18: $filename = $ARGV[0];
19: }
20: }
21: if ($matchcount == 0) {
22: print ("No matches found.\n");
23: } else {
24: print ("Total number of matches: $matchcount\n");
25: }

$ program7_7 file1 file2
Enter the search pattern:
another
Matches found:
file1, line 2
file2, line 2
Total number of matches: 2
$
This pr ogr am uses t he f ol l owing scal ar var iabl es t o keep t r ack of
inf or mat ion:
G $pattern cont ains t he sear ch pat t er n r ead in f r om t he st andar d input f il e.
G $filename cont ains t he f il e cur r ent l y being sear ched.
G $linenum cont ains t he l ine number of t he l ine cur r ent l y being sear ched.
G $matchcount cont ains t he t ot al number of mat ches f ound t o t his point .
Line 6 set s t he cur r ent f il ename, which cor r esponds t o t he f ir st el ement in t he buil t -in
ar r ay var iabl e @ARGV. This ar r ay var iabl e l ist s t he ar gument s suppl ied on t he command
l ine. (To r ef r esh your memor y on how @ARGV wor ks, r ef er back t o Day 6, "Reading f r om
and Wr it ing t o Fil es.") This cur r ent f il ename needs t o be st or ed in a scal ar var iabl e,
because t he <> oper at or in l ine 9 shif t s @ARGV and dest r oys t his name.
Line 9 r eads f r om each of t he f il es on t he command l ine in t ur n, one l ine at a t ime. The
cur r ent input l ine is st or ed in t he scal ar var iabl e $line. Once t he l ine is r ead, l ine 10
adds 1 t o t he cur r ent l ine number .
Lines 11-15 handl e t he mat ching pr ocess. Line 11 checks whet her t he pat t er n st or ed in
$pattern is cont ained in t he input l ine st or ed in $line. If a mat ch is f ound, l ine 12 pr int s
out t he cur r ent f il ename and l ine number . Line 13 t hen spl it s t he l ine int o "wor ds,"
using t he t r ick descr ibed in t he ear l ier sect ion, "Wor d-Boundar y Pat t er n Anchor s."
Because t he number of el ement s of t he l ist st or ed in @words is one l ar ger t han t he
number of t imes t he pat t er n is mat ched, t he expr ession @words - 1 is equival ent t o t he
number of mat ches; it s val ue is added t o $matchcount.
Line 16 checks whet her t he <> oper at or has r eached t he end of t he cur r ent input f il e. If
it has, l ine 17 r eset s t he cur r ent l ine number t o 0. This ensur es t hat t he next pass
t hr ough t he l oop wil l set t he cur r ent l ine number t o 1 (t o indicat e t hat t he pr ogr am is
on t he f ir st l ine of t he next f il e). Line 18 set s t he f il ename t o t he next f il e ment ioned
on t he command l ine, which is cur r ent l y st or ed in $ARGV[0].
Lines 21-25 eit her pr int t he t ot al number of mat ches or indicat e t hat no mat ches wer e
f ound.
NOTE
Make sur e t hat you r emember t o incl ude t he encl osing /
char act er s when you use a scal ar -var iabl e name in a
pat t er n. The Per l int er pr et er does not compl ain when it
sees t he f ol l owing, f or exampl e, but t he r esul t might
not be what you want :
@words = split($pattern, $line);
Excluding Alternatives
As you have seen, when t he special char act er s [] appear in a pat t er n, t hey specif y a set
of al t er nat ives t o choose f r om. For exampl e, t he pat t er n
/d[eE]f/
mat ches def or dEf.
When t he ^ char act er appear s as t he f ir st char act er af t er t he [, it indicat es t hat t he
pat t er n is t o mat ch any char act er except t he ones displ ayed bet ween t he [ and ]. For
exampl e, t he pat t er n
/d[^eE]f/
mat ches any pat t er n t hat sat isf ies t he f ol l owing cr it er ia:
G The f ir st char act er is d.
G The second char act er is anyt hing ot her t han e or E.
G The l ast char act er is f.
NOTE
To incl ude a ^ char act er in a set of al t er nat ives,
pr ecede it wit h a backsl ash, as f ol l ows:
/d[\^eE]f/
This pat t er n mat ches d^f, def, or dEf.
Character-Range Escape Sequences
In t he sect ion t it l ed "Mat ching Any Let t er or Number " ear l ier in t his chapt er , you
l ear ned t hat you can r epr esent consecut ive l et t er s or number s inside t he [] special
char act er s by specif ying r anges. For exampl e, in t he pat t er n
/a[1-3]c/
t he [1-3] mat ches any of 1, 2, or 3.
Some r anges occur f r equent l y enough t hat Per l def ines special escape sequences f or
t hem. For exampl e, inst ead of wr it ing
/[0-9]/
t o indicat e t hat any digit is t o be mat ched, you can wr it e
/\d/
The \d escape sequence means "any digit ."
Tabl e 7.2 l ist s t he char act er -r ange escape sequences, what t hey mat ch, and t heir
equival ent char act er r anges.
Tabl e 7.2. Char act er -r ange escape sequences.
Escape sequence Descr ipt ion Range
\d
Any digit
[0-9]
\D
Anyt hing ot her t han a digit
[^0-9]
\w
Any wor d char act er
[_0-9a-zA-Z]
\W
Anyt hing not a wor d
char act er
[^_0-9a-zA-Z]
\s
Whit e space [ \r \t \n\f ]
\S
Anyt hing ot her t han whit e
space
[^ \r\t\n\f]
These escape sequences can be used anywher e or dinar y char act er s ar e used. For exampl e,
t he f ol l owing pat t er n mat ches any digit or l ower case l et t er :
/[\da-z]/
NOTE
The def init ion of wor d boundar y as used by t he \b and \B
special char act er s cor r esponds t o t he def init ion of wor d
char act er used by \w and \W.
If t he pat t er n /\w\W/ mat ches a par t icul ar pair of
char act er s, t he f ir st char act er is par t of a wor d and t he
second is not ; t his means t hat t he f ir st char act er is t he
end of a wor d, and t hat a wor d boundar y exist s bet ween
t he f ir st and second char act er s mat ched by t he pat t er n.
Simil ar l y, if /\W\w/ mat ches a pair of char act er s, t he
f ir st char act er is not par t of a wor d and t he second
char act er is. This means t hat t he second char act er is t he
beginning of a wor d. Again, a wor d boundar y exist s
bet ween t he f ir st and second char act er s mat ched by t he
pat t er n.
Matching Any Character
Anot her special char act er suppor t ed in pat t er ns is t he per iod (.) char act er , which
mat ches any char act er except t he newl ine char act er . For exampl e, t he f ol l owing
pat t er n mat ches d, f ol l owed by any non-newl ine char act er , f ol l owed by f:
/d.f/
The . char act er is of t en used in conjunct ion wit h t he * char act er . For exampl e, t he
f ol l owing pat t er n mat ches any st r ing t hat cont ains t he char act er d pr eceding t he
char act er f:
/d.*f/
Nor mal l y, t he .* special -char act er combinat ion t r ies t o mat ch as much as possibl e. For
exampl e, if t he st r ing banana is sear ched using t he f ol l owing pat t er n, t he pat t er n
mat ches banana, not ba or bana:
/b.*a/
NOTE
Ther e is one except ion t o t he pr eceding r ul e: The .*
char act er onl y mat ches t he l ongest possibl e st r ing t hat
enabl es t he pat t er n mat ch as a whol e t o succeed.
For exampl e, suppose t he st r ing Mississippi is sear ched
using t he pat t er n
/M.*i.*pi/
Her e, t he f ir st .* in /M.*i.*pi/ mat ches
Mississippi
If it t r ied t o go f ur t her and mat ch
Mississippi
or even
Mississippi
t her e woul d be not hing l ef t f or t he r est of t he pat t er n
t o mat ch.
When t he f ir st .* mat ch is l imit ed t o
Mississippi
t he r est of t he pat t er n, i.*pi, mat ches ippi, and t he
pat t er n as a whol e succeeds.
Matching a Specified Number of Occurrences
Sever al special char act er s in pat t er ns t hat you have seen enabl e you t o mat ch a
specif ied number of occur r ences of a char act er . For exampl e, + mat ches one or mor e
occur r ences of a char act er , and ? mat ches zer o or one occur r ences.
Per l enabl es you t o def ine how many occur r ences of a char act er const it ut e a mat ch. To
do t his, use t he special char act er s { and }.
For exampl e, t he pat t er n
/de{1,3}f/
mat ches d, f ol l owed by one, t wo, or t hr ee occur r ences of e, f ol l owed by f. This means
t hat def, deef, and deeef mat ch, but df and deeeef do not .
To specif y an exact number of occur r ences, incl ude onl y one val ue bet ween t he { and
t he }.
/de{3}f/
This specif ies exact l y t hr ee occur r ences of e, which means t his pat t er n onl y mat ches
deeef.
To specif y a minimum number of occur r ences, l eave of f t he upper bound.
/de{3,}f/
This mat ches d, f ol l owed by at l east t hr ee es, f ol l owed by f.
Final l y, t o specif y a maximum number of occur r ences, use 0 as t he l ower bound.
/de{0,3}f/
This mat ches d, f ol l owed by no mor e t han t hr ee es, f ol l owed by f.
NOTE
You can use { and } wit h char act er r anges or any ot her
special char act er , as f ol l ows:
/[a-z]{1,3}/
This mat ches one, t wo, or t hr ee l ower case l et t er s.
/.{3}/
This mat ches any t hr ee char act er s.
Specifying Choices
The special char act er | enabl es you t o specif y t wo or mor e al t er nat ives t o choose f r om
when mat ching a pat t er n. For exampl e, t he pat t er n
/def|ghi/
mat ches eit her def or ghi. The pat t er n
/[a-z]+|[0-9]+/
mat ches one or mor e l ower case l et t er s or one or mor e digit s.
List ing 7.8 is a simpl e exampl e of a pr ogr am t hat uses t he | special char act er . It r eads a
number and checks whet her it is a l egit imat e Per l int eger .

List ing 7.8. A simpl e int eger -val idat ion pr ogr am.
1: #!/usr/local/bin/perl
2:
3: print ("Enter a number:\n");
4: $number = <STDIN>;
5: chop ($number);
6: if ($number =~ /^-?\d+$|^-?0[xX][\da-fa-F]+$/) {
7: print ("$number is a legal integer.\n");
8: } else {
9: print ("$number is not a legal integer.\n");
10: }

$ program7_8
Enter a number:
0x3ff1
0x3ff1 is a legal integer.
$
Recal l t hat Per l int eger s can be in any of t hr ee f or ms:
G St andar d base-10 not at ion, as in 123
G Base-8 (oct al ) not at ion, indicat ed by a l eading 0, as in 0123
G Base-16 (hexadecimal ) not at ion, indicat ed by a l eading 0x or 0X, as in 0X1ff
Line 6 checks whet her a number is a l egal Per l int eger . The f ir st al t er nat ive in t he
pat t er n,
^-?\d+$
mat ches a st r ing consist ing of one or mor e digit s, opt ional l y pr eceded by a -. (The ^ and $
char act er s ensur e t hat t his is t he onl y st r ing t hat mat ches.) This t akes car e of int eger s
in st andar d base-10 not at ion and int eger s in oct al not at ion.
The second al t er nat ive in t he pat t er n,
^-?0[xX][\da-fa-F]+$
mat ches int eger s in hexadecimal not at ion. Take a l ook at t his pat t er n one piece at a
t ime:
G The ^ mat ches t he beginning of t he l ine. This ensur es t hat l ines cont aining
l eading spaces or ext r aneous char act er s ar e not t r eat ed as val id hexadecimal
int eger s.
G The -? mat ches a - if it is pr esent . This ensur es t hat negat ive number s ar e mat ched.
G The 0 mat ches t he l eading 0.
G The [xX] mat ches t he x or X t hat f ol l ows t he l eading 0.
G The [\da-fa-F] mat ches any digit , any l et t er bet ween a and f, or any l et t er
bet ween A and F. Recal l t hat t hese ar e pr ecisel y t he char act er s which ar e
al l owed t o appear in hexadecimal digit s.
G The + indicat es t hat t he pat t er n is t o mat ch one or mor e hexadecimal digit s.
G The cl osing $ indicat es t hat t he pat t er n is t o mat ch onl y if t her e ar e no
ext r aneous char act er s f ol l owing t he hexadecimal int eger .
Bewar e t hat t he f ol l owing pat t er n mat ches eit her x or
one or mor e of y, not one or mor e of x or y:
/x|y+/
See t he sect ion cal l ed "Special -Char act er Pr ecedence"
l at er t oday f or det ail s on how t o specif y special -
char act er pr ecedence in pat t er ns.
Reusing Portions of Patterns
Suppose t hat you want t o wr it e a pat t er n t hat mat ches t he f ol l owing:
G One or mor e digit s or l ower case l et t er s
G Fol l owed by a col on or semicol on
G Fol l owed by anot her gr oup of one or mor e digit s or l ower case l et t er s
G Anot her col on or semicol on
G Yet anot her gr oup of one or mor e digit s or l ower case l et t er s
One way t o indicat e t his pat t er n is as f ol l ows:
/[\da-z]+[:;][\da-z]+[:;][\da-z]+/
This pat t er n is somewhat compl icat ed and is quit e r epet it ive.
Per l pr ovides an easier way t o specif y pat t er ns t hat cont ain mul t ipl e r epet it ions of a
par t icul ar sequence. When you encl ose a por t ion of a pat t er n in par ent heses, as in
([\da-z]+)
Per l st or es t he mat ched sequence in memor y. To r et r ieve a sequence f r om memor y, use
t he special char act er \n, wher e n is an int eger r epr esent ing t he nt h pat t er n st or ed in
memor y.
For exampl e, t he af or ement ioned pat t er n can be wr it t en as
/([\da-z]+])[:;]\1[:;]\1/
Her e, t he pat t er n mat ched by [\da-z]+ is st or ed in memor y. When t he Per l int er pr et er
sees t he escape sequence \1, it mat ches t he mat ched pat t er n.
You al so can st or e t he sequence [:;] in memor y, and wr it e t his pat t er n as f ol l ows:
/([\da-z]+)([:;])\1\2\1/
Pat t er n sequences ar e st or ed in memor y f r om l ef t t o r ight , so \1 r epr esent s t he
subpat t er n mat ched by [\da-z]+ and \2 r epr esent s t he subpat t er n mat ched by [:;].
Pat t er n-sequence memor y is of t en used when you want t o mat ch t he same char act er in
mor e t han one pl ace but don't car e which char act er you mat ch. For exampl e, if you ar e
l ooking f or a dat e in dd-mm-yy f or mat , you might want t o mat ch
/\d{2}([\W])\d{2}\1\d{2}/
This mat ches t wo digit s, a non-wor d char act er , t wo mor e digit s, t he same non-wor d
char act er , and t wo mor e digit s. This means t hat t he f ol l owing st r ings al l mat ch:
12-05-92
26.11.87
07 04 92
However , t he f ol l owing st r ing does not mat ch:
21-05.91
This is because t he pat t er n is l ooking f or a - bet ween t he 05 and t he 91, not a per iod.
Bewar e t hat t he pat t er n
/\d{2}([\W])\d{2}\1\d{2}/
is not t he same as t he pat t er n
/(\d{2})([\W])\1\2\1/
In t he f ir st pat t er n, any digit can appear anywher e. The
second pat t er n mat ches any t wo digit s as t he f ir st t wo
char act er s, but t hen onl y mat ches t he same t wo digit s
again. This means t hat
17-17-17
mat ches, but t he f ol l owing does not :
17-05-91
Pattern-Sequence Scalar Variables
Not e t hat pat t er n-sequence memor y is pr eser ved onl y f or t he l engt h of t he pat t er n.
This means t hat if you def ine t he f ol l owing pat t er n (which, incident al l y, mat ches any
f l oat ing-point number t hat does not cont ain an exponent ):
/-?(\d+)\.?(\d+)/
you cannot t hen def ine anot her pat t er n, such as t he f ol l owing:
/\1/
and expect t he Per l int er pr et er t o r emember t hat \1 r ef er s t o t he f ir st \d+ (t he digit s
bef or e t he decimal point ).
To get ar ound t his pr obl em, Per l def ines special buil t -in var iabl es t hat r emember t he
val ue of pat t er ns mat ched in par ent heses. These special var iabl es ar e named $n, wher e n
is t he nt h set of par ent heses in t he pat t er n.
For exampl e, consider t he f ol l owing:
$string = "This string contains the number 25.11.";
$string =~ /-?(\d+)\.?(\d+)/;
$integerpart = $1;
$decimalpart = $2;
In t his case, t he pat t er n
/-?(\d+)\.?(\d+)/
mat ches 25.11, and t he subpat t er n in t he f ir st set of par ent heses mat ches 25. This means
t hat 25 is st or ed in $1 and is l at er assigned t o $integerpart. Simil ar l y, t he second set of
par ent heses mat ches 11, which is st or ed in $2 and l at er assigned t o $decimalpart.
The val ues st or ed in $1, $2, and so on, ar e dest r oyed
when anot her pat t er n mat ch is per f or med. If you need
t hese val ues, be sur e t o assign t hem t o ot her scal ar
var iabl es.
Ther e is al so one ot her buil t -in scal ar var iabl e, $&, which cont ains t he ent ir e mat ched
pat t er n, as f ol l ows:
$string = "This string contains the number 25.11.";
$string =~ /-?(\d+)\.?(\d+)/;
$number = $&;
Her e, t he pat t er n mat ched is 25.11, which is st or ed in $& and t hen assigned t o $number.
Special-Character Precedence
Per l def ines r ul es of pr ecedence t o det er mine t he or der in which special char act er s in
pat t er ns ar e int er pr et ed. For exampl e, t he pat t er n
/x|y+/
mat ches eit her x or one or mor e occur r ences of y, because + has higher pr ecedence t han |
and is t her ef or e int er pr et ed f ir st .
Tabl e 7.3 l ist s t he special char act er s t hat can appear in pat t er ns in or der of pr ecedence
(highest t o l owest ). Special char act er s wit h higher pr ecedence ar e al ways int er pr et ed
bef or e t hose of l ower pr ecedence.
Tabl e 7.3. The pr ecedence of pat t er n-mat ching special char act er s.
Special
char act er
Descr ipt ion
()
Pat t er n memor y
+ * ? {}
Number of occur r ences
^ $ \b \B
Pat t er n anchor s
|
Al t er nat ives
Because t he pat t er n-memor y special char act er s () have t he highest pr ecedence, you can
use t hem t o f or ce ot her special char act er s t o be eval uat ed f ir st . For exampl e, t he
pat t er n
(ab|cd)+
mat ches one or mor e occur r ences of eit her ab or cd. This mat ches, f or exampl e, abcdab.
Remember t hat when you use par ent heses t o f or ce t he
or der of pr ecedence, you al so ar e st or ing int o pat t er n
memor y. For exampl e, in t he sequence
/(ab|cd)+(.)(ef|gh)+\1/
t he \1 r ef er s t o what ab|cd mat ched, not t o what t he .
special char act er mat ched.
Now t hat you know al l of t he special -pat t er n char act er s and t heir pr ecedence, l ook at
a pr ogr am t hat does mor e compl ex pat t er n mat ching. List ing 7.9 uses t he var ious special -
pat t er n char act er s, incl uding t he par ent heses, t o check whet her a given input st r ing is
a val id t went iet h-cent ur y dat e.

List ing 7.9. A dat e-val idat ion pr ogr am.
1: #!/usr/local/bin/perl
2:
3: print ("Enter a date in the format YYYY-MM-DD:\n");
4: $date = <STDIN>;
5: chop ($date);
6:
7: # Because this pattern is complicated, we split it
8: # into parts, assign the parts to scalar variables,
9: # then substitute them in later.
10:
11: # handle 31-day months
12: $md1 = "(0[13578]|1[02])\\2(0[1-9]|[12]\\d|3[01])";
13: # handle 30-day months
14: $md2 = "(0[469]|11)\\2(0[1-9]|[12]\\d|30)";
15: # handle February, without worrying about whether it's
16: # supposed to be a leap year or not
17: $md3 = "02\\2(0[1-9]|[12]\\d)";
18:
19: # check for a twentieth-century date
20: $match = $date =~ /^(19)?\d\d(.)($md1|$md2|$md3)$/;
21: # check for a valid but non-20th century date
22: $olddate = $date =~ /^(\d{1,4})(.)($md1|$md2|$md3)$/;
23: if ($match) {
24: print ("$date is a valid date\n");
25: } elsif ($olddate) {
26: print ("$date is not in the 20th century\n");
27: } else {
28: print ("$date is not a valid date\n");
29: }

$ program7_9
Enter a date in the format YYYY-MM-DD:
1991-04-31
1991-04-31 is not a valid date
$
Don't wor r y: t his pr ogr am is a l ot l ess compl icat ed t han it l ooks! Basical l y,
t his pr ogr am does t he f ol l owing:
1. It checks whet her t he dat e is in t he f or mat YYYY-MM-DD. (It al l ows YY-MM-DD, and
al so enabl es you t o use a char act er ot her t han a hyphen t o separ at e t he year ,
mont h, and dat e.)
2. It checks whet her t he year is in t he t went iet h cent ur y or not .
3. It checks whet her t he mont h is bet ween 01 and 12.
4. Final l y, it checks whet her t he dat e f iel d is a l egal dat e f or t hat mont h. Legal
dat e f iel ds ar e bet ween 01 and eit her 29, 30, or 31, depending on t he number of
days in t hat mont h.
If t he dat e is l egal , t he pr ogr am t el l s you so. If t he dat e is not a t went iet h-cent ur y
dat e but is l egal , t he pr ogr am inf or ms you of t his al so.
Because t he pat t er n t o be mat ched is t oo l ong t o f it on one l ine, t his pr ogr am br eaks it
int o pieces and assigns t he pieces t o scal ar var iabl es. This is possibl e because scal ar -
var iabl e subst it ut ion is suppor t ed in pat t er ns.
Line 12 is t he pat t er n t o mat ch f or mont hs wit h 31 days. Not e t hat t he escape sequences
(such as \d) ar e pr eceded by anot her backsl ash (pr oducing \\d). This is because t he
pr ogr am act ual l y want s t o st or e a backsl ash in t he scal ar var iabl e. (Recal l t hat
backsl ashes in doubl e-quot ed st r ings ar e t r eat ed as escape sequences.) The pat t er n
(0[13578]|1[02])\2(0[1-9]|[12]\d|3[01])
which is assigned t o $md1, consist s of t he f ol l owing component s:
G The sequence (0[13578]|1[02]), which mat ches t he mont h val ues 01, 03, 05, 07, 08,
10, and 12 (t he 31-day mont hs)
G \2, which mat ches t he char act er t hat separ at es t he day, mont h, and year
G The sequence (0[1-9]|[12]\d|3[01]), which mat ches any t wo-digit number
bet ween 01 and 31
Not e t hat \2 mat ches t he separ at or char act er because t he separ at or char act er wil l
event ual l y be t he second pat t er n sequence st or ed in memor y (when t he pat t er n is
f inal l y assembl ed).
Line 14 is simil ar t o l ine 12 and handl es 30-day mont hs. The onl y dif f er ences bet ween
t his subpat t er n and t he one in l ine 12 ar e as f ol l ows:
G The mont h val ues accept ed ar e 04, 06, 09, and 11.
G The val id dat e f iel ds ar e 01 t hr ough 30, not 01 t hr ough 31.
Line 17 is anot her simil ar pat t er n t hat checks whet her t he mont h is 02 (Febr uar y) and
t he dat e f iel d is bet ween 01 and 29.
Line 20 does t he act ual pat t er n mat ch t hat checks whet her t he dat e is a val id
t went iet h-cent ur y dat e. This pat t er n is divided int o t hr ee par t s.
G ^(19)?\d\d, which mat ches any t wo-digit number at t he beginning of a l ine, or any
f our -digit number st ar t ing wit h 19
G The separ at or char act er , which is t he second it em in par ent heses-t he second it em
st or ed in memor y-and t hus can be r et r ieved using \2
G ($md1|$md2|$md3)$, which mat ches any of t he val id mont h-day combinat ions
def ined in l ines 12, 14, and 17, pr ovided it appear s at t he end of t he l ine
The r esul t of t he pat t er n mat ch, eit her t r ue or f al se, is st or ed in t he scal ar var iabl e
$match.
Line 22 checks whet her t he dat e is a val id dat e in any cent ur y. The onl y dif f er ence
bet ween t his pat t er n and t he one in l ine 20 is t hat t he year can be any one-t o-f our -digit
number . The r esul t of t he pat t er n mat ch is st or ed in $olddate.
Lines 23-29 check whet her eit her $match or $olddate is t r ue and pr int t he appr opr iat e
message.
As you can see, t he pat t er n-mat ching f acil it y in Per l is quit e power f ul . This pr ogr am is
l ess t han 30 l ines l ong, incl uding comment s; t he equival ent pr ogr am in al most any
ot her pr ogr amming l anguage woul d be subst ant ial l y l onger and much mor e dif f icul t t o
wr it e.
Specifying a Different Pattern Delimiter
So f ar , al l t he pat t er ns you have seen have been encl osed by / char act er s.
/de*f/
These / char act er s ar e known as pattern delimiters.
Because / is t he pat t er n-del imit er char act er , you must use \/ t o incl ude a / char act er in
a pat t er n. This can become awkwar d if you ar e sear ching f or a dir ect or y such as, f or
exampl e, /u/jqpublic/perl/prog1.
/\/u\/jqpublic\/perl\/prog1/
To make it easier t o wr it e pat t er ns t hat incl ude / char act er s, Per l enabl es you t o use
any pat t er n-del imit er char act er you l ike. The f ol l owing pat t er n al so mat ches t he
dir ect or y /u/jqpublic/perl/prog1:
m!/u/jqpublic/perl/prog1!
Her e, t he m indicat es t he pat t er n-mat ching oper at ion. If you ar e using a pat t er n
del imit er ot her t han /, you must incl ude t he m.
Ther e ar e t wo t hings you shoul d wat ch out f or when
you use ot her pat t er n del imit er s.
Fir st , if you use t he ' char act er as a pat t er n del imit er ,
t he Per l int er pr et er does not subst it ut e f or scal ar -
var iabl e names.
m'$var'
This mat ches t he st r ing $var, not t he cur r ent val ue of
t he scal ar var iabl e $var.
Second, if you use a pat t er n del imit er t hat is nor mal l y a
special -pat t er n char act er , you wil l not be abl e t o use
t hat special char act er in your pat t er n. For exampl e, if
you want t o mat ch t he pat t er n ab?c (which mat ches a,
opt ional l y f ol l owed by b, f ol l owed by c) you cannot use
t he ? char act er as a pat t er n del imit er . The pat t er n
m?ab?c?
pr oduces a synt ax er r or , because t he Per l int er pr et er
assumes t hat t he ? af t er t he b is a pat t er n del imit er . You
can st il l use
m?ab\?c?
but t his pat t er n won't mat ch what you want . Because
t he ? inside t he pat t er n is escaped, t he Per l int er pr et er
assumes t hat you want t o mat ch t he act ual ? char act er ,
and t he pat t er n mat ches t he sequence ab?c.
Pattern-Matching Options
When you specif y a pat t er n, you al so can suppl y opt ions t hat cont r ol how t he pat t er n is
t o be mat ched. Tabl e 7.4 l ist s t hese pat t er n-mat ching opt ions.
Tabl e 7.4. Pat t er n-mat ching opt ions.
Opt ion Descr ipt ion
g
Mat ch al l possibl e pat t er ns
i
Ignor e case
m
Tr eat st r ing as mul t ipl e
l ines
o
Onl y eval uat e once
s
Tr eat st r ing as singl e l ine
x
Ignor e whit e space in
pat t er n
Al l pat t er n opt ions ar e incl uded immediat el y af t er t he pat t er n. For exampl e, t he
f ol l owing pat t er n uses t he i opt ion t o ignor e case:
/ab*c/i
You can specif y as many of t he opt ions as you l ike, and t he opt ions can be in any or der .
Matching All Possible Patterns
The g oper at or t el l s t he Per l int er pr et er t o mat ch al l t he possibl e pat t er ns in a st r ing.
For exampl e, if you sear ch t he st r ing balata using t he pat t er n
/.a/g
which mat ches any char act er f ol l owed by a, t he pat t er n mat ches ba, la, and ta.
If a pat t er n wit h t he g opt ion specif ied appear s as an assignment t o an ar r ay var iabl e,
t he ar r ay var iabl e is assigned a l ist consist ing of al l t he pat t er ns mat ched. For exampl e,
@matches = "balata" =~ /.a/g;
assigns t he f ol l owing l ist t o @matches:
("ba", "la", "ta")
Now, consider t he f ol l owing st at ement :
$match = "balata" =~ /.a/g;
The f ir st t ime t his st at ement is execut ed, $match is assigned t he f ir st pat t er n mat ched,
which in t his case is ba. If t his assignment is per f or med again, $match is assigned t he
second pat t er n mat ched in t he st r ing, which is la, and so on unt il t he pat t er n r uns out
of mat ches.
This means t hat you can use pat t er ns wit h t he g opt ion in l oops. List ing 7.10 shows how
t his wor ks.

List ing 7.10. A pr ogr am t hat l oops using a pat t er n.
1: #!/usr/local/bin/perl
2:
3: while ("balata" =~ /.a/g) {
4: $match = $&;
5: print ("$match\n");
6: }

$ program7_10
ba
la
ta
$
The f ir st t ime t hr ough t he l oop, $match has t he val ue of t he f ir st pat t er n
mat ched, which is ba. (The syst em var iabl e $& al ways cont ains t he l ast pat t er n mat ched;
t his pat t er n is assigned t o $match in l ine 4.) When t he l oop is execut ed f or a second t ime,
$match has t he val ue la. The t hir d t ime t hr ough, $match has t he val ue ta. Af t er t his, t he
l oop t er minat es; because t he pat t er n doesn't mat ch anyt hing el se, t he condit ional
expr ession is now f al se.
Determining the Match Location
If you need t o know how much of a st r ing has been sear ched by t he pat t er n mat cher
when t he g oper at or is specif ied, use t he pos f unct ion.
$offset = pos($string);
This r et ur ns t he posit ion at which t he next pat t er n mat ch wil l be st ar t ed.
You can r eposit ion t he pat t er n mat cher by put t ing pos() on t he l ef t side of an
assignment .
pos($string) = $newoffset;
This t el l s t he Per l int er pr et er t o st ar t t he next pat t er n mat ch at t he posit ion specif ied
by $newoffset.
If you change t he st r ing being sear ched, t he mat ch
posit ion is r eset t o t he beginning of t he st r ing.
NOTE
The pos f unct ion is not avail abl e in Per l ver sion 4.
Ignoring Case
The i opt ion enabl es you t o specif y t hat a mat ched l et t er can eit her be upper case or
l ower case. For exampl e, t he f ol l owing pat t er n mat ches de, dE, De, or DE:
/de/i
Pat t er ns t hat mat ch eit her upper case or l ower case l et t er s ar e said t o be case-insensitive.
Treating the String as Multiple Lines
The m opt ion t el l s t he Per l int er pr et er t hat t he st r ing t o be mat ched cont ains mul t ipl e
l ines of t ext . When t he m opt ion is specif ied, t he ^ special char act er mat ches eit her t he
st ar t of t he st r ing or t he st ar t of any new l ine. For exampl e, t he pat t er n
/^The/m
mat ches t he wor d The in
This pattern matches\nThe first word on the second line
The m opt ion al so specif ies t hat t he $ special char act er is t o mat ch t he end of any l ine.
This means t hat t he pat t er n
/line.$/m
is mat ched in t he f ol l owing st r ing:
This is the end of the first line.\nHere's another line.
NOTE
The m opt ion is def ined onl y in Per l 5. To t r eat a st r ing as
mul t ipl e l ines when you r un Per l 4, set t he $* syst em
var iabl e, descr ibed on Day 17, "Syst em Var iabl es."
Evaluating a Pattern Only Once
The o opt ion enabl es you t o t el l t he Per l int er pr et er t hat a pat t er n is t o be eval uat ed
onl y once. For exampl e, consider t he f ol l owing:
$var = 1;
$line = <STDIN>;
while ($var < 10) {
$result = $line =~ /$var/o;
$line = <STDIN>;
$var++;
}
The f ir st t ime t he Per l int er pr et er sees t he pat t er n /$var/, it r epl aces t he name $var
wit h t he cur r ent val ue of $var, which is 1; t his means t hat t he pat t er n t o be mat ched is
/1/.
Because t he o opt ion is specif ied, t he pat t er n t o be mat ched r emains /1/ even when t he
val ue of $var changes. If t he o opt ion had not been specif ied, t he pat t er n woul d have
been /2/ t he next t ime t hr ough t he l oop.
TIP
Ther e's no r eal r eason t o use t he o opt ion f or pat t er ns
unl ess you ar e keen on ef f iciency. Her e's an easier way
t o do t he same t hing:
$var = <STDIN>;
$matchval = $var;
$line = <STDIN>;
while ($var < 10) {
$result = $line =~ /$matchval/;
$line = <STDIN>;
$var++;
}
The val ue of $matchval never changes, so t he o opt ion is
not necessar y.
Treating the String as a Single Line
The s opt ion specif ies t hat t he st r ing t o be mat ched is t o be t r eat ed as a singl e l ine of
t ext . In t his case, t he . special char act er mat ches ever y char act er in a st r ing, incl uding
t he newl ine char act er . For exampl e, t he pat t er n /a.*bc/s is mat ched successf ul l y in
t he f ol l owing st r ing:
axxxxx \nxxxxbc
If t he s opt ion is not specif ied, t his pat t er n does not mat ch, because t he . char act er does
not mat ch t he newl ine.
NOTE
The s opt ion is def ined onl y in Per l 5.
Using White Space in Patterns
One pr obl em wit h pat t er ns in Per l is t hat t hey can become dif f icul t t o f ol l ow. For
exampl e, consider t his pat t er n, which you saw ear l ier :
/\d{2}([\W])\d{2}\1\d{2}/
Pat t er ns such as t his ar e dif f icul t t o f ol l ow, because t her e ar e a l ot of backsl ashes,
br aces, and br acket s t o sor t out .
Per l 5 makes l if e a l it t l e easier by suppl ying t he x opt ion. This t el l s t he Per l int er pr et er
t o ignor e whit e space in a pat t er n unl ess it is pr eceded by a backsl ash. This means t hat
t he pr eceding pat t er n can be r ewr it t en as t he f ol l owing, which is much easier t o
f ol l ow:
/\d{2} ([\W]) \d{2} \1 \d{2}/x
Her e is an exampl e of a pat t er n cont aining an act ual bl ank space:
/[A-Z] [a-z]+ \ [A-Z] [a-z]+ /x
This mat ches a name in t he st andar d f ir st -name/l ast -name f or mat (such as John Smith).
Nor mal l y, you won't want t o use t he x opt ion if you'r e act ual l y t r ying t o mat ch whit e
space, because you wind up wit h t he backsl ash pr obl em al l over again.
NOTE
The x opt ion is def ined onl y in Per l 5.
The Substitution Operator
Per l enabl es you t o r epl ace par t of a st r ing using t he subst it ut ion oper at or , which has
t he f ol l owing synt ax:
s/pattern/replacement/
The Per l int er pr et er sear ches f or t he pat t er n specif ied by t he pl acehol der pattern. If it
f inds pattern, it r epl aces it wit h t he st r ing r epr esent ed by t he pl acehol der replacement.
For exampl e:
$string = "abc123def";
$string =~ s/123/456/;
Her e, 123 is r epl aced by 456, which means t hat t he val ue st or ed in $string is now
abc456def.
You can use any of t he pat t er n special char act er s in t he subst it ut ion oper at or . For
exampl e,
s/[abc]+/0/
sear ches f or a sequence consist ing of one or mor e occur r ences of t he l et t er s a, b, and c
(in any or der ) and r epl aces t he sequence wit h 0.
If you just want t o del et e a sequence of char act er s r at her t han r epl ace it , l eave out
t he r epl acement st r ing as in t he f ol l owing exampl e, which del et es t he f ir st occur r ence
of t he pat t er n abc:
s/abc//
Using Pattern-Sequence Variables in Substitutions
You can use pat t er n-sequence var iabl es t o incl ude a mat ched pat t er n in t he
r epl acement st r ing. The f ol l owing is an exampl e:
s/(\d+)/[$1]/
This mat ches a sequence of one or mor e digit s. Because t his sequence is encl osed in
par ent heses, it is st or ed in t he scal ar var iabl e $1. In t he r epl acement st r ing, [$1], t he
scal ar var iabl e name $1 is r epl aced by it s val ue, which is t he mat ched pat t er n.
NOTE
Because t he r epl acement st r ing in t he subst it ut ion
oper at or is a st r ing, not a pat t er n, t he pat t er n special
char act er s, such as [], *, and +, do not have a special
meaning. For exampl e, in t he subst it ut ion
s/abc/[def]/
t he r epl acement st r ing is [def] (incl uding t he squar e
br acket s).
Options for the Substitution Operator
The subst it ut ion oper at or suppor t s sever al opt ions, which ar e l ist ed in Tabl e 7.5.
Tabl e 7.5. Opt ions f or t he subst it ut ion oper at or .
Opt ion Descr ipt ion
g
Change al l occur r ences of t he pat t er n
i
Ignor e case in pat t er n
e
Eval uat e r epl acement st r ing as expr ession
m
Tr eat st r ing t o be mat ched as mul t ipl e
l ines
o
Eval uat e onl y once
s
Tr eat st r ing t o be mat ched as singl e l ine
x
Ignor e whit e space in pat t er n
As wit h pat t er n mat ching, opt ions ar e appended t o t he end of t he oper at or . For exampl e,
t o change al l occur r ences of abc t o def, use t he f ol l owing:
s/abc/def/g
Global Substitution
The g opt ion changes al l occur r ences of a pat t er n in a par t icul ar st r ing. For exampl e,
t he f ol l owing subst it ut ion put s par ent heses ar ound any number in t he st r ing:
s/(\d+)/($1)/g
List ing 7.11 is an exampl e of a pr ogr am t hat uses gl obal subst it ut ion. It examines each
l ine of it s input , r emoves al l ext r aneous l eading spaces and t abs, and r epl aces mul t ipl e
spaces and t abs bet ween wor ds wit h a singl e space.

List ing 7.11. A simpl e whit e space cl eanup pr ogr am.
1: #!/usr/local/bin/perl
2:
3: @input = <STDIN>;
4: $count = 0;
5: while ($input[$count] ne "") {
6: $input[$count] =~ s/^[ \t]+//;
7: $input[$count] =~ s/[ \t]+\n$/\n/;
8: $input[$count] =~ s/[ \t]+/ /g;
9: $count++;
10: }
11: print ("Formatted text:\n");
12: print (@input);

$ program7_11
This is a line of input.
Here is another line.
This is my last line of input.
^D
Formatted text:
This is a line of input.
Here is another line.
This is my last line of input.
$
This pr ogr am per f or ms t hr ee subst it ut ions on each l ine of it s input . The f ir st
subst it ut ion, in l ine 6, checks whet her t her e ar e any spaces or t abs at t he beginning of
t he l ine. If any exist , t hey ar e r emoved.
Simil ar l y, l ine 7 checks whet her t her e ar e any spaces or t abs at t he end of t he l ine
(bef or e t he t r ail ing newl ine char act er ). If any exist , t hey ar e r emoved. To do t his, l ine 7
r epl aces t he f ol l owing pat t er n (one or mor e spaces and t abs, f ol l owed by a newl ine
char act er , f ol l owed by t he end of t he l ine) wit h a newl ine char act er :
/[ \t]+\n$/
Line 8 uses a gl obal subst it ut ion t o r emove ext r a spaces and t abs bet ween wor ds. The
f ol l owing pat t er n mat ches one or mor e spaces or t abs, in any or der ; t hese spaces and
t abs ar e r epl aced by a singl e space:
/[ \t]+/
Ignoring Case
The i opt ion ignor es case when subst it ut ing. For exampl e, t he f ol l owing subst it ut ion
r epl aces al l occur r ences of t he wor ds no, No, NO, and nO wit h NO. (Recal l t hat t he \b
escape char act er specif ies a wor d boundar y.)
s/\bno\b/NO/gi
Replacement Using an Expression
The e opt ion t r eat s t he r epl acement st r ing as an expr ession, which it eval uat es bef or e
r epl acing. For exampl e, consider t he f ol l owing:
$string = "0abc1";
$string =~ s/[a-zA-Z]+/$& x 2/e
The subst it ut ion shown her e is a quick way t o dupl icat e par t of a st r ing. Her e's how it
wor ks:
1. The pat t er n /[a-zA-Z]+/ mat ches abc, which is st or ed in t he buil t -in var iabl e $&.
2. The e opt ion indicat es t hat t he r epl acement st r ing, $& x 2, is t o be t r eat ed as an
expr ession. This expr ession is eval uat ed, pr oducing t he r esul t abcabc.
3. abcabc is subst it ut ed f or abc in t he st r ing st or ed in $string. This means t hat t he
new val ue of $string is 0abcabc1.
List ing 7.12 is anot her exampl e t hat uses t he e opt ion in a subst it ut ion. This pr ogr am
t akes ever y int eger in a l ist of input f il es and mul t ipl ies t hem by 2, l eaving t he r est of
t he cont ent s unchanged. (For t he sake of simpl icit y, t he pr ogr am assumes t hat t her e ar e
no f l oat ing-point number s in t he f il e.)

List ing 7.12. A pr ogr am t hat mul t ipl ies ever y int eger in a f il e by 2.
1: #!/usr/local/bin/perl
2:
3: $count = 0;
4: while ($ARGV[$count] ne "") {
5: open (FILE, "$ARGV[$count]");
6: @file = <FILE>;
7: $linenum = 0;
8: while ($file[$linenum] ne "") {
9: $file[$linenum] =~ s/\d+/$& * 2/eg;
10: $linenum++;
11: }
12: close (FILE);
13: open (FILE, ">$ARGV[$count]");
14: print FILE (@file);
15: close (FILE);
16: $count++;
17: }

If a file named foo contains the text
This contains the number 1.
This contains the number 26.
and t he name foo is passed as a command-l ine ar gument t o t his pr ogr am, t he
f il e foo becomes
This contains the number 2.
This contains the number 52.
This pr ogr am uses t he buil t -in var iabl e @ARGV t o r et r ieve f il enames f r om t he
command l ine. Not e t hat t he pr ogr am cannot use <>, because t he f ol l owing st at ement
r eads t he ent ir e cont ent s of al l t he f il es int o a singl e ar r ay:
@file = <>;
Lines 8-11 r ead and subst it ut e one l ine of a f il e at a t ime. Line 9 per f or ms t he act ual
subst it ut ion as f ol l ows:
1. The pat t er n \d+ mat ches a sequence of one or mor e digit s, which is aut omat ical l y
assigned t o $&.
2. The val ue of $& is subst it ut ed int o t he r epl acement st r ing.
3. The e opt ion indicat es t hat t his r epl acement st r ing is t o be t r eat ed as an
expr ession. This expr ession mul t ipl ies t he mat ched int eger by 2.
4. The r esul t of t he mul t ipl icat ion is t hen subst it ut ed int o t he f il e in pl ace of t he
or iginal int eger .
5. The g opt ion indicat es t hat ever y int eger on t he l ine is t o be subst it ut ed f or .
Af t er al l t he l ines in t he f il e have been r ead, t he f il e is cl osed and r eopened f or
wr it ing. The cal l t o print in l ine 14 t akes t he l ist st or ed in @file-t he cont ent s of t he
cur r ent f il e-and wr it es t hem back out t o t he f il e, over wr it ing t he or iginal cont ent s.
Evaluating a Pattern Only Once
As wit h t he mat ch oper at or , t he o opt ion t o t he subst it ut ion oper at or t el l s t he Per l
int er pr et er t o r epl ace a scal ar var iabl e name wit h it s val ue onl y once. For exampl e, t he
f ol l owing st at ement subst it ut es t he cur r ent val ue of $var f or it s name, pr oducing a
r epl acement st r ing:
$string =~ /abc/$var/o;
This r epl acement st r ing t hen never changes, even if t he val ue of $var changes. For
exampl e:
$var = 17;
while ($var > 0) {
$string = <STDIN>;
$string =~ /abc/$var/o;
print ($string);
$var--; # the replacement string is still "17"
}
Again, as wit h t he mat ch oper at or , t her e is no r eal r eason t o use t he o opt ion.
Treating the String as Single or Multiple Lines
As in t he pat t er n-mat ching oper at or , t he s and m opt ions specif y t hat t he st r ing t o be
mat ched is t o be t r eat ed as a singl e l ine or as mul t ipl e l ines, r espect ivel y.
The s opt ion ensur es t hat t he newl ine char act er \n is mat ched by t he . special
char act er .
$string = "This is a\ntwo-line string.";
$string =~ s/a.*o/one/s;
# $string now contains "This is a one-line string."
If t he m opt ion is specif ied, ^ and $ mat ch t he beginning and end of any l ine.
$string = "The The first line\nThe The second line";
$string =~ s/^The//gm;
# $string now contains "The first line\nThe second line"
$string =~ s/e$/k/gm;
# $string now contains "The first link\nThe second link"
The \A and \Z escape sequences (def ined in Per l 5) al ways
mat ch onl y t he beginning and end of t he st r ing,
r espect ivel y. (This is t he onl y case wher e \A and \Z
behave dif f er ent l y f r om ^ and $.)
NOTE
The m and s opt ions ar e def ined onl y in Per l 5. To t r eat a
st r ing as mul t ipl e l ines when you r un Per l 4, set t he $*
syst em var iabl e, descr ibed on Day 17.
Using White Space in Patterns
The x opt ion t el l s t he Per l int er pr et er t o ignor e al l whit e space unl ess pr eceded by a
backsl ash. As wit h t he pat t er n-mat ching oper at or , ignor ing whit e space makes
compl icat ed st r ing pat t er ns easier t o r ead.
$string =~ s/\d{2} ([\W]) \d{2} \1 \d{2}/$1-$2-$3/x
This conver t s a day-mont h-year st r ing t o t he dd-mm-yy f or mat .
NOTE
Even if t he x opt ion is specif ied, spaces in t he r epl acement
st r ing ar e not ignor ed. For exampl e, t he f ol l owing
r epl aces 14/04/95 wit h 14 - 04 - 95, not 14-04-95:
$string =~ s/\d{2} ([\W]) \d{2} \1 \d{2}/$1 - $2 -
$3/x
Al so not e t hat t he x opt ion is def ined onl y in Per l 5.
Specifying a Different Delimiter
You can specif y a dif f er ent del imit er t o separ at e t he pat t er n and r epl acement st r ing in
t he subst it ut ion oper at or . For exampl e, t he f ol l owing subst it ut ion oper at or r epl aces
/u/bin wit h /usr/local/bin:
s#/u/bin#/usr/local/bin#
The sear ch and r epl acement st r ings can be encl osed in par ent heses or angl e br acket s.
s(/u/bin)(/usr/local/bin)
s</u/bin>/\/usr\/local\/bin/
NOTE
As wit h t he mat ch oper at or , you cannot use a special
char act er bot h as a del imit er and in a pat t er n.
s.a.c.def.
This subst it ut ion wil l be f l agged as cont aining an er r or
because t he . char act er is being used as t he del imit er .
The subst it ut ion
s.a\.c.def.
does wor k, but it subst it ut es def f or a.c, wher e . is an
act ual per iod and not t he pat t er n special char act er .
The Translation Operator
Per l al so pr ovides anot her way t o subst it ut e one gr oup of char act er s f or anot her : t he
tr t r ansl at ion oper at or . This oper at or uses t he f ol l owing synt ax:
tr/string1/string2/
Her e, string1 cont ains a l ist of char act er s t o be r epl aced, and string2 cont ains t he
char act er s t hat r epl ace t hem. The f ir st char act er in string1 is r epl aced by t he f ir st
char act er in string2, t he second char act er in string1 is r epl aced by t he second
char act er in string2, and so on.
Her e is a simpl e exampl e:
$string = "abcdefghicba";
$string =~ tr/abc/def/;
Her e, t he char act er s a, b, and c ar e t o be r epl aced as f ol l ows:
G Al l occur r ences of t he char act er a ar e t o be r epl aced by t he char act er d.
G Al l occur r ences of t he char act er b ar e t o be r epl aced by t he char act er e.
G Al l occur r ences of t he char act er c ar e t o be r epl aced by t he char act er f.
Af t er t he t r ansl at ion, t he scal ar var iabl e $string cont ains t he val ue defdefghifed.
NOTE
If t he st r ing l ist ing t he char act er s t o be r epl aced is
l onger t han t he st r ing cont aining t he r epl acement
char act er s, t he l ast char act er of t he r epl acement
st r ing is r epeat ed. For exampl e:
$string = "abcdefgh";
$string =~ tr/efgh/abc/;
Her e, t her e is no char act er cor r esponding t o d in t he
r epl acement l ist , so c, t he l ast char act er in t he
r epl acement l ist , r epl aces h. This t r ansl at ion set s t he
val ue of $string t o abcdabcc.
Al so not e t hat if t he same char act er appear s mor e t han
once in t he l ist of char act er s t o be r epl aced, t he f ir st
r epl acement is used:
$string =~ tr/AAA/XYZ/; replaces A with X
The most common use of t he t r ansl at ion oper at or is t o conver t al phabet ic char act er s
f r om upper case t o l ower case or vice ver sa. List ing 7.13 pr ovides an exampl e of a pr ogr am
t hat conver t s a f il e t o al l l ower case char act er s.

List ing 7.13. An upper case-t o-l ower case conver sion pr ogr am.
1: #!/usr/local/bin/perl
2:
3: while ($line = <STDIN>) {
4: $line =~ tr/A-Z/a-z/;
5: print ($line);
6: }

$ program7_13
THIS LINE IS IN UPPER CASE.
this line is in upper case.
ThiS LiNE Is iN mIxED cASe.
this line is in mixed case.
^D
$
This pr ogr am r eads a l ine at a t ime f r om t he st andar d input f il e, t er minat ing
when it sees a l ine cont aining t he Ct r l +D (end-of -f il e) char act er .
Line 4 per f or ms t he t r ansl at ion oper at ion. As in t he ot her pat t er n-mat ching oper at ions,
t he r ange char act er (-) indicat es a r ange of char act er s t o be incl uded. Her e, t he r ange
a-z r ef er s t o al l t he l ower case char act er s, and t he r ange A-Z r ef er s t o al l t he
upper case char act er s.
NOTE
Ther e ar e t wo t hings you shoul d not e about t he
t r ansl at ion oper at or :
The pat t er n special char act er s ar e not suppor t ed by t he
t r ansl at ion oper at or .
You can use y in pl ace of tr if you want .
$string =~ y/a-z/A-Z/;
Options for the Translation Operator
The t r ansl at ion oper at or suppor t s t hr ee opt ions, which ar e l ist ed in Tabl e 7.6.
The c opt ion (c is f or "compl ement ") t r ansl at es al l char act er s t hat ar e not specif ied. For
exampl e, t he st at ement
$string =~ tr/\d/ /c;
r epl aces ever yt hing t hat is not a digit wit h a space.
Tabl e 7.6. Opt ions f or t he t r ansl at ion oper at or .
Opt ion Descr ipt ion
c
Tr ansl at e al l char act er s not specif ied
d
Del et e al l specif ied char act er s
s
Repl ace mul t ipl e ident ical out put char act er s wit h a singl e
char act er
The d opt ion del et es ever y specif ied char act er .
$string =~ tr/\t //d;
This del et es al l t he t abs and spaces f r om $string.
The s opt ion (f or "squeeze") checks t he out put f r om t he t r ansl at ion. If t wo or mor e
consecut ive char act er s t r ansl at e t o t he same out put char act er , onl y one out put
char act er is act ual l y used. For exampl e, t he f ol l owing r epl aces ever yt hing t hat is not
a digit and out put s onl y one space bet ween digit s:
$string =~ tr/0-9/ /cs;
List ing 7.14 is a simpl e exampl e of a pr ogr am t hat uses some of t hese t r ansl at ion opt ions.
It r eads a number f r om t he st andar d input f il e, and it get s r id of ever y input char act er
t hat is not act ual l y a digit .

List ing 7.14. A pr ogr am t hat ensur es t hat a st r ing consist s of not hing
but digit s.
1: #!/usr/local/bin/perl
2:
3: $string = <STDIN>;
4: $string =~ tr/0-9//cd;
5: print ("$string\n");

$ program7_14
The number 45 appears in this string.
45
$
Line 4 of t his pr ogr am per f or ms t he t r ansl at ion. The d opt ion indicat es t hat
t he t r ansl at ed char act er s ar e t o be del et ed, and t he c opt ion indicat es t hat ever y
char act er not in t he l ist is t o be del et ed. Ther ef or e, t his t r ansl at ion del et es ever y
char act er in t he st r ing t hat is not a digit . Not e t hat t he t r ail ing newl ine char act er is
not a digit , so it is one of t he char act er s del et ed.
Extended Pattern-Matching
Per l 5 pr ovides some addit ional pat t er n-mat ching capabil it ies not f ound in Per l 4 or in
st andar d UNIX pat t er n-mat ching oper at ions.
Ext ended pat t er n-mat ching capabil it ies empl oy t he f ol l owing synt ax:
(?<c>pattern)
<c> is a singl e char act er r epr esent ing t he ext ended pat t er n-mat ching capabil it y being
used, and pattern is t he pat t er n or subpat t er n t o be af f ect ed.
The f ol l owing ext ended pat t er n-mat ching capabil it ies ar e suppor t ed by Per l 5:
G Par ent hesizing subpat t er ns wit hout saving t hem in memor y
G Embedding opt ions in pat t er ns
G Posit ive and negat ive l ook-ahead condit ions
G Comment s
Parenthesizing Without Saving in Memory
In Per l , when a subpat t er n is encl osed in par ent heses, t he subpat t er n is al so st or ed in
memor y. If you want t o encl ose a subpat t er n in par ent heses wit hout st or ing it in
memor y, use t he ?: ext ended pat t er n-mat ching f eat ur e. For exampl e, consider t his
pat t er n:
/(?:a|b|c)(d|e)f\1/
This mat ches t he f ol l owing:
G One of a, b, or c
G One of d or e
G f
G Whichever of d or e was mat ched ear l ier
Her e, \1 mat ches eit her d or e, because t he subpat t er n a|b|c was not st or ed in memor y.
Compar e t his wit h t he f ol l owing:
/(a|b|c)(d|e)f\1/
Her e, t he subpat t er n a|b|c is st or ed in memor y, and one of a, b, or c is mat ched by \1.
Embedding Pattern Options
Per l 5 pr ovides a way of specif ying a pat t er n-mat ching opt ion wit hin t he pat t er n it sel f .
For exampl e, t he f ol l owing pat t er ns ar e equival ent :
/[a-z]+/i
/(?i)[a-z]+/
In bot h cases, t he pat t er n mat ches one or mor e al phabet ic char act er s; t he i opt ion
indicat es t hat case is t o be ignor ed when mat ching.
The synt ax f or embedded pat t er n opt ions is
(?option)
wher e option is one of t he opt ions shown in Tabl e 7.7.
Tabl e 7.7. Opt ions f or embedded pat t er ns.
Opt ion Descr ipt ion
i
Ignor e case in pat t er n
m
Tr eat pat t er n as mul t ipl e l ines
s
Tr eat pat t er n as singl e l ine
x
Ignor e whit e space in pat t er n
The g and o opt ions ar e not suppor t ed as embedded pat t er n opt ions.
Embedded pat t er n opt ions give you mor e f l exibil it y when you ar e mat ching pat t er ns. For
exampl e:
$pattern1 = "[a-z0-9]+";
$pattern2 = "(?i)[a-z]+";
if ($string =~ /$pattern1|$pattern2/) {
...
}
Her e, t he i opt ion is specif ied f or some, but not al l , of a pat t er n. (This pat t er n mat ches
eit her any col l ect ion of l ower case l et t er s mixed wit h digit s, or any col l ect ion of
l et t er s.)
Positive and Negative Look-Ahead
Per l 5 enabl es you t o use t he ?= f eat ur e t o def ine a boundar y condit ion t hat must be
mat ched in or der f or t he pat t er n t o mat ch. For exampl e, t he f ol l owing pat t er n mat ches
abc onl y if it is f ol l owed by def:
/abc(?=def)/
This is known as a positive look-ahead condition.
NOTE
The posit ive l ook-ahead condit ion is not par t of t he
pat t er n mat ched. For exampl e, consider t hese
st at ement s:
$string = "25abc8";
$string =~ /abc(?=[0-9])/;
$matched = $&;
Her e, as al ways, $& cont ains t he mat ched pat t er n, which
in t his case is abc, not abc8.
Simil ar l y, t he ?! f eat ur e def ines a negative look-ahead condition, which is a boundar y
condit ion t hat must not be pr esent if t he pat t er n is t o mat ch. For exampl e, t he pat t er n
/abc(?!def)/ mat ches any occur r ence of abc unl ess it is f ol l owed by def.
Pattern Comments
Per l 5 enabl es you t o add comment s t o a pat t er n using t he ?# f eat ur e. For exampl e:
if ($string =~ /(?i)[a-z]{2,3}(?# match two or three alphabetic
characters)/ {
...
}
Adding comment s makes it easier t o f ol l ow compl icat ed pat t er ns.
Summary
Per l enabl es you t o sear ch f or sequences of char act er s using patterns. If a pat t er n is
f ound in a st r ing, t he pat t er n is said t o be matched.
Pat t er ns of t en ar e used in conjunct ion wit h t he pat t er n-mat ch oper at or s, =~ and !~. The
=~ oper at or r et ur ns t r ue if t he pat t er n mat ches, and t he !~ oper at or r et ur ns t r ue if t he
pat t er n does not mat ch.
Special -pat t er n char act er s enabl e you t o sear ch f or a st r ing t hat meet s one of a var iet y
of condit ions.
G The + char act er mat ches one or mor e occur r ences of a char act er .
G The * char act er mat ches zer o or mor e occur r ences of a char act er .
G The [] char act er s encl ose a set of char act er s, any one of which mat ches.
G The ? char act er mat ches zer o or one occur r ences of a char act er .
G The ^ and $ char act er s mat ch t he beginning and end of a l ine, r espect ivel y. The \b
and \B char act er s mat ch a wor d boundar y or somewher e ot her t han a wor d
boundar y, r espect ivel y.
G The {} char act er s specif y t he number of occur r ences of a char act er .
G The | char act er specif ies al t er nat ives, eit her of which mat ch.
To give a special char act er it s nat ur al meaning in a pat t er n, pr ecede it wit h a backsl ash
\.
Encl osing a par t of a pat t er n in par ent heses st or es t he mat ched subpat t er n in memor y;
t his st or ed subpat t er n can be r ecal l ed using t he char act er sequence \n, and st or ed in a
scal ar var iabl e using t he buil t -in scal ar var iabl e $n. The buil t -in scal ar var iabl e $&
st or es t he ent ir e mat ched pat t er n.
You can subst it ut e f or scal ar -var iabl e names in pat t er ns, specif y dif f er ent pat t er n
del imit er s, or suppl y opt ions t hat mat ch ever y possibl e pat t er n, ignor e case, or per f or m
scal ar -var iabl e subst it ut ion onl y once.
The subst it ut ion oper at or , s, enabl es you t o r epl ace a mat ched pat t er n wit h a specif ied
st r ing. Opt ions t o t he subst it ut ion oper at or enabl e you t o r epl ace ever y mat ched
pat t er n, ignor e case, t r eat t he r epl acing st r ing as an expr ession, or per f or m scal ar -
var iabl e subst it ut ion onl y once.
The t r ansl at ion oper at or , tr, enabl es you t o t r ansl at e one set of char act er s int o
anot her set . Opt ions exist t hat enabl e you t o per f or m t r ansl at ion on ever yt hing not in
t he l ist , t o del et e char act er s in t he l ist , or t o ignor e mul t ipl e ident ical out put
char act er s.
Per l 5 pr ovides ext ended pat t er n-mat ching capabil it ies not pr ovided in Per l 4. To use one
of t hese ext ended pat t er n f eat ur es on a subpat t er n, put (? at t he beginning of t he
subpat t er n and ) at t he end of t he subpat t er n.
Q&A
Q: How many subpat t er ns can be st or ed in memor y using \1, \2, and so on?
A: Basical l y, as many as you l ike. Af t er you st or e mor e t han nine pat t er ns, you can
r et r ieve t he l at er pat t er ns using t wo-digit number s pr eceded by a backsl ash,
such as \10.
Q: Why does pat t er n-memor y var iabl e number ing st ar t wit h 1, wher eas
subscr ipt number ing st ar t s wit h 0?
A: Subscr ipt number ing st ar t s wit h 0 t o r emain compat ibl e wit h t he C pr ogr amming
l anguage. Ther e is no such t hing as pat t er n memor y in C, so t her e is no need t o be
compat ibl e wit h it .
Q: What happens when t he r epl acement st r ing in t he t r ansl at e command is l ef t
out , as in tr/abc//?
A: If t he r epl acement st r ing is omit t ed, a copy of t he f ir st st r ing is used. This means
t hat
:t:r/abc//
does not do anyt hing, because it is t he same as
tr/abc/abc/
If t he r epl acement st r ing is omit t ed in t he subst it ut e command, as in
s/abc//
t he pat t er n mat ched-in t his case, abc-is del et ed.
Q: Why does Per l use char act er s such as +, *, and ? as pat t er n special
char act er s?
A: These special char act er s usual l y cor r espond t o special char act er s used in ot her
UNIX appl icat ions, such as vi and csh. Some of t he special char act er s, such as +,
ar e used in f or mal synt ax descr ipt ion l anguages.
Q: Why does Per l use bot h \1 and $1 t o st or e pat t er n memor y?
A: To enabl e you t o dist inguish bet ween a subpat t er n mat ched in t he cur r ent
pat t er n (which is st or ed in \1) and a subpat t er n mat ched in t he pr evious
st at ement (which is st or ed in $1).
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. What do t he f ol l owing pat t er ns mat ch?
a. /a|bc*/
b. /[\d]{1,3}/
c. /\bc[aou]t\b/
d. /(xy+z)\.\1/
e. /^$/
2. Wr it e pat t er ns t hat mat ch t he f ol l owing:
a. Five or mor e l ower case l et t er s (a-z).
b. Eit her t he number 1 or t he st r ing one.
c. st r ing of digit s opt ional l y cont aining a decimal point .
d. Any l et t er , f ol l owed by any vowel , f ol l owed by t he same l et t er again.
e. One or mor e + char act er s.
3. Suppose t he var iabl e $var has t he val ue abc123. Indicat e whet her t he f ol l owing
condit ional expr essions r et ur n t r ue or f al se.
a. $var =~ /./
b. $var =~ /[A-Z]*/
c. $var =~ /\w{4-6}/
d. $var =~ /(\d)2(\1)/
e. $var =~ /abc$/
f. $var =~ /1234?/
4. Suppose t he var iabl e $var has t he val ue abc123abc. What is t he val ue of $var
af t er t he f ol l owing subst it ut ions?
a. $var =~ s/abc/def/;
b. $var =~ s/[a-z]+/X/g;
c. $var =~ s/B/W/i;
d. $var =~ s/(.)\d.*\1/d/;
e. $var =~ s/(\d+)/$1*2/e;
5. Suppose t he var iabl e $var has t he val ue abc123abc. What is t he val ue of $var
af t er t he f ol l owing t r ansl at ions?
a. $var =~ tr/a-z/A-Z/;
b. $var =~ tr/123/456/;
c. $var =~ tr/231/564/;
d. $var =~ tr/123/ /s;
e. $var =~ tr/123//cd;
Exercises
1. Wr it e a pr ogr am t hat r eads al l t he input f r om t he st andar d input f il e, conver t s
al l t he vowel s (except y) t o upper case, and pr int s t he r esul t on t he st andar d
out put f il e.
2. Wr it e a pr ogr am t hat count s t he number of t imes each digit appear s in t he
st andar d input f il e. Pr int t he t ot al f or each digit and t he sum of al l t he t ot al s.
3. Wr it e a pr ogr am t hat r ever ses t he or der of t he f ir st t hr ee wor ds of each input
l ine (f r om t he st andar d input f il e) using t he subst it ut ion oper at or . Leave t he
spacing unchanged, and pr int each r esul t ing l ine.
4. Wr it e a pr ogr am t hat adds 1 t o ever y number in t he st andar d input f il e. Pr int t he
r esul t s.
5. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
while ($line = <STDIN>) {
# put quotes around each line of input
$line =~ /^.*$/"\1"/;
print ($line);
}
6. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
while ($line = <STDIN>) {
if ($line =~ /[\d]*/) {
print ("This line contains the digits '$&'\n");
}
}

Week
1
Week 1 in Review
By now, you know enough about pr ogr amming in Per l t o wr it e pr ogr ams t hat per f or m
many usef ul t asks. The pr ogr am in List ing R1.1, which t akes a number and pr int s out it s
Engl ish equival ent , il l ust r at es some of t he concept s you've l ear ned dur ing your f ir st
week.

List ing R1.1. Pr int ing t he Engl ish equival ent of numer ic input .
1: #!/usr/local/bin/perl
2:
3: # define the strings used in printing
4: @digitword = ("", "one", "two", "three", "four", "five",
5: "six", "seven", "eight", "nine");
6: @digit10word = ("", "ten", "twenty", "thirty", "forty",
7: "fifty", "sixty", "seventy", "eighty", "ninety");
8: @teenword = ("ten", "eleven", "twelve", "thirteen", "fourteen",
9: "fifteen", "sixteen", "seventeen", "eighteen", "nineteen");
10: @groupword = ("", "thousand", "million", "billion", "trillion",
11: "quadrillion", "quintillion", "sextillion", "septillion",
12: "octillion", "novillion", "decillion");
13:
14: # read a line of input and remove all blanks, commas and tabs;
15: # complain about anything else
16: $inputline = <STDIN>;
17: chop ($inputline);
18: $inputline =~ s/[, \t]+//g;
19: if ($inputline =~ /[^\d]/) {
20: die ("Input must be a number.\n");
21: }
22:
23: # remove leading zeroes
24: $inputline =~ s/^0+//;
25: $inputline =~ s/^$/0/; # put one back if they're all zero
26:
27: # split into digits: $grouping contains the number of groups
28: # of digits, and $oddlot contains the number of digits in the
29: # first group, which may be only 1 or 2 (e.g., the 1 in 1,000)
30: @digits = split(//, $inputline);
31: if (@digits > 36) {
32: die ("Number too large for program to handle.\n");
33: }
34: $oddlot = @digits % 3;
35: $grouping = (@digits-1) / 3;
36:
37: # this loop iterates once for each grouping
38: $count = 0;
39: while ($grouping >= 0) {
40: if ($oddlot == 2) {
41: $digit1 = 0;
42: $digit2 = $digits[0];
43: $digit3 = $digits[1];
44: $count += 2;
45: } elsif ($oddlot == 1) {
46: $digit1 = 0;
47: $digit2 = 0;
48: $digits = $digits[0];
49: $count += 1;
50: } else { # regular group of three digits
51: $digit1 = $digits[$count];
52: $digit2 = $digits[$count+1];
53: $digit3 = $digits[$count+2];
54: $count += 3;
55: }
56: $oddlot = 0;
57: if ($digit1 != 0) {
58: print ("$digitword[$digit1] hundred ");
59: }
60: if (($digit1 != 0 || ($grouping == 0 && $count > 3)) &&
61: ($digit2 != 0 || $digit3 != 0)) {
62: print ("and ");
63: }
64: if ($digit2 == 1) {
65: print ("$teenword[$digit3] ");
66: } elsif ($digit2 != 0 && $digit3 != 0) {
67: print ("$digit10word[$digit2]-$digitword[$digit3]
");
68: } elsif ($digit2 != 0 || $digit3 != 0) {
69: print ("$digit10word[$digit2]$digitword[$digit3]
");
70: }
71: if ($digit1 != 0 || $digit2 != 0 || $digit3 != 0) {
72: print ("$groupword[$grouping]\n");
73: } elsif ($count <= 3 && $grouping == 0) {
74: print ("zero\n");
75: }
76: $grouping-;
77: }

$ programR1_1
11,683
eleven thousand
six hundred and eighty-three
$
This pr ogr am r eads in a number up t o 36 digit s l ong and pr int s out it s Engl ish
equival ent , using one l ine f or each gr oup of t hr ee digit s.
Lines 4-12 def ine ar r ay var iabl es whose l ist s ar e t he possibl e wor ds t hat can be in a
number . The var iabl e @digitword l ist s t he digit s; @digit10word l ist s t he wor ds t hat
indicat e mul t ipl es of t en; @teenword l ist s t he wor ds t hat r epr esent t he val ues f r om 11 t o
19; and @groupword l ist s t he names f or each gr oup of digit s. Not e t hat some of t hese l ist s
have an empt y f ir st el ement ; t his ensur es t hat t he ar r ay subscr ipt s r ef er t o t he cor r ect
val ue. (For exampl e, wit hout t he empt y wor d at t he beginning of @digitword,
$digitword[5] woul d r ef er t o four, not five.)
Lines 14-21 r ead t he input and check whet her it is val id. Val id number s consist of digit s
opt ional l y separ at ed by spaces, t abs, or commas. The subst it ut ion oper at or in l ine 18
r emoves t hese val id separ at or s; t he condit ional expr ession in l ine 19 checks whet her any
inval id separ at or s exist .
If t he pr ogr am r eaches l ine 24, t he input number is val id. Line 24 get s r id of any l eading
zer os (t o ensur e t hat , f or exampl e, 000071 is conver t ed t o 71). If a number consist s
ent ir el y of zer os, l ine 24 conver t s $inputline t o t he empt y st r ing; l ine 25 t est s f or t his
empt y st r ing and adds a zer o if necessar y.
Lines 30-35 spl it t he number int o individual digit s and cr eat e a l ist consist ing of t hese
digit s. This l ist is assigned t o t he ar r ay var iabl e @digits. Line 34 det er mines whet her t he
f ir st gr oup of digit s cont ains f ewer t han t hr ee digit s; an exampl e of t his is t he number
45,771, whose f ir st gr oup of digit s consist s of onl y t wo digit s. The scal ar var iabl e
$oddlot is assigned t he number of digit s in t he f ir st gr oup if t he gr oup is an odd l ot of
one or t wo; it is assigned 0 if t he f ir st gr oup of digit s cont ains al l t hr ee digit s.
Line 35 cal cul at es t he number of gr oups of digit s (incl uding t he init ial odd l ot ). This
det er mines t he number of t imes t hat t he upcoming pr int ing l oop is t o be it er at ed.
Lines 38-79 act ual l y pr int t he Engl ish val ue f or t his number . Each gr oup of t hr ee digit s
is pr int ed on it s own l ine. The scal ar var iabl e $count cont ains t he number of digit s
pr int ed so f ar and is used as a subscr ipt f or t he ar r ay var iabl e @digits.
To act ual l y pr int t he Engl ish val ue cor r esponding t o a gr oup of t hr ee digit s, t his l oop
f ir st execut es l ines 40-57, which assign t he val ues of t he digit s in t he gr oup t o t hr ee
scal ar var iabl es: $digit1, $digit2, and $digit3. If t he gr oup being handl ed is t he f ir st
gr oup, l ines 40 and 46 check whet her t he gr oup is an odd l ot . For exampl e, if t he f ir st
gr oup cont ains onl y t wo digit s, t he condit ion in l ine 40 becomes t r ue, and t he var iabl e
$digit1, which r epr esent s t he f ir st digit of t he gr oup, is assigned 0. Using $digit1,
$digit2, and $digit3 r educes t he compl exit y of t he pr ogr am because no code f ol l owing
l ine 57 has t o check f or t he val ue of $oddlot.
The number of digit s act ual l y handl ed is added t o t he scal ar var iabl e $count at t his
point .
Line 58 assigns 0 t o $oddlot. Subsequent gr oups of digit s al ways cont ain t hr ee digit s.
Lines 59-77 pr int t he Engl ish val ue associat ed wit h t his par t icul ar gr oup of digit s as
f ol l ows:
1. Lines 59-61 pr int t he val ue of t he hundr eds pl ace in t his gr oup (t he f ir st of t he
t hr ee digit s).
2. Lines 62-64 check whet her t he wor d and needs t o appear her e. The wor d and is
r equir ed in t he f ol l owing cases:
H $digit1 is nonzer o and one of t he ot her digit s is nonzer o (as in three
hundred and four)
H $digit1 is zer o, one of t he ot her digit s is nonzer o, and t his is t he l ast gr oup
t o be handl ed (as in t he and four par t of t he number 11,004)
3. If t he second digit is a 1 (as in 317), one of t he "t een wor ds" (such as eleven, twelve,
and thirteen) must be used. Line 66 checks f or t his condit ion, and l ine 67 pr int s
t he appr opr iat e wor d.
4. If bot h of t he l ast t wo digit s ar e def ined, t hey bot h must be pr int ed, and a dash
must separ at e t hem (as in forty-two). Line 69 pr int s t his pair of wor ds and t he dash.
5. If onl y one of t he l ast t wo digit s is def ined, it is pr int ed using l ine 71. (Not e t hat
l ine 71 act ual l y specif ies t hat bot h digit s ar e pr int ed; however , because onl y one
is act ual l y nonzer o, it is t he onl y one t hat appear s. The digit t hat is zer o appear s
in t he out put as t he empt y st r ing because zer o is equival ent t o t he empt y st r ing in
Per l .)
6. Lines 73-74 pr int t he wor d associat ed wit h t his gr oup of digit s. For exampl e, if t his
gr oup is t he second-l ast gr oup of digit s, t he wor d thousand is pr int ed.
7. Line 75 handl es t he special case of t he number 0. In t his case, t he wor d zero is
pr int ed.
Once t he Engl ish val ue f or a par t icul ar gr oup of digit s is pr int ed, t he scal ar var iabl e
$grouping has it s val ue decr eased by one, and t he pr ogr am cont inues wit h t he next
gr oup of digit s. If t her e ar e no mor e digit s t o pr int , t he pr ogr am t er minat es.

Week
2
Week 2 at a Glance
CONTENTS
G Wher e You'r e Going
By now, you know enough about Per l t o wr it e many usef ul pr ogr ams. You've discover ed
t hat Per l is power f ul enough t o enabl e you t o per f or m compl icat ed t asks, and simpl e
enough t o accompl ish t hem quickl y.
Where You're Going
The second week cover s most of t he f eat ur es of t he l anguage not cover ed in t he f ir st
week and descr ibes some of t he many l ibr ar y f unct ions suppl ied wit h Per l . Her e's a
summar y of what you'l l l ear n.
Day 8, "Mor e Cont r ol St r uct ur es," discusses t he cont r ol f l ow st at ement s not pr eviousl y
cover ed.
Day 9, "Using Subr out ines," shows how you can br eak down your pr ogr am int o mor e
manageabl e chunks.
Day 10, "Associat ive Ar r ays," int r oduces one of t he most power f ul and usef ul const r uct s
in Per l , associat ive ar r ays, and it shows how you can use t hese ar r ays t o simul at e ot her
dat a st r uct ur es.
Day 11, "For mat t ing Your Out put ," shows how you can use Per l t o pr oduce t idy r epor t s.
Day 12, "Wor king wit h t he Fil e Syst em," shows how you can int er act wit h your syst em's
dir ect or y st r uct ur e.
Day 13, "Pr ocess, St r ing, and Mat hemat ical Funct ions," descr ibes t he l ibr ar y f unct ions
t hat int er act wit h pr ocesses r unning on t he syst em, oper at e on t ext st r ings, and per f or m
mat hemat ical oper at ions.
Day 14, "Scal ar -Conver sion and List -Manipul at ion Funct ions," descr ibes t he l ibr ar y
f unct ions t hat conver t val ues f r om one f or m t o anot her and wor k wit h l ist s and ar r ay
var iabl es.
By t he end of t he second week, you'l l have mast er ed al most al l of t he f eat ur es of Per l
and you'l l have l ear ned about many of t he l ibr ar y f unct ions suppl ied wit h t he
l anguage.

Chapter 8
More Control Structures
CONTENTS
G Using Singl e-Line Condit ional St at ement s
H Pr obl ems wit h Singl e-Line Condit ional St at ement s
G Looping Using t he for St at ement
H Using t he Comma Oper at or in a for St at ement
G Looping Thr ough a List : The foreach St at ement
H The foreach Local Var iabl e
H Changing t he Val ue of t he Local Var iabl e
H Using Ret ur ned List s in t he foreach St at ement
G The do St at ement
G Exit ing a Loop Using t he last St at ement
G Using next t o St ar t t he Next It er at ion of a Loop
G The redo St at ement
G Using Label ed Bl ocks f or Mul t il evel Jumps
H Using next and redo wit h Label s
G The continue Bl ock
G The goto St at ement
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
On Day 2, "Basic Oper at or s and Cont r ol Fl ow," you l ear ned about some of t he simpl er
condit ional st at ement s in Per l , incl uding t he f ol l owing:
G The if st at ement , which def ines st at ement s t hat ar e execut ed onl y when a
cer t ain condit ion is t r ue
G The if-else st at ement , which chooses bet ween t wo al t er nat ives
G The if-elsif-else st at ement , which chooses bet ween mul t ipl e al t er nat ives
G The unless st at ement , which def ines st at ement s t hat ar e execut ed unl ess a
specif ied condit ion is t r ue
G The while st at ement , which execut es a gr oup of st at ement s whil e a specif ied
condit ion is t r ue
G The until st at ement , which execut es a gr oup of st at ement s unt il a specif ied
condit ion is t r ue
Today's l esson t al ks about t he ot her cont r ol st r uct ur es in Per l ; t hese cont r ol
st r uct ur es give you a gr eat deal of f l exibil it y when you ar e det er mining t he or der of
execut ion of your pr ogr am st at ement .
Today you l ear n t he f ol l owing cont r ol st r uct ur es:
G Singl e-l ine condit ional st at ement s
G The for st at ement
G The foreach st at ement
G The do st at ement
G The last st at ement
G The next st at ement
G The redo st at ement
G The continue st at ement
G Label ed bl ocks
G The goto st at ement
Using Single-Line Conditional Statements
On Day 2 you saw t he if st at ement , which wor ks as f ol l ows:
if ($var == 0) {
print ("This is zero.\n");
}
If t he st at ement bl ock inside t he if st at ement consist s of onl y one st at ement , Per l
enabl es you t o wr it e t his in a mor e convenient way using a single-line conditional statement.
This is a condit ional st at ement whose st at ement bl ock cont ains onl y one l ine of code.
The f ol l owing singl e-l ine condit ional st at ement is ident ical t o t he if st at ement
def ined pr eviousl y:
print ("This is zero.\n") if ($var == 0);
Singl e-l ine condit ional st at ement s al so wor k wit h unless, while, and until:
print ("This is zero.\n") unless ($var != 0);
print ("Not zero yet.\n") while ($var-- > 0);
print ("Not zero yet.\n") until ($var-- == 0);
In al l f our cases, t he synt ax of t he singl e-l ine condit ional st at ement is t he same.
The synt ax f or t he singl e-l ine condit ional st at ement is
statement keyword condexpr
Her e, statement is any Per l st at ement . keyword is eit her if, unless, while, or until.
condexpr is t he condit ional expr ession t hat is eval uat ed.
statement is execut ed in t he f ol l owing cases:
G If keyword is if, st at ement is execut ed if condexpr is t r ue.
G If keyword is unless, st at ement is execut ed unl ess condexpr is t r ue.
G If keyword is while, st at ement is execut ed whil e condexpr is t r ue.
G If keyword is until, st at ement is execut ed unt il condexpr is t r ue.
To see how singl e-l ine condit ional expr essions can be usef ul , l ook at t he f ol l owing
exampl es, st ar t ing wit h List ing 8.1. This is a simpl e pr ogr am t hat copies one f il e t o
anot her . Singl e-l ine condit ional st at ement s ar e used t o check whet her t he f il es opened
successf ul l y, and anot her singl e-l ine condit ional st at ement act ual l y copies t he f il e.

List ing 8.1. A pr ogr am t hat uses singl e-l ine condit ional st at ement s t o
copy one f il e t o anot her .
1: #!/usr/local/bin/perl
2:
3: die ("Can't open input\n") unless (open(INFILE, "infile"));
4: die ("Can't open output\n") unless (open(OUTFILE, ">outfile"));
5: print OUTFILE ($line) while ($line = <INFILE>);
6: close (INFILE);
7: close (OUTFILE);

Ther e is no out put ; t his pr ogr am wr it es t o a f il e.
As you can see, t his pr ogr am is cl ear and concise. Inst ead of using t hr ee l ines
t o open a f il e and check it , as in
unless (open (INFILE, "infile")) {
die ("Can't open input\n");
}
you can now use just one:
die ("Can't open input\n") unless (open(INFILE, "infile"));
Line 3 opens t he input f il e. If t he open is not successf ul , t he pr ogr am t er minat es by
cal l ing die.
Line 4 is simil ar t o l ine 3. It opens t he out put f il e and checks whet her t he f il e act ual l y
is open; if t he f il e is not open, t he pr ogr am t er minat es.
Line 5 act ual l y copies t he f il e. The condit ional expr ession
$line = <INFILE>
r eads a l ine f r om t he f il e r epr esent ed by t he f il e var iabl e INFILE and assigns it t o $line.
If t he l ine is empt y, t he condit ional expr ession is f al se, and t he while st at ement st ops
execut ing. If t he l ine is not empt y, it is wr it t en t o OUTFILE.
NOTE
The condit ional expr ession in a singl e-l ine condit ional
st at ement is al ways execut ed f ir st , even t hough it
appear s at t he end of t he st at ement . For exampl e:
print OUTFILE ($line) while ($line = <INFILE>);
Her e, t he condit ional expr ession t hat r eads a l ine of
input and assigns it t o $line is al ways execut ed f ir st .
This means t hat print is not cal l ed unt il $line cont ains
somet hing t o pr int . This al so means t hat t he cal l t o
print is never execut ed if INFILE is an empt y f il e (which
is what you want ).
Because singl e-l ine condit ional expr essions ar e
"backwar d," be car ef ul when you use t hem wit h
anyt hing mor e compl icat ed t han what you see her e.
You can use t he singl e-l ine condit ional st at ement in conjunct ion wit h t he
aut oincr ement oper at or ++ t o wr it e a l oop in a singl e l ine. For exampl e, examine List ing
8.2, which pr int s t he number s f r om 1 t o 5 using a singl e-l ine condit ional st at ement .

List ing 8.2. A pr ogr am t hat l oops using a singl e-l ine condit ional
st at ement .
1: #!/usr/local/bin/perl
2:
3: $count = 0;
4: print ("$count\n") while ($count++ < 5);

$ program8_2
1
2
3
4
5
$
When t he Per l int er pr et er execut es l ine 3, it f ir st eval uat es t he condit ional
expr ession
$count++ < 5
Because t he ++ appear s af t er $count, 1 is added t o t he val ue of $count af t er t he
condit ional expr ession is eval uat ed. This means t hat $count has t he val ue 0, not 1, t he
f ir st t ime t he expr ession is eval uat ed. Simil ar l y, $count has t he val ue 1 t he second t ime,
2 t he t hir d t ime, 3 t he f our t h t ime, and 4 t he f if t h t ime. In each of t hese f ive cases, t he
condit ional expr ession eval uat es t o t r ue, which means t hat t he l oop it er at es f ive t imes.
Af t er t he condit ional expr ession has been eval uat ed, t he ++ oper at or adds 1 t o t he
val ue of $count. This new val ue of $count is t hen pr int ed. This means t hat when t he l oop
is f ir st execut ed, t he cal l t o print pr int s 1, even t hough t he val ue of $count was 0 when
t he condit ional expr ession was eval uat ed.
Problems with Single-Line Conditional Statements
Al t hough singl e-l ine condit ional st at ement s t hat cont ain l oops ar e usef ul , t her e ar e
pr obl ems. Consider List ing 8.2, which you've just seen. It is easy t o f or get t hat $count has
t o be init ial ized t o one l ess t han t he f ir st val ue you want t o use in t he l oop, and t hat
t he condit ional expr ession has t o use t he < oper at or , not t he <= oper at or .
For exampl e, t ake a l ook at t he f ol l owing:
$count = 1;
print ("$count\n") while ($count++ < 5);
Her e, you have t o l ook cl osel y t o see t hat t he f ir st val ue pr int ed is 2, not 1.
Her e is anot her l oop cont aining a mist ake:
$count = 0;
print ("$count\n") while ($count++ <= 5);
This l oop it er at es six t imes, not f ive; t he sixt h t ime t hr ough t he l oop, $count has t he
val ue 5 when t he condit ional expr ession is eval uat ed. The expr ession eval uat es t o t r ue,
$count is incr ement ed t o 6, and print t her ef or e pr int s t he val ue 6.
Her e is a r el at ed but sl ight l y mor e subt l e pr obl em:
$count = 0;
print ("$count\n") while ($count++ < 5);
print ("The total number of iterations is $count.\n");
This l oop it er at es f ive t imes, which is what you want . However , af t er t he condit ional
expr ession is eval uat ed f or t he f inal t ime, t he val ue of $count becomes 6, as f ol l ows:
G Bef or e t he condit ional expr ession is eval uat ed, $count has t he val ue 5.
G Because t he val ue of $count is not l ess t han 5, t he condit ional expr ession
eval uat es t o f al se, which t er minat es t he l oop.
G Af t er t he condit ional expr ession is eval uat ed, t he ++ oper at or adds one t o $count,
giving it t he val ue 6.
This means t hat t he f inal print st at ement pr int s t he f ol l owing, which is pr obabl y not
what you want :
The total number of iterations is 6.
DO use t he for st at ement as a convenient way t o wr it e a
concise, compact l oop. It is discussed in t he next sect ion.
DON' T use t he ++ oper at or t o pr oduce a l oop in a singl e-
l ine condit ional st at ement unl ess it 's absol ut el y
necessar y. It 's just t oo easy t o go wr ong wit h it .
Looping Using the for Statement
Many of t he pr ogr ams t hat you've seen so f ar use t he while st at ement t o cr eat e a
pr ogr am l oop. Her e is a simpl e exampl e:
$count = 1;
while ($count <= 5) {
# statements inside the loop go here
$count++;
}
This l oop cont ains t hr ee it ems t hat cont r ol it :
1. A st at ement t hat set s t he init ial val ue of t he l oop. In t his l oop, t he scal ar
var iabl e $count is used t o cont r ol t he number of it er at ions of t he l oop, and t he
st at ement
$count = 1;
set s t he init ial val ue of $count t o 1. St at ement s such as t his ar e cal l ed loop
initializers.
2. A condit ional expr ession t hat checks t o see whet her t o cont inue it er at ing t he
l oop. In t his case, t he condit ional expr ession
$count <= 5
is eval uat ed; if it is f al se, t he l oop is t er minat ed.
3. A st at ement t hat changes t he val ue of t he var iabl e which is t est ed in t he
condit ional expr ession. In t his l oop, t he st at ement
count++;
adds 1 t o t he val ue of $count, which is t he scal ar var iabl e being t est ed in t he
condit ional expr ession. St at ement s such as t his ar e cal l ed loop iterators.
Per l enabl es you t o put t he t hr ee component s t hat cont r ol a l oop t oget her on a singl e
l ine using a for st at ement . For exampl e, t he f ol l owing st at ement is equival ent t o t he
l oop you've been l ooking at :
for ($count=1; $count <= 5; $count++) {
# statements inside the loop go here
}
Her e, t he t hr ee cont r ol l ing component s-t he l oop init ial izer , t he condit ional expr ession,
and t he l oop it er at or -appear t oget her , and ar e separ at ed by semicol ons.
The synt ax of t he for st at ement is
for (expr1; expr2; expr3) {
statement_block
}
expr1 is t he l oop init ial izer . It is eval uat ed onl y once, bef or e t he st ar t of t he l oop.
expr2 is t he condit ional expr ession t hat t er minat es t he l oop. The condit ional expr ession
in expr2 behaves just l ike t he ones in while and if st at ement s. If it s val ue is 0 (f al se),
t he l oop is t er minat ed, and if it s val ue is nonzer o, t he l oop is execut ed.
statement_block is t he col l ect ion of st at ement s t hat is execut ed if (and when) expr2 has
a nonzer o val ue.
expr3 is execut ed once per it er at ion of t he l oop and is execut ed af t er t he l ast st at ement
in statement_block is execut ed.
NOTE
If you know t he C pr ogr amming l anguage, t he for
st at ement wil l be f amil iar t o you. The for st at ement in
Per l is synt act ical l y ident ical t o t he for st at ement in C.
List ing 8.3 is a pr ogr am based on t he exampl e for st at ement you've just seen.

List ing 8.3. A pr ogr am t hat pr int s t he number s f r om 1 t o 5 using t he for
st at ement .
1: #!/usr/local/bin/perl
2:
3: for ($count=1; $count <= 5; $count++) {
4: print ("$count\n");
5: }

$ program8_3
1
2
3
4
5
$
Line 3 of t he pr ogr am is t he st ar t of t he for st at ement . The f ir st expr ession
def ined in t he for st at ement , $count = 1, is t he l oop init ial izer ; it is execut ed bef or e t he
l oop is it er at ed.
The second expr ession def ined in t he for st at ement , $count <= 5, t est s whet her t o
cont inue it er at ing t he l oop.
The t hir d expr ession def ined in t he for st at ement , $count++, is eval uat ed af t er t he l ast
st at ement in t he l oop, l ine 4, is execut ed.
As you can see f r om t he out put , t he l oop is it er at ed f ive t imes.
TIP
Use t he for st at ement inst ead of while or until
whenever possibl e; when you use t he for st at ement , it is
easier t o avoid inf init e l oops.
For exampl e, when you use a while st at ement , it 's easy t o
f or get t o it er at e t he l oop. The f ol l owing is an exampl e:
$count = 1;
while ($count <= 5) {
print ("$count\n");
}
The equival ent st at ement using for is
for ($count = 1; $count <= 5; ) {
print ("$count\n");
}
When you use t he for st at ement , it is easier t o not ice
t hat t he l oop it er at or is missing.
Using the Comma Operator in a for Statement
Some l oops need t o per f or m mor e t han one act ion bef or e it er at ing. For exampl e, consider
t he f ol l owing l oop, which r eads f our l ines of input f r om t he st andar d input f il e and
pr int s t hr ee of t hem:
$line = <STDIN>;
$count = 1;
while ($count <= 3) {
print ($line);
$line = <STDIN>;
$count++;
}
This l oop needs t wo l oop init ial izer s and t wo l oop it er at or s: one of each f or t he
var iabl e $count, and one of each t o r ead anot her l ine of input f r om STDIN.
At f ir st gl ance, you might t hink t hat you can't wr it e t his l oop using t he for st at ement .
However , you can use t he comma oper at or t o combine t he t wo l oop init ial izer s and t he
t wo l oop it er at or s int o singl e expr essions. List ing 8.4 does t his.

List ing 8.4. A pr ogr am t hat uses t he for st at ement t o r ead f our input
l ines and wr it e t hr ee of t hem.
1: #!/usr/local/bin/perl
2:
3: for ($line = <STDIN>, $count = 1; $count <= 3;
4: $line = <STDIN>, $count++) {
5: print ($line);
6: }

$ program8_4
This is my first line.
This is my first line.
This is my second line.
This is my second line.
This is my last line.
This is my last line.
This input line is not written out.
$
The l oop init ial izer in t his for st at ement is t he expr ession
$line = <STDIN>, $count = 1
The comma oper at or in t his expr ession t el l s t he Per l int er pr et er t o eval uat e t he f ir st
hal f of t he expr ession-t he par t t o t he l ef t of t he comma-and t hen eval uat e t he second
hal f . The f ir st hal f of t his expr ession r eads a l ine f r om t he st andar d input f il e and
assigns it t o $line; t he second hal f of t he expr ession assigns 1 t o $count.
The l oop it er at or al so consist s of t wo par t s:
$line = <STDIN>, $count++
This expr ession r eads a l ine f r om t he st andar d input f il e and adds 1 t o t he var iabl e
keeping t r ack of when t o t er minat e t he l oop, which is $count.
Don't use t he for st at ement if you have a l ar ge number
of l oop init ial izer s or l oop it er at or s, because st at ement s
t hat cont ain a l ar ge number of comma oper at or s ar e
dif f icul t t o r ead.
Looping Through a List: The foreach Statement
One common use of l oops is t o per f or m an oper at ion on ever y el ement of a l ist st or ed in
an ar r ay var iabl e. For exampl e, t he f ol l owing l oop checks whet her any el ement of t he
l ist st or ed in t he ar r ay var iabl e @words is t he wor d the:
$count = 1;
while ($count <= @words) {
if ($words[$count-1] eq "the") {
print ("found the word 'the'\n");
}
$count++;
}
As you've seen, you can use t he for st at ement t o simpl if y t his l oop, as f ol l ows:
for ($count = 1; $count <= @words; $count++) {
if ($words[$count-1] eq "the") {
print ("found the word 'the'\n");
}
}
Per l pr ovides an even simpl er way t o do t he same t hing, using t he foreach st at ement . The
f ol l owing l oop, which uses foreach, is ident ical t o t he pr eceding one:
foreach $word (@words) {
if ($word eq "the") {
print ("found the word 'the'\n");
}
}
The synt ax f or t he foreach st at ement is
foreach localvar (listexpr) {
statement_block;
}
Her e, listexpr is any l ist or ar r ay var iabl e, and statement_block is a col l ect ion of
st at ement s t hat is execut ed ever y t ime t he l oop it er at es.
localvar is a scal ar var iabl e t hat is def ined onl y f or t he dur at ion of t he foreach
st at ement . The f ir st t ime t he l oop is execut ed, localvar is assigned t he val ue of t he f ir st
el ement of t he l ist in listexpr. Each subsequent t ime t he l oop is execut ed, localvar is
assigned t he val ue of t he next el ement of listexpr.
List ing 8.5 shows how t his wor ks.

List ing 8.5. A demonst r at ion of t he foreach st at ement .
1: #!/usr/local/bin/perl
2:
3: @words = ("Here", "is", "a", "list.");
4: foreach $word (@words) {
5: print ("$word\n");
6: }

$ program8_5
Here
is
a
list.
$
The foreach st at ement in l ine 4 assigns a wor d f r om @list t o t he l ocal
var iabl e $word. The f ir st t ime t he l oop is execut ed, t he val ue st or ed in $word is t he
st r ing Here. The second t ime t he l oop is execut ed, t he val ue st or ed in $word is is.
Subsequent it er at ions assign a and list. t o $word.
The l oop def ined by t he foreach st at ement t er minat es af t er al l of t he wor ds in t he l ist
have been assigned t o $word.
NOTE
In Per l , t he for st at ement and t he foreach st at ement
ar e act ual l y synonymous: you can use for wher ever
foreach is expect ed, and vice ver sa.
The foreach Local Variable
Not e t hat t he scal ar var iabl e def ined in t he foreach st at ement is def ined onl y f or t he
dur at ion of t he l oop. If a val ue is assigned t o t he scal ar var iabl e pr ior t o t he execut ion
of t he foreach st at ement , t his val ue is r est or ed af t er t he foreach is execut ed. List ing 8.6
shows how t his wor ks.

List ing 8.6. A pr ogr am t hat uses t he same name inside and out side a
foreach st at ement .
1: #!/usr/local/bin/perl
2:
3: $temp = 1;
4: @list = ("This", "is", "a", "list", "of", "words");
5: print ("Here are the words in the list: \n");
6: foreach $temp (@list) {
7: print ("$temp ");
8: }
9: print("\n");
10: print("The value of temp is now $temp\n");

$ program8_6
Here are the words in the list:
This is a list of words
The value of temp is now 1
$
Line 3 assigns 1 t o t he scal ar var iabl e $temp.
The foreach st at ement t hat pr int s t he wor ds in t he l ist is def ined in l ines 6-8. This
st at ement assigns t he el ement s of @list t o $temp, one per it er at ion of t he l oop.
Af t er t he l oop is t er minat ed, t he or iginal val ue of $temp is r est or ed, which is 1. This
val ue is pr int ed by l ine 10.
Var iabl es (such as $temp in l ines 6-8) t hat ar e onl y def ined f or par t of a pr ogr am ar e
known as local variables; var iabl es t hat ar e def ined t hr oughout a pr ogr am ar e known as
global variables. You'l l see mor e exampl es of l ocal var iabl es on Day 9, "Using
Subr out ines."
TIP
It is not a good idea t o use $temp t he way it is used in
List ing 8.6, namel y, as bot h a l ocal and a gl obal
var iabl e. You might f or get t hat t he val ue of t he gl obal
var iabl e-in t he case of $temp, t he val ue 1-is over wr it t en
by t he val ue assigned in t he foreach st at ement .
Conver sel y, you might f or get t hat t he val ue assigned t o
$temp in t he foreach st at ement is l ost when t he foreach
is f inished.
It is bet t er t o def ine a new scal ar var iabl e name f or t he
l ocal var iabl e, t o avoid conf usion.
Changing the Value of the Local Variable
Not e t hat changing t he val ue of t he l ocal var iabl e inside a foreach st at ement al so
changes t he val ue of t he cor r esponding el ement of t he l ist . For exampl e:
@list = (1, 2, 3, 4, 5);
foreach $temp (@list) {
if ($temp == 2) {
$temp = 20;
}
}
In t his l oop, when $temp is equal t o 2, $temp is r eset t o 20. Ther ef or e, t he l ist st or ed in
t he ar r ay var iabl e @list becomes (1, 20, 3, 4, 5).
Use t his f eat ur e wit h caut ion, because it is not obvious t hat t he val ue of @list has
changed.
Using Returned Lists in the foreach Statement
So f ar , al l of t he exampl es of t he foreach st at ement t hat you've seen have it er at ed
using t he cont ent s of an ar r ay var iabl e. For exampl e, consider t he f ol l owing:
@list = ("This", "is", "a", "list");
foreach $temp (@list) {
print ("$temp ");
}
This l oop assigns This t o $temp t he f ir st t ime t hr ough t he l oop, and t hen assigns is, a,
and list t o $temp on subsequent it er at ions.
You al so can use l ist const ant s or t he r et ur n val ues f r om f unct ions in foreach
st at ement s. For exampl e, t he pr eceding st at ement s can be wr it t en as f ol l ows:
foreach $temp ("This", "is", "a", "list") {
print("$temp ");
}
As bef or e, $temp is assigned This, is, a, and list in successive it er at ions of t he foreach
l oop.
List ing 8.7 shows how you can use t he r et ur n val ue f r om a f unct ion as a l oop it er at or .

List ing 8.7. A pr ogr am t hat pr int s out t he wor ds in a l ine in r ever se-
sor t ed or der .
1: #!/usr/local/bin/perl
2:
3: $line = <STDIN>;
4: $line =~ s/^\s+//;
5: $line =~ s/\s+$//;
6: foreach $word (reverse sort split(/[\t ]+/, $line)) {
7: print ("$word ");
8: }
9: print ("\n");

$ program8_7
here is my test line
test my line is here
$
Bef or e spl it t ing t he input l ine int o wor ds using split, t his pr ogr am f ir st
r emoves t he l eading and t r ail ing whit e space. (If l eading and t r ail ing space is not
r emoved, split cr eat es an empt y wor d.) Line 4 r emoves l eading spaces and t abs f r om t he
input l ine. Line 5 r emoves any t r ail ing spaces and t abs as wel l as t he cl osing newl ine
char act er .
Lines 6-8 cont ain t he foreach l oop. The l ist used in t his l oop is cr eat ed as f ol l ows:
1. Fir st , split br eaks t he input l ine int o wor ds. The l ist r et ur ned by split is
("here", "is", "my", "test", "line").
2. The l ist r et ur ned by split is passed t o t he buil t -in f unct ion sort, which sor t s t he
l ist . The l ist r et ur ned by sort is ("here", "is", "line", "my", "test").
3. The l ist r et ur ned by sort is passed t o anot her buil t -in f unct ion, reverse. This
r ever ses t he sor t ed l ist , pr oducing t he l ist ("test", "my", "line", "is",
"here").
4. Each el ement of t he l ist r et ur ned by reverse is assigned, in t ur n, t o t he l ocal
scal ar var iabl e $word, st ar t ing wit h "test" and pr oceeding f r om t her e.
Line 7 pr int s t he cur r ent val ue st or ed in $word. Each t ime t he foreach l oop it er at es, a
dif f er ent val ue in t he l ist is pr int ed.
NOTE
The code f r agment
foreach $word (reverse sort split(/[\t ]+/, $line))
shows why omit t ing par ent heses when cal l ing buil t -in
f unct ions can somet imes be usef ul . If al l t he par ent heses
ar e incl uded, t his becomes
foreach $word (reverse(sort(split(/[\t ]+/,
$line))))
which is not as r eadabl e.
The do Statement
So f ar , al l of t he l oops you've seen t est t he condit ional expr ession bef or e execut ing t he
l oop. Per l enabl es you t o wr it e l oops t hat al ways execut e at l east once using t he do
st at ement .
The synt ax f or t he do st at ement is
do {
statement_block
} while_or_until (condexpr);
As in ot her condit ional st at ement s, such as t he if st at ement and t he while st at ement ,
statement_block is a bl ock of st at ement s t o be execut ed, and condexpr is a condit ional
expr ession.
while_or_until is eit her t he while keywor d or t he until keywor d. If you use while,
statement_block l oops whil e condexpr is t r ue. For exampl e:
do {
$line = <STDIN>;
} while ($line ne "");
This l oops whil e $line is non-empt y (in ot her wor ds, whil e t he pr ogr am has not r eached
t he end of f il e).
If you use until, statement_block l oops unt il condexpr is t r ue. For exampl e:
do {
$line = <STDIN>;
} until ($line eq "");
This r eads f r om t he st andar d input f il e unt il $line is empt y (again, unt il end of f il e is
r eached).
List ing 8.8 is a simpl e exampl e of a pr ogr am t hat uses a do st at ement .

List ing 8.8. A simpl e exampl e of a do st at ement .
1: #!/usr/local/bin/perl
2:
3: $count = 1;
4: do {
5: print ("$count\n");
6: $count++;
7: } until ($count > 5);

$ program8_8
1
2
3
4
5
$
Lines 4-7 cont ain t he do st at ement , which l oops f ive t imes. Line 7 t est s
whet her t he count ing var iabl e $count is gr eat er t han 5.
NOTE
The do st at ement can al so be used t o cal l subr out ines.
See Day 9, "Using Subr out ines," f or mor e inf or mat ion.
Exiting a Loop Using the last Statement
Nor mal l y, you exit a l oop by t est ing t he condit ional expr ession t hat is par t of t he l oop.
For exampl e, if a l oop is def ined by t he while st at ement , as in t he f ol l owing, t he pr ogr am
exit s t he l oop when t he condit ional expr ession at t he t op of t he l oop, $count <= 10, is
f al se:
while ($count <= 10) {
# statements go here
}
In t he pr eceding case, t he pr ogr am can exit t he l oop onl y af t er execut ing al l of t he
st at ement s in it . Per l enabl es you t o def ine an exit point anywher e in t he l oop using a
special last st at ement .
The synt ax f or t he last st at ement is simpl e:
last;
To see how t he last st at ement wor ks, t ake a l ook at List ing 8.9, which adds a l ist of
number s suppl ied by means of t he st andar d input f il e.

List ing 8.9. A pr ogr am t hat exit s using t he last st at ement .
1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: while (1) {
5: $line = <STDIN>;
6: if ($line eq "") {
7: last;
8: }
9: chop ($line);
10: @numbers = split (/[\t ]+/, $line);
11: foreach $number (@numbers) {
12: if ($number =~ /[^0-9]/) {
13: print STDERR ("$number is not a number\n");
14: }
15: $total += $number;
16: }
17: }
18: print ("The total is $total.\n");

$ program8_9
4 5 7
2 11 6
^D
The total is 35.
$
The l oop t hat r eads and adds number s st ar t s on l ine 4. The condit ional
expr ession at t he t op of t his l oop is t he number 1. Because t his is a nonzer o number , t his
condit ional expr ession al ways eval uat es t o t r ue. Nor mal l y, t his means t hat t he while
st at ement l oops f or ever ; however , because t his pr ogr am cont ains a last st at ement , t he
l oop event ual l y t er minat es.
Line 6 checks whet her t he pr ogr am has r eached t he end of t he st andar d input f il e. To do
t his, it checks whet her t he l ine r ead f r om t he st andar d input f il e, now st or ed in $line,
is empt y. (Recal l t hat t he Ct r l +D char act er , wr it t en her e as ^D, mar ks t he st andar d
input f il e as empt y.)
If t he l ine is empt y, l ine 7, t he last st at ement , is execut ed. This st at ement t el l s t he Per l
int er pr et er t o t er minat e execut ing t he l oop and t o cont inue wit h t he f ir st st at ement
af t er t he l oop, which is l ine 18.
Lines 10-16 add t he number s on t he input l ine t o t he t ot al st or ed in t he scal ar var iabl e
$total. Line 10 br eaks t he l ine int o individual number s, and l ines 11-16 add each number ,
in t ur n, t o $total.
Line 12 checks whet her each number act ual l y consist s of t he digit s 0-9. The pat t er n [^0-
9] mat ches anyt hing t hat is not a digit ; if t he pr ogr am f inds such a char act er , it f l ags
t he number as er r oneous. (The pr ogr am can pr oduce empt y wor ds if l eading or t r ail ing
spaces or t abs exist in t he l ine; t his is not a pr obl em, because [^0-9] doesn't mat ch an
empt y wor d.)
NOTE
You can use t he last st at ement wit h a singl e-l ine
condit ional st at ement . For exampl e,
last if ($count == 5);
t er minat es t he l oop if t he val ue of $count is 5.
You cannot use t he last st at ement inside t he do
st at ement . Al t hough t he do st at ement behaves l ike t he
ot her cont r ol st r uct ur es, it is act ual l y impl ement ed
dif f er ent l y.
Using next to Start the Next Iteration of a Loop
In Per l , t he last st at ement t er minat es t he execut ion of a l oop. To t er minat e a
par t icul ar it er at ion of a l oop, use t he next st at ement .
Like last, t he synt ax f or t he next st at ement is simpl e:
next;
List ing 8.10 is an exampl e t hat uses t he next st at ement . It sums up t he number s f r om 1 t o
a user -specif ied upper l imit and al so pr oduces a separ at e sum of t he number s divisibl e by
2.

List ing 8.10. A pr ogr am t hat sums t he number s f r om 1 t o a specif ied
number and al so sums t he even number s.
1: #!/usr/local/bin/perl
2:
3: print ("Enter the last number in the sum:\n");
4: $limit = <STDIN>;
5: chop ($limit);
6: $count = 1;
7: $total = $eventotal = 0;
8: for ($count = 1; $count <= $limit; $count++) {
9: $total += $count;
10: if ($count % 2 == 1) {
11: # start the next iteration if the number is odd
12: next;
13: }
14: $eventotal += $count;
15: }
16: print("The sum of the numbers 1 to $limit is $total\n");
17: print("The sum of the even numbers is $eventotal\n");

$ program8_10
Enter the last number in the sum:
7
The sum of the numbers 1 to 7 is 28
The sum of the even numbers is 12
$
The l oop in l ines 8-15 adds t he number s t oget her . The st ar t of t he for
st at ement in l ine 8 l oops f ive t imes; t he count er var iabl e, $count, is assigned t he val ues
1, 2, 3, 4, and 5 in successive it er at ions.
Line 9 adds t o t he t ot al of al l t he number s. This st at ement is al ways execut ed.
Line 10 t est s whet her t he cur r ent number -t he cur r ent val ue of $count-is even or odd. If
$count is even, t he condit ional expr ession
$count % 2 == 1
is f al se, and pr ogr am execut ion cont inues wit h l ine 14. If t he cur r ent val ue of $count is
odd, t he Per l int er pr et er execut es l ine 12, t he next st at ement . This st at ement t el l s t he
Per l in-t er pr et er t o st ar t t he next it er at ion of t he l oop.
Not e t hat t he l oop it er at or in t he for st at ement , $count++, is st il l execut ed, even
t hough t he next st at ement skips over par t of t he l oop. This ensur es t hat t he pr ogr am
does not go int o an inf init e l oop.
Because t he next st at ement is execut ed when t he val ue of $count is odd, l ine 14 is
skipped in t his case. This means t hat t he val ue of $count is added onl y when it is even.
Be car ef ul when you use next in a while or until l oop.
The f ol l owing exampl e goes int o an inf init e l oop:
$count = 0;
while ($count <= 10) {
if ($count == 5) {
next;
}
$count++;
}
When $count is 5, t he pr ogr am t el l s Per l t o st ar t t he
next it er at ion of t he l oop. However , t he val ue of $count
is not changed, which means t hat t he expr ession $count
== 5 is st il l t r ue.
To get r id of t his pr obl em, you need t o incr ement $count
bef or e using next, as in t he f ol l owing:
$count = 0;
while ($count <= 10) {
if ($count == 5) {
$count++;
next;
}
$count++;
}
This, by t he way, is why many pr ogr amming pur ist s disl ike
st at ement s such as next and last-it 's t oo easy t o l ose
t r ack of wher e you ar e and what needs t o be updat ed.
The next st at ement enabl es you t o check f or and ignor e unusual condit ions when
r eading input . For exampl e, List ing 8.11 count s t he number of wor ds in t he input r ead
f r om t he st andar d input f il e. It uses t he next st at ement t o skip bl ank l ines.

List ing 8.11. A wor d-count ing pr ogr am t hat uses t he next st at ement .
1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: while ($line = <STDIN>) {
5: $line =~ s/^[\t ]*//;
6: $line =~ s/[\t ]*\n$//;
7: next if ($line eq "");
8: @words = split(/[\t ]+/, $line);
9: $total += @words;
10: }
11: print ("The total number of words is $total\n");

$ program8_11
Here is my test input.
It contains some words.
^D
The total number of words is 9
$
Af t er l ine 4 has r ead a l ine of input and checked t hat it is not empt y (which
means t hat t he end of f il e has not been r eached), t he pr ogr am t hen get s r id of l eading
spaces and t abs (l ine 5) and t r ail ing spaces, t abs, and t he t r ail ing newl ine (l ine 6). If a
l ine is bl ank, l ines 5 and 6 t ur n it int o t he empt y st r ing, f or which l ine 7 t est s.
Line 7 cont ains t he next st at ement as par t of a singl e-l ine condit ional st at ement . If t he
l ine is now empt y, t he next st at ement t el l s t he pr ogr am t o go t o t he beginning of t he
l oop and r ead in t he next l ine of input .
You cannot use t he next st at ement inside t he do
st at ement . Al t hough t he do st at ement behaves l ike t he
ot her cont r ol st r uct ur es, it is act ual l y impl ement ed
dif f er ent l y.
The redo Statement
Per l enabl es you t o t el l t he Per l int er pr et er t o r est ar t an it er at ion of a l oop using t he
redo st at ement .
Like last and next, t he synt ax f or t he redo st at ement is simpl e:
redo;
For an exampl e, l ook at List ing 8.12, which count s t he number of wor ds in t hr ee non-
bl ank input l ines.

List ing 8.12. A wor d-count ing pr ogr am t hat uses t he redo st at ement .
1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: for ($count = 1; $count <= 3; $count++) {
5: $line = <STDIN>;
6: last if ($line eq "");
7: $line =~ s/^[\t ]*//;
8: $line =~ s/[\t ]*\n$//;
9: redo if ($line eq "");
10: @words = split(/[\t ]+/, $line);
11: $total += @words;
12: }
13: print ("The total number of words is $total\n");

$ program8_12
Here is my test input.
It contains some words.
^D
The total number of words is 9
$
Line 5 r eads a l ine of input f r om t he st andar d input f il e. If t his l ine is empt y,
t he condit ional expr ession in l ine 6 is t r ue, and t he last st at ement exit s t he l oop. (This
ensur es t hat t he pr ogr am behaves pr oper l y when t her e ar e l ess t han t hr ee l ines of
input .)
Line 7 r emoves t he l eading bl anks and t abs f r om t his l ine of input , and l ine 8 r emoves
t he t r ail ing whit e space. If t he r esul t ing l ine is now empt y, t he l ine must or iginal l y
have been bl ank. Because t his pr ogr am does not want t o incl ude a bl ank l ine as one of
t he t hr ee l ines in which t o count wor ds, l ine 9 invokes t he redo st at ement , which t el l s
t he pr ogr am t o st ar t t his l oop over . The pr ogr am r et ur ns t o l ine 4, t he for st at ement ,
but does not incr ement t he val ue of $count.
You cannot use t he redo st at ement inside t he do
st at ement . Al t hough t he do st at ement behaves l ike t he
ot her cont r ol st r uct ur es, it is act ual l y impl ement ed
dif f er ent l y.
Not e t hat t he redo st at ement is not r ecommended, because it is t oo easy t o l ose t r ack of
how many t imes a pr ogr am goes t hr ough a l oop. For exampl e, in List ing 8.12, a quick
gl ance at t he for st at ement in l ine 4 seems t o indicat e t hat t he pr ogr am onl y l oops
t hr ee t imes; however , t he redo st at ement might change t hat .
List ing 8.13 shows an al t er nat ive way t o sol ve t his pr obl em.

List ing 8.13. A pr ogr am t hat count s t he wor ds in t hr ee non-bl ank l ines
of input wit hout using t he redo st at ement .
1: #!/usr/local/bin/perl
2:
3: $nonblanklines = 0;
4: while (1) {
5: $line = <STDIN>;
6: last if ($line eq "");
7: $line =~ s/^[\t ]*//;
8: $line =~ s/[\t ]*\n$//;
9: if ($line ne "") {
10: $nonblanklines += 1;
11: @words = split(/[\t ]+/, $line);
12: $total += @words;
13: }
14: last if ($nonblanklines == 3);
15: };
16: print ("The total number of words is $total\n");

$ program8_13
Here is my test input.
It contains some words.
^D
The total number of words is 9.
$
This pr ogr am is ident ical t o t he pr evious one, but it is much easier t o
under st and. It uses a mor e meaningf ul var iabl e name-$nonblanklines-which impl ies t hat
bl ank l ines ar e a special case.
As in List ing 8.12, if t he l ine is a bl ank l ine, l ines 7 and 8 t ur n it int o an empt y l ine by
r emoving al l whit e space. When t his happens, t he condit ion in l ine 10 f ail s, and
$nonblanklines is not incr ement ed.
Using Labeled Blocks for Multilevel Jumps
As you've seen, t he last, next, and redo st at ement s enabl e you t o exit a l oop f r om
anywher e inside it s st at ement bl ock, as f ol l ows:
while (1) {
$line = <STDIN>;
last if ($line eq "");
}
If t he l oop is inside anot her l oop, t he last, next, and redo st at ement s quit t he inner l oop
onl y; f or exampl e:
while ($line1 = <FILE1>) {
while ($line2 = <FILE2>) {
last if ($line2 eq "") {
}
}
Her e, t he last st at ement onl y quit s t he inner while l oop. The out er while l oop, which
r eads f r om t he f il e r epr esent ed by FILE1, cont inues execut ing.
To quit f r om mor e t han one l oop at once, do t he f ol l owing:
1. Assign a l abel t o t he out er l oop (t he one f r om which you want t o quit ).
2. When you use last, next, or redo, specif y t he l abel you just assigned.
List ing 8.14 shows an exampl e of a last st at ement t hat specif ies a l abel .

List ing 8.14. A pr ogr am t hat uses a l abel .
1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: $firstcounter = 0;
5: DONE: while ($firstcounter < 10) {
6: $secondcounter = 1;
7: while ($secondcounter <= 10) {
8: $total++;
9: if ($firstcounter == 4 && $secondcounter == 7) {
10: last DONE;
11: }
12: $secondcounter++;
13: }
14: $firstcounter++;
15: }
16: print ("$total\n");

$ program8_14
47
$
The out er while l oop st ar t ing in l ine 5 has t he l abel DONE assigned t o it . This
l abel consist s of an al phabet ic char act er f ol l owed by one or mor e al phanumer ic
char act er s or under scor es. The col on (:) char act er f ol l owing t he l abel indicat es t hat
t he l abel is assigned t o t he f ol l owing st at ement (in t his case, t he while st at ement ).
When t he condit ional expr ession in l ine 9 is t r ue, l ine 10 is execut ed. This st at ement
t el l s t he Per l int er pr et er t o jump out of t he l oop l abel ed DONE and cont inue execut ion
wit h t he f ir st st at ement af t er t his l oop. (By t he way, t his code f r agment is just a r at her
compl icat ed way of assigning 47 t o $total.)
Make sur e t hat you do not use a l abel which has
anot her meaning in Per l . For exampl e, t he st at ement
if: while ($x == 0) { # this is an error in Perl
}
is f l agged as er r oneous, because t he Per l int er pr et er
doesn't r eal ize t hat t he if is not t he st ar t of an if
st at ement .
You can avoid t his pr obl em by using upper case l et t er s
f or l abel names (such as DONE).
Not e t hat l abel s can be ident ical t o f il e var iabl e names:
FILE1: while ($line = <FILE1>) {
...
}
The Per l int er pr et er has no pr obl em dist inguishing t he
l abel FILE1 f r om t he f il e var iabl e FILE1, because it is
al ways possibl e t o det er mine which is which f r om t he
cont ext .
Using next and redo with Labels
You can use next and redo wit h l abel s as wel l , as shown in t he f ol l owing exampl e:
next LABEL;
redo LABEL;
This next st at ement indicat es t hat t he next it er at ion of t he l oop l abel ed LABEL is t o be
execut ed. This redo st at ement indicat es t hat t he cur r ent it er at ion of t he l oop l abel ed
LABEL is t o be r est ar t ed.
The continue Block
In a for st at ement , t he expr ession f ol l owing t he second semicol on is execut ed each t ime
t he end of t he l oop is r eached or whenever a next st at ement is execut ed. For exampl e:
for ($i = 1; $i <= 10; $i++) {
print ("$i\n");
}
In t his exampl e, t he expr ession $i++, which adds 1 t o $i, is execut ed af t er t he print
f unct ion is cal l ed.
Simil ar l y, you can def ine st at ement s t hat ar e t o be execut ed whenever t he end of a
while l oop or an until l oop is r eached. To car r y out t his t ask, specif y a continue
st at ement af t er t he l oop.
$i = 1;
while ($i <= 10) {
print ("$i\n");
}
continue {
$i++;
}
A continue st at ement must be f ol l owed by a st at ement bl ock, which is a col l ect ion of
zer o or mor e st at ement s encl osed in br ace char act er s. This st at ement bl ock cont ains
t he st at e-ment s t o be execut ed at t he bot t om of each l oop. In t his exampl e, t he
st at ement
$i++;
is execut ed af t er each cal l t o print. This while l oop t her ef or e behaves l ike t he for l oop
you've just seen.
The continue st at ement is execut ed even if a pass t hr ough t he l oop is pr emat ur el y ended
by a next st at ement . It is not execut ed, however , if t he l oop is t er minat ed by a last
st at ement .
TIP
Usual l y, it is bet t er t o use a for st at ement t han t o use
continue wit h a while or an until st at ement , because
t he for st at ement is easier t o f ol l ow.
The goto Statement
For t he sake of compl et eness, Per l pr ovides a goto st at ement .
The synt ax of t he goto st at ement is
goto label;
label is a l abel associat ed wit h a st at ement , as def ined in t he ear l ier sect ion, "Using
Label ed Bl ocks f or Mul t il evel Jumps." The st at ement t o which label is assigned cannot
be in t he middl e of a do st at ement or inside a subr out ine. (You'l l l ear n about
subr out ines on Day 9.)
List ing 8.15 is an exampl e of a simpl e pr ogr am t hat uses goto.

List ing 8.15. A pr ogr am t hat uses t he goto st at ement .
1: #!/usr/local/bin/perl
2:
3: NEXTLINE: $line = <STDIN>;
4: if ($line ne "") {
5: print ($line);
6: goto NEXTLINE;
7: }

$ program8_15
Here is a line of input.
Here is a line of input.
^D
$
This pr ogr am just r eads and wr it es l ines of input unt il t he st andar d input f il e
is exhaust ed. If t he l ine r ead int o $line is not empt y, l ine 6 t el l s t he Per l int er pr et er t o
jump back t o t he l ine t o which t he NEXTLINE l abel is assigned, which is l ine 3.
Not e t hat l ines 3-7 ar e equival ent t o t he f ol l owing st at ement :
print ($line) while ($line = <STDIN>);
TIP
Ther e is al most never any need t o use t he goto
st at ement . In f act , using goto of t en makes it mor e
dif f icul t t o f ol l ow t he l ogic of t he pr ogr am. For t his
r eason, using goto is not r ecommended.
Summary
Today you l ear ned about t he mor e compl ex cont r ol st r uct ur es suppor t ed in Per l .
Singl e-l ine condit ional st at ement s enabl e you t o put a condit ional expr ession on t he
same l ine as t he st at ement t o be execut ed if t he condit ion is sat isf ied. This enabl es you
t o wr it e mor e concise pr ogr ams.
The for st at ement enabl es you t o put t he l oop init ial izer , t he l oop it er at or , and t he
condit ional expr ession t oget her on t he same l ine. This makes it mor e dif f icul t t o wr it e
code t hat goes int o an inf init e l oop.
The foreach st at ement enabl es a pr ogr am t o l oop based on t he cont ent s of a l ist . When
t he l oop is f ir st execut ed, t he f ir st el ement in t he l ist is assigned t o a l ocal scal ar
var iabl e t hat is onl y def ined f or t he dur at ion of t he l oop. Subsequent it er at ions of t he
l oop assign subsequent el ement s of t he l ist t o t his l ocal scal ar var iabl e.
The do st at ement enabl es you t o wr it e a l oop t hat execut es at l east once. It s
t er minat ing condit ional expr ession appear s at t he bot t om of t he l oop, not t he t op.
The last st at ement t el l s t he Per l int er pr et er t o exit t he l oop and cont inue execut ion
wit h t he f ir st st at ement af t er t he l oop. The next st at ement t el l s t he Per l int er pr et er
t o skip t he r est of t his it er at ion of a l oop and st ar t wit h t he next one. The redo
st at ement t el l s t he Per l int er pr et er t o r est ar t t his it er at ion of a l oop. last, next, and
redo cannot be used wit h t he do st at ement .
You can assign a l abel t o a st at ement , which enabl es you t o use last, next, and redo t o
exit or r est ar t an out er l oop f r om inside an inner l oop.
The continue st at ement enabl es you t o def ine code t o be execut ed each t ime a l oop
it er at es.
The goto st at ement enabl es you t o jump t o any l abel ed st at ement in your pr ogr am.
Q&A
Q: Which cont r ol st r uct ur e is t he best one t o use as a l oop?
A: It depends on what you want t o do.
G The foreach st r uct ur e is t he best way t o per f or m oper at ions on ever y
el ement of a l ist .
G The for st at ement is t he best way t o per f or m an oper at ion a set number of
t imes.
G The while st at ement is t he best way t o per f or m a l oop unt il a par t icul ar
condit ion occur s.
G The do st at ement is usef ul if you want t o per f or m a l oop at l east once.
(However , it is not as usef ul as t he ot her s, because you cannot use last,
next, or redo wit h it .)
Q: Why does Per l bot her wit h t he next, last, and redo st at ement s, when t he if-
elsif-else st r uct ur e can do t he job just as wel l ?
A: The last and next st at ement s ar e ideal f or l oops t hat check f or except ional
condit ions. For exampl e:
for ($count = 1; $count <= 3; $count++) {
$line = <STDIN>;
last if ($line eq "");
$line =~ s/^[\t ]+//;
$line =~ s/[\t ]+\n$//;
@words = split(/[\t ]+/, $line);
$total += @words;
}
If t he last st at ement did not exist , t he onl y way t o impl ement t his woul d be
wit h anot her l evel of nest ing and anot her condit ion in t he for st at ement , as
f ol l ows:
for ($count = 1; $count <= 3 && $line ne ""; $count++) {
$line = <STDIN>;
if ($line ne "") {
$line =~ s/^[\t ]+//;
$line =~ s/[\t ]+\n$//;
@words = split(/[\t ]+/, $line);
$total += @words;
}
}
If your pr ogr am has t o check f or sever al except ional condit ions, you might need
sever al l evel s of if st at ement s t o handl e t hem unl ess you use next or last.
On t he ot her hand, t he redo st at ement shoul d be avoided whenever possibl e,
because it is dif f icul t t o f ol l ow pr ogr am l ogic when it is used.
Q: Is t he goto st at ement ever t he best way t o sol ve a pr obl em?
A: Al most never . Avoid using t he goto st at ement if at al l possibl e.
Q: Why is t he condit ional expr ession l ast in singl e-l ine condit ional
st at ement s?
A: This is t o avoid a pr obl em f ound in t he C pr ogr amming l anguage. In C, you don't
need t o put br aces ar ound t he st at ement bl ock in a condit ional st at ement if t he
bl ock consist s of onl y one l ine. For exampl e, t he f ol l owing is l egal :
if (x == 0)
printf ("x is zero\n");
Wit h t his synt ax, it is easy t o accident al l y f or get t o add t he br aces when you
add anot her st at ement t o t he st at ement bl ock, as f ol l ows:
if (x == 0)
printf ("x is zero\n");
printf ("this statement is always printed\n");
If you gl ance at t his code quickl y, you might t hink t hat t he second cal l t o
printf is execut ed onl y if x is 0. However , t his code is r eal l y
if (x == 0)
printf ("x is zero\n");
printf ("this statement is always printed\n");
In Per l , t his pr obl em does not exist because t he onl y way t o wr it e t he f ir st
st at ement is
print ("x is zero\n") if (x == 0);
Q: Is a continue bl ock execut ed if a redo st at ement r est ar t s t he l oop?
A: No. The continue bl ock is execut ed onl y when an it er at ion of a l oop is
successf ul l y compl et ed (by r eaching t he bot t om of a l oop or a next st at ement ).
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. How many t imes does t he f ol l owing l oop it er at e?
for ($count = 0; $count < 7; $count++) {
print ("$count\n");
}
2. How many t imes does t he f ol l owing l oop it er at e?
$count = 1;
do {
print ("$count\n");
} until ($count++ > 10);
3. How many t imes does t he f ol l owing l oop it er at e?
for ($count = 1; $count <= 10; $count++) {
last if ($count == 5);
}
4. How many t imes does t he f ol l owing l oop it er at e?
$restart = 0;
for ($count = 1; $count <= 5; $count++) {
redo if ($restart++ == 1);
}
5. Wr it e a singl e-l ine condit ional st at ement t hat quit s a l oop if $x equal s done.
6. Wr it e a singl e-l ine condit ional st at ement t hat r est ar t s a l oop if t he f ir st
el ement of t he l ist @list is 26.
7. Wr it e a singl e-l ine condit ional st at ement t hat goes t o t he next it er at ion of t he
l oop l abel ed LABEL if $scalar equal s #.
8. Wr it e a singl e-l ine condit ional st at ement t hat pr int s t he digit s f r om 1 t o 10. (Use
a scal ar var iabl e, and assume t hat it has not been pr eviousl y def ined.)
9. What does t he continue st at ement do?
Exercises
1. Wr it e a pr ogr am t hat uses t he do st at ement t o pr int t he number s f r om 1 t o 10.
2. Wr it e a pr ogr am t hat uses t he for st at ement t o pr int t he number s f r om 1 t o 10.
3. Wr it e a pr ogr am t hat uses a l oop t o r ead and wr it e f ive l ines of input . Use t he
last st at ement t o exit t he l oop if t her e ar e l ess t han f ive l ines t o r ead.
4. Wr it e a pr ogr am t hat l oops t hr ough t he number s 1 t o 20, pr int ing t he even-
number ed val ues. Use t he next st at ement t o skip over t he odd-number ed val ues.
5. Wr it e a pr ogr am t hat uses t he foreach st at ement t o check each wor d in t he
st andar d input f il e. Pr int t he l ine number s of al l occur r ences of t he wor d the (in
upper case, l ower case, or mixed case).
6. Wr it e a pr ogr am t hat uses a while l oop and a continue st at ement t o pr int t he
int eger s f r om 10 down t o 1.
7. BUG BUSTER: What is wr ong wit h t he f ol l owing code?
$count = 1;
do {
print ("$count\n");
last if ($count == 10);
$count++;
} while (1);

Chapter 9
Using Subroutines
CONTENTS
G What Is a Subr out ine?
G Def ining and Invoking a Subr out ine
H For war d Ref er ences t o Subr out ines
G Ret ur ning a Val ue f r om a Subr out ine
H Ret ur n Val ues and Condit ional Expr essions
G The return St at ement
G Using Local Var iabl es in Subr out ines
H Init ial izing Local Var iabl es
G Passing Val ues t o a Subr out ine
H Passing a List t o a Subr out ine
G Cal l ing Subr out ines f r om Ot her Subr out ines
G Recur sive Subr out ines
G Passing Ar r ays by Name Using Al iases
G Using t he do St at ement wit h Subr out ines
G Specif ying t he Sor t Or der
G Pr edef ined Subr out ines
H Cr eat ing St ar t up Code Using BEGIN
H Cr eat ing Ter minat ion Code Using END
H Handl ing Non-Exist ent Subr out ines Using AUTOLOAD
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson shows you how t o use subr out ines t o divide your pr ogr am int o smal l er ,
mor e manageabl e modul es. Today, you l ear n about t he f ol l owing:
G What a subr out ine is
G How t o def ine subr out ines
G How t o invoke subr out ines
G How t o r et ur n a val ue f r om a subr out ine
G How t o use t he return st at ement
G How t o use l ocal var iabl es in subr out ines
G How t o pass ar gument s t o subr out ines
G How t o cal l subr out ines f r om ot her subr out ines
G The meaning of r ecur sive subr out ines
G How t o pass ar r ays by name in subr out ines using al iasing
G How t o use t he do st at ement wit h subr out ines
G How t o use subr out ines t o change t he sor t or der used by sort
G How t o pr ovide st ar t up and t er minat ion code using BEGIN and END
G How t o use AUTOLOAD
What Is a Subroutine?
In Per l , a subroutine is a separ at e body of code designed t o per f or m a par t icul ar t ask. A
Per l pr ogr am execut es t his body of code by cal l ing or invoking t he subr out ine; t he act
of invoking a subr out ine is cal l ed a subroutine invocation.
Subr out ines ser ve t wo usef ul pur poses:
G They br eak down your pr ogr am int o smal l er par t s, making it easier t o r ead and
under st and.
G They enabl e you t o use one piece of code t o per f or m t he same t ask mul t ipl e t imes,
el iminat ing needl ess dupl icat ion.
Defining and Invoking a Subroutine
List ing 9.1 shows how a subr out ine wor ks. This pr ogr am cal l s a subr out ine t hat r eads a
l ine f r om t he st andar d input f il e and br eaks it int o number s. The pr ogr am t hen adds t he
number s t oget her .

List ing 9.1. A pr ogr am t hat uses a subr out ine.
1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: &getnumbers;
5: foreach $number (@numbers) {
6: $total += $number;
7: }
8: print ("the total is $total\n");
9:
10: sub getnumbers {
11: $line = <STDIN>;
12: $line =~ s/^\s+|\s*\n$//g;
13: @numbers = split(/\s+/, $line);
14: }

$ program9_1
11 8 16 4
the total is 39
$
Lines 10-14 ar e an exampl e of a subr out ine. The keywor d sub t el l s t he Per l
int er pr et er t hat t his is a subr out ine def init ion. The getnumbers immediat el y f ol l owing
sub is t he name of t he subr out ine; t he Per l pr ogr am uses t his name when invoking t he
subr out ine.
The pr ogr am st ar t s execut ion in t he nor mal way, beginning wit h l ine 3. Line 4 invokes
t he subr out ine getnumbers; t he & char act er t el l s t he Per l int er pr et er t hat t he
f ol l owing name is t he name of a subr out ine. (This ensur es t hat t he Per l int er pr et er does
not conf use subr out ine names wit h t he names of scal ar or ar r ay var iabl es.)
The Per l int er pr et er execut es l ine 4 by jumping t o t he f ir st execut abl e st at ement inside
t he subr out ine, which is l ine 11. The int er pr et er t hen execut es l ines 11-13.
Lines 11-13 cr eat e t he ar r ay @numbers as f ol l ows:
G Line 11 r eads a l ine of input f r om t he st andar d input f il e.
G Line 12 r emoves t he l eading and t r ail ing whit e space (incl uding t he t r ail ing
newl ine) f r om t he input l ine.
G Line 13 t hen br eaks t he input l ine int o number s and assigns t he r esul t ing l ist of
number s t o @numbers.
Af t er l ine 13 is f inished, t he Per l int er pr et er jumps back t o t he main pr ogr am and
execut es t he l ine immediat el y f ol l owing t he subr out ine cal l , which is l ine 5.
Lines 5-7 add t he number s t oget her by using t he foreach st at ement t o l oop t hr ough t he
l ist st or ed in @numbers. (Not e t hat t his pr ogr am does not check whet her a par t icul ar
el ement of @numbers act ual l y consist s of digit s. Because char act er st r ings t hat ar e not
digit s ar e conver t ed t o 0 in expr essions, t his isn't a signif icant pr obl em.)
The synt ax f or a subr out ine def init ion is
sub subname {
statement_block
}
subname is a pl acehol der f or t he name of t he subr out ine. Like al l Per l names, subname
consist s of an al phabet ic char act er f ol l owed by one or mor e l et t er s, digit s, or
under scor es.
statement_block is t he body of t he subr out ine and consist s of one or mor e Per l
st at ement s. Any st at ement t hat can appear in t he main par t of a Per l pr ogr am can
appear in a subr out ine.
NOTE
The Per l int er pr et er never conf uses a subr out ine name
wit h a scal ar var iabl e name or any ot her name, because
it can al ways t el l f r om t he cont ext which name you ar e
r ef er r ing t o. This means t hat you can have a subr out ine
and a scal ar var iabl e wit h t he same name. For exampl e:
$word = 0;
&word;
Her e, when t he Per l int er pr et er sees t he & char act er in
t he second st at ement , it r eal izes t hat t he second
st at ement is cal l ing t he subr out ine named word.
When you ar e def ining names f or your subr out ines, it 's
best not t o use a name bel onging t o a buil t -in Per l
f unct ion t hat you pl an t o use.
For exampl e, you coul d, if you want , def ine a subr out ine
named split. The Per l int er pr et er can al ways
dist inguish an invocat ion of t he subr out ine split f r om
an invocat ion of t he l ibr ar y f unct ion split, because t he
name of t he subr out ine is pr eceded by an & when it is
invoked, as f ol l ows:
@words = &split(1, 2); # subroutine
@words = split(/\s+/, $line); # library function
However , it 's easy t o l eave of f t he & by mist ake
(especial l y if you ar e used t o pr ogr amming in C, wher e
subr out ine cal l s do not st ar t wit h an &). To avoid such
pr obl ems, use subr out ine names t hat don't cor r espond t o
t he names of l ibr ar y f unct ions.
Per l subr out ines can appear anywher e in a pr ogr am, even in t he middl e of a condit ional
st at ement . For exampl e, List ing 9.2 is a per f ect l y l egal Per l pr ogr am.

List ing 9.2. A pr ogr am cont aining a subr out ine in t he middl e of t he main
pr ogr am.
1: #!/usr/local/bin/perl
2:
3: while (1) {
4: &readaline;
5: last if ($line eq "");
6: sub readaline {
7: $line = <STDIN>;
8: }
9: print ($line);
10: }
11: print ("done\n");

$ program9_2
Here is a line of input.
Here is a line of input.
^D
done
$
This pr ogr am just r eads l ines of input f r om t he st andar d input f il e and wr it es
t hem st r aight back out t o t he st andar d out put f il e.
Line 4 cal l s t he subr out ine readaline. When you examine t his subr out ine, which is
cont ained in l ines 6-8, you can see t hat it r eads a l ine of input and assigns it t o t he
scal ar var iabl e $line.
When readaline is f inished, pr ogr am execut ion cont inues wit h l ine 5. When l ine 5 is
execut ed, t he pr ogr am skips over t he subr out ine def init ion and cont inues wit h l ine 9.
The code inside t he subr out ine is never dir ect l y execut ed, even if it appear s in t he middl e
of a pr ogr am; l ines 6-8 can be execut ed onl y by a subr out ine invocat ion, such as t hat
f ound in l ine 4.
TIP
Al t hough subr out ines can appear anywher e in a
pr ogr am, it usual l y is best t o put al l your subr out ines at
eit her t he beginning of t he pr ogr am or t he end.
Fol l owing t his pr act ice makes your pr ogr ams easier t o
r ead.
Forward References to Subroutines
As you have seen, t he Per l int er pr et er uses t he & char act er t o indicat e t hat a
subr out ine is being specif ied in a st at ement . In Per l 5, you do not need t o suppl y an &
char act er when cal l ing a subr out ine if you have al r eady def ined t he subr out ine.
sub readaline {
$line = <STDIN>;
}
...
readaline;
Because t he Per l int er pr et er al r eady knows t hat readaline is a subr out ine, you don't
need t o specif y t he & when cal l ing it .
If you pr ef er t o l ist al l your subr out ines at t he end of your pr ogr am, you can st il l omit
t he & char act er pr ovided you suppl y a f or war d r ef er ence f or your subr out ine, as shown
in t he f ol l owing:
sub readaline; # forward reference
...
readaline;
...
sub readaline {
$line = <STDIN>;
}
The f or war d r ef er ence t el l s t he Per l int er pr et er t hat readaline is t he name of a
subr out ine. This means t hat you no l onger need t o suppl y t he & when you cal l
readaline.
Occasional l y, cal l ing a subr out ine wit hout specif ying
t he & char act er might not behave t he way you expect . If
your pr ogr am is behaving st r angel y, or you ar e not sur e
whet her or not t o use t he & char act er , suppl y t he &
char act er wit h your cal l .
Returning a Value from a Subroutine
Take anot her l ook at t he getnumbers subr out ine f r om List ing 9.1.
sub getnumbers {
$line = <STDIN>;
$line =~ s/^\s+|\s*\n$//g;
@numbers = split(/\s+/, $temp);
}
Al t hough t his subr out ine is usef ul , it suf f er s f r om one ser ious l imit at ion: it over wr it es
any exist ing l ist st or ed in t he ar r ay var iabl e @numbers (as wel l as any val ue st or ed in
$line or $temp). This over wr it ing can l ead t o pr obl ems. For exampl e, consider t he
f ol l owing:
@numbers = ("the", "a", "an");
&getnumbers;
print ("The value of \@numbers is: @numbers\n");
When t he subr out ine getnumbers is invoked, t he val ue of @numbers is over wr it t en. If you
just examine t his por t ion of t he pr ogr am, it is not obvious t hat t his is what is happening.
To get ar ound t his pr obl em, you can empl oy a usef ul pr oper t y of subr out ines in Per l : The
val ue of t he l ast expr ession eval uat ed by t he subr out ine is aut omat ical l y consider ed t o
be t he subr out ine's return value.
For exampl e, in t he subr out ine getnumbers f r om List ing 9.1, t he l ast expr ession
eval uat ed is
@numbers = split(/\s+/, $temp);
The val ue of t his expr ession is t he l ist of number s obt ained by spl it t ing t he l ine of input .
This means t hat t his l ist of number s is t he r et ur n val ue f or t he subr out ine.
To see how t o use a subr out ine r et ur n val ue, l ook at List ing 9.3, which modif ies t he
wor d-count ing pr ogr am t o use t he r et ur n val ue f r om t he subr out ine getnumbers.

List ing 9.3. A pr ogr am t hat uses a subr out ine r et ur n val ue.
1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: @numbers = &getnumbers;
5: foreach $number (@numbers) {
6: $total += $number;
7: }
8: print ("the total is $total\n");
9:
10: sub getnumbers {
11: $line = <STDIN>;
12: $line =~ s/^\s+|\s*\n$//g;
13: split(/\s+/, $line); # this is the return value
14: }

$ program9_3
11 8 16 4
the total is 39
$
Line 4, once again, cal l s t he subr out ine getnumbers. As bef or e, t he ar r ay
var iabl e @numbers is assigned t he l ist of number s r ead f r om t he st andar d input f il e;
however , in t his pr ogr am, t he assignment is in t he main body of t he pr ogr am, not in t he
subr out ine. This makes t he pr ogr am easier t o r ead.
The onl y ot her dif f er ence bet ween t his pr ogr am and List ing 9.1 is t hat t he cal l t o split
in l ine 13 no l onger assigns anyt hing t o @numbers. In f act , it doesn't assign t he l ist
r et ur ned by split t o any var iabl e at al l , because it does not need t o. Line 13 is t he l ast
expr ession eval uat ed in getnumbers, so it aut omat ical l y becomes t he r et ur n val ue f r om
getnumbers. Ther ef or e, when l ine 4 cal l s getnumbers, t he l ist r et ur ned by split is
assigned t o t he ar r ay var iabl e @numbers.
NOTE
If t he idea of eval uat ing an expr ession wit hout assigning
it conf uses you, t her e's not hing wr ong wit h cr eat ing a
var iabl e inside t he subr out ine just f or t he pur pose of
cont aining t he r et ur n val ue. For exampl e:
sub getnumbers {
$line = <STDIN>;
$line =~ s/^\s+|\s*\n$//g;
@retval = split(/\s+/, $temp); # the return value
}
Her e, it is obvious t hat t he r et ur n val ue is t he cont ent s
of @retval.
The onl y dr awback t o doing t his is t hat assigning t he
l ist r et ur ned by split t o @retval is sl ight l y l ess
ef f icient . In l ar ger pr ogr ams, such ef f iciency cost s ar e
wor t h it , because subr out ines become much mor e
compr ehensibl e.
Using a special r et ur n var iabl e al so el iminat es an ent ir e
cl ass of er r or s, which you wil l see in "Ret ur n Val ues
and Condit ional Expr essions," l at er t oday.
You can use a r et ur n val ue of a subr out ine any pl ace an expr ession is expect ed. For
exampl e:
foreach $number (&getnumbers) {
print ("$number\n");
}
This foreach st at ement it er at es on t he l ist of number s r et ur ned by getnumbers. Each
el ement of t he l ist is assigned t o $number in t ur n, which means t hat t his l oop pr int s al l
t he number s in t he l ist , each on it s own l ine.
List ing 9.4 shows anot her exampl e t hat uses t he r et ur n val ue of a subr out ine in an
expr ession. This t ime, t he r et ur n val ue is used as an ar r ay subscr ipt .

List ing 9.4. A pr ogr am t hat uses a r et ur n val ue as an ar r ay subscr ipt .
1: #!/usr/local/bin/perl
2:
3: srand();
4: print ("Random number tester.\n");
5: for ($count = 1; $count <= 100; $count++) {
6: $randnum[&intrand] += 1;
7: }
8: print ("Totals for the digits 0 through 9:\n");
9: print ("@randnum\n");
10:
11: sub intrand {
12: $num = int(rand(10));
13: }

$ progam9_4
Random number tester.
Totals for the digits 0 through 9:
10 9 11 10 8 8 12 11 9 12
$
This pr ogr am uses t he f ol l owing t hr ee buil t -in f unct ions:
srand
Init ial izes t he buil t -in r andom-number gener at or
rand
Gener at es a r andom (non-int egr al ) number gr eat er t han
zer o and l ess t han t he val ue passed t o it
int
Get s r id of t he non-int eger por t ion of a number
The subr out ine intrand f ir st cal l s rand t o get a r andom number gr eat er t han 0 and l ess
t han 10. The r et ur n val ue f r om rand is passed t o int t o r emove t he f r act ional por t ion of
t he number ; t his means, f or exampl e, t hat 4.77135 becomes 4. This number becomes t he
r et ur n val ue r et ur ned by intrand.
Line 6 cal l s intrand. The r et ur n val ue f r om intrand, an int eger bet ween 0 and 9, ser ves
as t he subscr ipt int o t he ar r ay var iabl e randnum. If t he r et ur n val ue f r om intrand is 7,
$randnum[7] has it s val ue incr eased by one.
As a consequence, at any given t ime, t he nt h val ue of @randnum cont ains t he number of
occur r ences of n as a r andom number .
Line 9 pr int s out t he number of occur r ences of each of t he 10 number s. Each number
shoul d occur appr oximat el y t he same number of t imes (al t hough not necessar il y exact l y
t he same number of t imes).
Return Values and Conditional Expressions
Because t he r et ur n val ue of a subr out ine is al ways t he l ast expr ession eval uat ed, t he
r et ur n val ue might not al ways be what you expect .
Consider t he simpl e pr ogr am in List ing 9.5. This pr ogr am, l ike t he one in List ing 9.3, r eads
an input l ine, br eaks it int o number s, and adds t he number s. This pr ogr am, however ,
at t empt s t o do al l t he wor k inside t he subr out ine get_total.

List ing 9.5. A pr ogr am il l ust r at ing a pot ent ial pr obl em wit h r et ur n
val ues f r om subr out ines.
1: #!/usr/local/bin/perl
2:
3: $total = &get_total;
4: print("The total is $total\n");
5:
6: sub get_total {
7: $value = 0;
8: $inputline = <STDIN>;
9: $inputline =~ s/^\s+|\s*\n$//g;
10: @subwords = split(/\s+/, $inputline);
11: $index = 0;
12: while ($subwords[$index] ne "") {
13: $value += $subwords[$index++];
14: }
15: }

$ program9_5
11 8 16 4
the total is
$
Cl ear l y, t his pr ogr am is supposed t o assign t he cont ent s of t he scal ar var iabl e
$value t o t he scal ar var iabl e $total. However , when l ine 4 t r ies t o pr int t he t ot al , you
see t hat t he val ue of $total is act ual l y t he empt y st r ing. What has happened?
The pr obl em is in t he subr out ine get_total. In get_total, as in al l ot her subr out ines, t he
r et ur n val ue is t he val ue of t he l ast expr ession eval uat ed. However , in get_total, t he
l ast expr ession eval uat ed is not t he l ast expr ession in t he pr ogr am.
The l ast expr ession t o be eval uat ed in get_total is t he condit ional expr ession in l ine 12,
which is
$subwords[$index] ne ""
The l oop in l ines 12-14 it er at es unt il t he val ue of t his expr ession is 0. When t he val ue of
t his expr ession is 0, t he l oop t er minat es and t he subr out ine t er minat es. This means t hat
t he val ue of t he l ast expr ession eval uat ed in t he subr out ine is 0 and t hat t he r et ur n
val ue of t he subr out ine is 0. Because 0 is t r eat ed as t he nul l st r ing by print (0 and t he
nul l st r ing ar e equival ent in Per l ), l ine 4 pr int s t he f ol l owing, which isn't what t he
pr ogr am is supposed
t o do:
the total is
List ing 9.6 shows how you can get ar ound t his pr obl em.

List ing 9.6. A pr ogr am t hat cor r ect s t he pr obl em t hat occur s in List ing
9.5.
1: #!/usr/local/bin/perl
2:
3: $total = &get_total;
4: print("The total is $total.\n");
5: sub get_total {
6: $value = 0;
7: $inputline = <STDIN>;
8: $inputline =~ s/^\s+|\s*\n$//g;
9: @subwords = split(/\s+/, $inputline);
10: $index = 0;
11: while ($subwords[$index] ne "") {
12: $value += $subwords[$index++];
13: }
14: $retval = $value;
15: }

$ program9_6
11 8 16 4
the total is 39.
$
This pr ogr am is ident ical t o List ing 9.5 except f or one dif f er ence: l ine 15 has
been added. This l ine assigns t he t ot al st or ed in $value t o t he scal ar var iabl e $retval.
Line 15 ensur es t hat t he val ue of t he l ast expr ession eval uat ed in t he subr out ine
get_total is, in f act , t he t ot al which is supposed t o become t he r et ur n val ue. This means
t hat l ine 3 now assigns t he cor r ect t ot al t o $total, which in t ur n means t hat l ine 4 now
pr int s t he cor r ect r esul t .
Not e t hat you don't r eal l y need t o assign t o $retval. The subr out ine get_total can just
as easil y be t he f ol l owing:
sub get_total {
$value = 0;
$inputline = <STDIN>;
$inputline =~ s/^\s+|\s*\n$//g;
@subwords = split(/\s+/, $inputline);
$index = 0;
while ($subwords[$index] ne "") {
$value += $subwords[$index++];
}
$value;
}
Her e, t he f inal expr ession eval uat ed by t he subr out ine is simpl y $value. The val ue of
t his expr ession is t he cur r ent val ue st or ed in $value, which is t he sum of t he number s in
t he l ine.
TIP
Subr out ines, such as get_total in List ing 9.6, which
assign t heir r et ur n val ue at t he ver y end ar e known as
single-exit modules.
Singl e-exit modul es avoid pr obl ems l ike t hose you saw in
List ing 9.5, and t hey usual l y ar e much easier t o r ead. For
t hese r easons, it is a good idea t o assign t o t he r et ur n
val ue at t he ver y end of t he subr out ine, unl ess t her e
ar e over whel ming r easons not t o do so.
The return Statement
Anot her way t o ensur e t hat t he r et ur n val ue f r om a subr out ine is t he val ue you want
is t o use t he return st at ement .
The synt ax f or t he return st at ement is
return (retval);
retval is t he val ue you want your subr out ine t o r et ur n. It can be eit her a scal ar val ue
(incl uding t he r esul t of an expr ession) or a l ist .
List ing 9.7 pr ovides an exampl e of t he use of t he return st at ement .

List ing 9.7. A pr ogr am t hat uses t he return st at ement .
1: #!/usr/local/bin/perl
2:
3: $total = &get_total;
4: if ($total eq "error") {
5: print ("No input supplied.\n");
6: } else {
7: print("The total is $total.\n");
8: }
9:
10: sub get_total {
11: $value = 0;
12: $inputline = <STDIN>;
13: $inputline =~ s/^\s+|\s*\n$//g;
14: if ($inputline eq "") {
15: return ("error");
16: }
17: @subwords = split(/\s+/, $inputline);
18: $index = 0;
19: while ($subwords[$index] ne "") {
20: $value += $subwords[$index++];
21: }
22: $retval = $value;
23: }

$ program9_7
^D
No input supplied.
$
This pr ogr am is simil ar t o t he one in List ing 9.6. The onl y dif f er ence is t hat
t his pr ogr am checks whet her an input l ine exist s.
If t he input l ine does not exist , t he condit ional expr ession in l ine 14 becomes t r ue, and
l ine 15 is execut ed. Line 15 exit s t he subr out ine wit h t he r et ur n val ue error; t his means
t hat error is assigned t o $total in l ine 3.
This pr ogr am shows why al l owing scal ar var iabl es t o st or e eit her number s or char act er
st r ings is usef ul . When t he subr out ine get_total det ect s t he er r or , it can assign a val ue
t hat is not an int eger t o $total, which makes it easier t o det er mine t hat somet hing has
gone wr ong. Ot her pr ogr amming l anguages, which onl y enabl e you t o assign eit her a
number or a char act er st r ing t o a par t icul ar var iabl e, do not of f er t his f l exibil it y.
Using Local Variables in Subroutines
The subr out ine get_total in List ing 9.7 def ines sever al var iabl es t hat ar e used onl y
inside t he subr out ine: t he ar r ay var iabl e @subwords, and t he f our scal ar var iabl es
$inputline, $value, $index, and $retval.
If you know f or cer t ain t hat t hese var iabl es ar e going t o be used onl y inside t he
subr out ine, you can t el l Per l t o def ine t hese var iabl es as local variables.
In Per l 5, t her e ar e t wo st at ement s used t o def ine l ocal var iabl es:
G The my st at ement , which def ines var iabl es t hat exist onl y inside a subr out ine.
G The local st at ement , which def ines var iabl es t hat do not exist inside t he main
pr ogr am, but inside t he subr out ine and any subr out ines cal l ed by t he subr out ine.
(Cal l ing subr out ines f r om ot her subr out ines is discussed l at er t oday.)
In Per l 4, t he my st at ement is not def ined, so you must use local t o def ine a var iabl e t hat
is not known t o t he main pr ogr am.
List ing 9.8 shows how you can use my t o def ine a var iabl e t hat exist s onl y inside a
subr out ine.
NOTE
If you ar e using Per l 4, r epl ace my wit h local in al l t he
r emaining exampl es in t his chapt er . For exampl e, in
List ing 9.8, r epl ace my wit h local in l ines 13 and 14,
which pr oduces
local ($total, $inputline, @subwords);
local ($index, $retval);
In Per l , my and local behave ident ical l y and use t he
same synt ax. The onl y dif f er ence bet ween t hem is t hat
var iabl es cr eat ed using my ar e not known out side t he
subr out ine.

List ing 9.8. A pr ogr am t hat uses l ocal var iabl es.
1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: while (1) {
5: $linetotal = &get_total;
6: last if ($linetotal eq "done");
7: print ("Total for this line: $linetotal\n");
8: $total += $linetotal;
9: }
10: print ("Total for all lines: $total\n");
11:
12: sub get_total {
13: my ($total, $inputline, @subwords);
14: my ($index, $retval);
15: $total = 0;
16: $inputline = <STDIN>;
17: if ($inputline eq "") {
18: return ("done");
19: }
20: $inputline =~ s/^\s+|\s*\n$//g;
21: @subwords = split(/\s+/, $inputline);
22: $index = 0;
23: while ($subwords[$index] ne "") {
24: $total += $subwords[$index++];
25: }
26: $retval = $total;
27: }

$ program9_8
11 8 16 4
Total for this line: 39
7 20 6 1
Total for this line: 34
^D
Total for all lines: 73
$
This pr ogr am uses t wo copies of t he scal ar var iabl e $total. One copy of $total
is def ined in t he main pr ogr am and keeps a r unning t ot al of al l of t he number s in al l of
t he l ines.
The scal ar var iabl e $total is al so def ined in t he subr out ine get_total; in t his
subr out ine, $total r ef er s t o t he t ot al f or a par t icul ar l ine, and l ine 13 def ines it as a
l ocal var iabl e. Because t his copy of $total is onl y def ined inside t he subr out ine, t he
copy of $total def ined in t he main pr ogr am is not af f ect ed by l ine 15 (which assigns 0 t o
$total).
Because a l ocal var iabl e is not known out side t he
subr out ine, t he l ocal var iabl e is dest r oyed when t he
subr out ine is compl et ed. If t he subr out ine is cal l ed
again, a new copy of t he l ocal var iabl e is def ined.
This means t hat t he f ol l owing code does not wor k:
sub subroutine_count {
my($number_of_calls);
$number_of_calls += 1;
}
This subr out ine does not r et ur n t he number of t imes
subroutine_count has been cal l ed. Because a new copy of
$number_of_calls is def ined ever y t ime t he subr out ine is
cal l ed, $number_of_calls is al ways assigned t he val ue 1.
Local var iabl es can appear anywher e in a pr ogr am, pr ovided t hey ar e def ined bef or e
t hey ar e used. It is good pr ogr amming pr act ice t o put al l your l ocal def init ions at t he
beginning of your subr out ine.
Initializing Local Variables
If you want , you can assign a val ue t o a l ocal var iabl e when you decl ar e it . For
exampl e:
sub my_sub {
my($scalar) = 43;
my(@array) = ("here's", "a", "list");
# code goes here
}
Her e, t he l ocal scal ar var iabl e $scalar is given an init ial val ue of 43, and t he l ocal
ar r ay var iabl e @array is init ial ized t o cont ain t he l ist ("here's", "a", "list").
Passing Values to a Subroutine
You can make your subr out ines mor e f l exibl e by al l owing t hem t o accept val ues passed
f r om t he main pr ogr am; t hese val ues passed f r om t he main pr ogr am ar e known as
arguments.
List ing 9.9 pr ovides a ver y simpl e exampl e of a subr out ine t hat accept s t hr ee ar gument s.

List ing 9.9. A pr ogr am t hat uses a subr out ine t o pr int t hr ee number s
and t heir t ot al .
1: #!/usr/local/bin/perl
2:
3: print ("Enter three numbers, one at a time:\n");
4: $number1 = <STDIN>;
5: chop ($number1);
6: $number2 = <STDIN>;
7: chop ($number2);
8: $number3 = <STDIN>;
9: chop ($number3);
10: &printnum ($number1, $number2, $number3);
11:
12: sub printnum {
13: my($number1, $number2, $number3) = @_;
14: my($total);
15: print ("The numbers you entered: ");
16: print ("$number1 $number2 $number3\n");
17: $total = $number1 + $number2 + $number3;
18: print ("The total: $total\n");
19: }

$ program9_9
Enter three numbers, one at a time:
5
11
4
The numbers you entered: 5 11 4
The total: 20
$
Line 10 cal l s t he subr out ine printnum. Thr ee ar gument s ar e passed t o
printnum: t he val ue st or ed in $number1, t he val ue st or ed in $number2, and t he val ue
st or ed in $number3. Not e t hat ar gument s ar e passed t o subr out ines in t he same way t hey
ar e passed t o buil t -in l ibr ar y f unct ions.
Line 13 def ines l ocal copies of t he scal ar var iabl es $number1, $number2, and $number3. It
t hen assigns t he cont ent s of t he syst em var iabl e @_ t o t hese scal ar var iabl es. @_ is
cr eat ed whenever a subr out ine is cal l ed wit h ar gument s; it cont ains a l ist consist ing of
t he ar gument s in t he or der in which t hey ar e passed. In t his case, printnum is cal l ed wit h
ar gument s 5, 11, and 4, which means t hat @_ cont ains t he l ist (5, 11, 4).
The assignment in l ine 13 assigns t he l ist t o t he l ocal scal ar var iabl es t hat have just
been def ined. This assignment wor ks just l ike any ot her assignment of a l ist t o a set of
scal ar var iabl es. The f ir st el ement of t he l ist , 5, is assigned t o t he f ir st var iabl e,
$number1; t he second el ement of t he l ist , 11, is assigned t o $number2; and t he f inal
el ement , 4, is assigned t o $number3.
NOTE
Af t er t he ar r ay var iabl e @_ has been cr eat ed, it can be
used anywher e any ot her ar r ay var iabl e can be used.
This means t hat you do not need t o assign it s cont ent s t o
l ocal var iabl es.
The f ol l owing subr out ine is equival ent t o t he
subr out ine in l ines 12-19 of List ing 9.9:
sub printnum {
my($total);
print ("The numbers you entered: ");
print ("$_[0] $_[1] $_[2]\n");
$total = $_[0] + $_[1] + $_[2];
print ("The total: $total\n");
}
Her e, $_[0] r ef er s t o t he f ir st el ement of t he ar r ay
var iabl e @_, $_[1] r ef er s t o t he second el ement , and
$_[2] r ef er s t o t he t hir d el ement .
This subr out ine is a l it t l e mor e ef f icient , but it is har der
t o r ead.
TIP
It usual l y is bet t er t o def ine l ocal var iabl es and assign
@_ t o t hem because t hen your subr out ines wil l be easier
t o under st and.
List ing 9.10 is anot her exampl e of a pr ogr am t hat passes ar gument s t o a subr out ine. This
pr ogr am uses t he same subr out ine t o count t he number of wor ds and t he number of
char act er s in a f il e.

List ing 9.10. Anot her exampl e of a subr out ine wit h ar gument s passed t o
it .
1: #!/usr/local/bin/perl
2:
3: $wordcount = $charcount = 0;
4: $charpattern = "";
5: $wordpattern = "\\s+";
6: while ($line = <STDIN>) {
7: $charcount += &count($line, $charpattern);
8: $line =~ s/^\s+|\s+$//g;
9: $wordcount += &count($line, $wordpattern);
10: }
11: print ("Totals: $wordcount words, $charcount characters\n");
12:
13: sub count {
14: my ($line, $pattern) = @_;
15: my ($count);
16: if ($pattern eq "") {
17: @items = split (//, $line);
18: } else {
19: @items = split (/$pattern/, $line);
20: }
21: $count = @items;
22: }

$ program9_10
This is a line of input.
Here is another line.
^D
Totals: 10 words, 47 characters
$
This pr ogr am r eads l ines f r om t he st andar d input f il e unt il t he f il e is
exhaust ed. Each l ine has it s char act er s count ed and it s wor ds count ed.
Line 7 det er mines t he number of char act er s in a l ine by cal l ing t he subr out ine count.
This subr out ine is passed t he l ine of input and t he st r ing st or ed in $charpattern, which is
t he empt y st r ing. Inside t he subr out ine count, t he l ocal var iabl e $pattern r eceives t he
pat t er n passed t o it by t he cal l in l ine 7. This means t hat t he val ue st or ed in $pattern is
al so t he empt y st r ing.
Lines 16-20 spl it t he input l ine. The pat t er n specif ied in t he cal l t o split has t he val ue
st or ed in $pattern subst it ut ed int o it . Because $pattern cur r ent l y cont ains t he empt y
st r ing, t he pat t er n used t o spl it t he l ine is //, which spl it s t he input l ine int o individual
char act er s. As a r esul t , each el ement of t he r esul t ing l ist st or ed in @items is a
char act er in t he input l ine.
The t ot al number of el ement s in t he l ist -in ot her wor ds, t he t ot al number of char act er s
in t he input l ine-is assigned t o $count by l ine 17. Because t his is t he l ast expr ession
eval uat ed in t he subr out ine, t he r esul t ing t ot al number of char act er s is r et ur ned by
t he subr out ine. Line 8 adds t his t ot al t o t he scal ar var iabl e $charcount.
Line 8 t hen r emoves t he l eading and t r ail ing whit e space; t his whit e space is incl uded in
t he t ot al number of char act er s-because spaces, t abs, and t he t r ail ing newl ine char act er
count as char act er s-but is not incl uded when t he l ine is br oken int o wor ds.
Line 9 cal l s t he subr out ine count again, t his t ime wit h t he pat t er n st or ed in
$wordpattern, which is \s+. (Recal l t hat you need t o use t wo backsl ashes in a st r ing t o
r epr esent a singl e backsl ash, because t he \ char act er is t he escape char act er in st r ings.)
This val ue, r epr esent ing one or mor e whit espace char act er s, is assigned t o $pattern
inside t he subr out ine, and t he pat t er n passed t o split t her ef or e becomes /\s+/.
When split is cal l ed wit h t his pat t er n, @items is assigned a l ist of wor ds. The t ot al
number of wor ds in t he l ist is assigned t o $count and is r et ur ned; l ine 11 adds t his
r et ur ned val ue t o t he t ot al number of wor ds.
Passing a List to a Subroutine
If you want , you can pass a l ist t o a subr out ine. For exampl e, t he f ol l owing subr out ine
adds t he el ement s of a l ist t oget her and pr int s t he r esul t :
sub addlist {
my (@list) = @_;
$total = 0;
foreach $item (@list) {
$total += $item;
}
print ("The total is $total\n");
}
To invoke t his subr out ine, pass it an ar r ay var iabl e, a l ist , or any combinat ion of l ist s
and
scal ar val ues.
&addlist (@mylist);
&addlist ("14", "6", "11");
&addlist ($value1, @sublist, $value2);
In each case, t he val ues and l ist s suppl ied in t he cal l t o addlist ar e mer ged int o a singl e
l ist and t hen passed t o t he subr out ine.
Because val ues ar e mer ged int o a singl e l ist when a l ist is passed t o a subr out ine, you
can onl y def ine one l ist as an ar gument f or a subr out ine. The subr out ine
sub twolists {
my (@list1, @list2) = @_;
}
isn't usef ul because it al ways assigns t he empt y l ist t o @list2, and because @list1
absor bs al l of t he cont ent s of @_.
This means t hat if you want t o have bot h scal ar var iabl es and a l ist as ar gument s t o a
subr out ine, t he l ist must appear l ast , as f ol l ows:
sub twoargs {
my ($scalar, @list) = @_;
}
If you cal l t his subr out ine using
&twoargs(47, @mylist);
t he val ue 47 is assigned t o $scalar, and @mylist is assigned t o @list.
If you want , you can cal l twoargs wit h a singl e l ist , as f ol l ows:
&twoargs(@mylist);
Her e, t he f ir st el ement of @mylist is assigned t o $scalar, and t he r est of @mylist is
assigned t o @list.
NOTE
If you f ind t his conf using, it might hel p t o r eal ize t hat
passing ar gument s t o a subr out ine f ol l ows t he same
r ul es as assignment does. For exampl e, you can have
($scalar, @list1) = @list2;
because $scalar is assigned t he f ir st el ement of @list2.
However , you can't have t his:
(@list1, $scalar) = @list2;
because al l of @list1 woul d be assigned t o @list2 and
$scalar woul d be assigned t he nul l st r ing.
Calling Subroutines from Other Subroutines
In Per l , you can cal l subr out ines f r om ot her subr out ines. To cal l a subr out ine f r om
anot her subr out ine, use t he same subr out ine-invocat ion synt ax you've been using al l
al ong. Subr out ines t hat ar e cal l ed by ot her subr out ines ar e known as nested subroutines
(because one cal l is "nest ed" inside t he ot her ).
List ing 9.11 is an exampl e of a pr ogr am t hat cont ains a nest ed subr out ine. It is a f air l y
simpl e modif icat ion of List ing 9.10 and count s t he number of wor ds and char act er s in
t hr ee l ines of st andar d input . It al so demonst r at es how t o r et ur n mul t ipl e val ues f r om
a subr out ine.

List ing 9.11. An exampl e of a nest ed subr out ine.
1: #!/usr/local/bin/perl
2:
3: ($wordcount, $charcount) = &getcounts(3);
4: print ("Totals for three lines: ");
5: print ("$wordcount words, $charcount characters\n");
6:
7: sub getcounts {
8: my ($numlines) = @_;
9: my ($charpattern, $wordpattern);
10: my ($charcount, $wordcount);
11: my ($line, $linecount);
12: my (@retval);
13: $charpattern = "";
14: $wordpattern = "\\s+";
15: $linecount = $charcount = $wordcount = 0;
16: while (1) {
17: $line = <STDIN>;
18: last if ($line eq "");
19: $linecount++;
20: $charcount += &count($line, $charpattern);
21: $line =~ s/^\s+|\s+$//g;
22: $wordcount += &count($line, $wordpattern);
23: last if ($linecount == $numlines);
24: };
25: @retval = ($wordcount, $charcount);
26: }
27:
28: sub count {
29: my ($line, $pattern) = @_;
30: my ($count);
31: if ($pattern eq "") {
32: @items = split (//, $line);
33: } else {
34: @items = split (/$pattern/, $line);
35: }
36: $count = @items;
37: }

$ program9_11
This is a line of input.
Here is another line.
Here is the last line.
Totals for three lines: 15 words, 70 characters
$
The main body of t his pr ogr am now consist s of onl y f ive l ines of code,
incl uding t he special header comment and a bl ank l ine. This is because most of t he
act ual wor k is being done inside t he subr out ines. (This is common in l ar ge pr ogr ams. Most
of t hese pr ogr ams cal l a f ew main subr out ines, which in t ur n cal l ot her subr out ines.
This appr oach makes pr ogr ams easier t o r ead, because each subr out ine is compact and
concise.)
Line 3 cal l s t he subr out ine getcounts, which r et r ieves t he l ine and char act er count f or
t he t hr ee l ines f r om t he st andar d input f il e. Because a l ist cont aining t wo el ement s is
r et ur ned by getcounts, a st andar d "l ist t o scal ar var iabl e" assignment can be used t o
assign t he r et ur ned l ist dir ect l y t o $wordcount and $charcount.
The subr out ine getcounts is simil ar t o t he main body of t he pr ogr am in List ing 9.10. The
onl y dif f er ence is t hat t he while l oop has been modif ied t o l oop onl y t he number of
t imes specif ied by t he ar gument passed t o getcounts, which is st or ed in t he l ocal var iabl e
$numlines.
The subr out ine getcounts act ual l y does t he wor d and char act er count ing by cal l ing a
nest ed subr out ine, count. This subr out ine is ident ical t o t he subr out ine of t he same name
in List -ing 9.10.
NOTE
The @_ var iabl e is a l ocal var iabl e t hat is def ined inside
t he subr out ine. When a subr out ine cal l s a nest ed
subr out ine, a new copy of @_ is cr eat ed f or t he nest ed
subr out ine.
For exampl e, in List ing 9.11, when getcounts cal l s count,
a new copy of @_ is cr eat ed f or count, and t he @_ var iabl e
in getcounts is not changed.
Recursive Subroutines
In Per l , not onl y can subr out ines cal l ot her subr out ines, but subr out ines act ual l y can
cal l t hemsel ves. A subr out ine t hat cal l s it sel f is known as a recursive subroutine.
You can use a subr out ine as a r ecur sive subr out ine if t he f ol l owing t wo condit ions ar e
t r ue:
G Al l var iabl es t he subr out ine uses ar e l ocal (except t hose which ar e not changed
by t he subr out ine).
G The subr out ine cont ains code t hat , one way or anot her , det er mines when it
shoul d st op cal l ing it sel f .
When al l t he var iabl es t hat a subr out ine uses ar e l ocal , t he subr out ine cr eat es a new
copy of t he var iabl es each t ime it cal l s it sel f . This ensur es t hat t her e is no conf usion or
over l ap.
List ing 9.12 is an exampl e of a pr ogr am t hat cont ains a r ecur sive subr out ine. This
pr ogr am accept s a l ist of number s and oper ands t hat is t o be eval uat ed f r om r ight t o
l ef t , as if t he l ist is a st ack whose t op is t he l ef t end of t he l ist . For exampl e, if t he
input is
- 955 * 26 + 11 8
t his pr ogr am adds 11 and 8, mul t ipl ies t he r esul t by 26, and subt r act s t hat r esul t f r om
955. This is equival ent t o t he f ol l owing Per l expr ession:
955 - 26 * (11 + 8)

List ing 9.12. A pr ogr am t hat uses a r ecur sive subr out ine t o per f or m
ar it hmet ic.
1: #!/usr/local/bin/perl
2:
3: $inputline = <STDIN>;
4: $inputline =~ s/^\s+|\s+$//g;
5: @list = split (/\s+/, $inputline);
6: $result = &rightcalc (0);
7: print ("The result is $result.\n");
8:
9: sub rightcalc {
10: my ($index) = @_;
11: my ($result, $operand1, $operand2);
12:
13: if ($index+3 == @list) {
14: $operand2 = $list[$index+2];
15: } else {
16: $operand2 = &rightcalc ($index+2);
17: }
18: $operand1 = $list[$index+1];
19: if ($list[$index] eq "+") {
20: $result = $operand1 + $operand2;
21: } elsif ($list[$index] eq "*") {
22: $result = $operand1 * $operand2;
23: } elsif ($list[$index] eq "-") {
24: $result = $operand1 - $operand2;
25: } else {
26: $result = $operand1 / $operand2;
27: }
28: }

$ program9_12
- 98 * 4 + 12 11
The result is 6.
$
This pr ogr am st ar t s of f by r eading a l ine of input f r om t he st andar d input f il e
and br eaking it int o it s component s, which ar e st or ed as a l ist in t he ar r ay var iabl e
@list.
When given t he input
- 98 * 4 + 12 11
l ines 3-5 pr oduce t he f ol l owing l ist , which is assigned t o @list:
("-", "98", "*", "4", "+", "12", "11")
Line 6 cal l s t he subr out ine rightcalc f or t he f ir st t ime. rightcalc r equir es one
ar gument , an index val ue t hat t el l s t he subr out ine what par t of t he l ist t o wor k on.
Because t he f ir st ar gument her e is zero, rightcalc st ar t s wit h t he f ir st el ement in t he
l ist .
Line 10 assigns t he ar gument passed t o rightcalc t o t he l ocal var iabl e $index. When
rightcalc is cal l ed f or t he f ir st t ime, $index is 0.
Lines 13-17 ar e t he hear t of t his subr out ine, because t hey cont r ol whet her t o cal l
rightcalc r ecur sivel y. The basic l ogic is t hat a l ist such as
("-", "98", "*", "4", "+", "12", "11")
can be br oken int o t hr ee par t s: t he f ir st oper at or , -; t he f ir st oper and, 98; and a subl ist
(t he r est of t he l ist ). Not e t hat t he subl ist
("*", "4", "+", "12", "11")
is it sel f a compl et e set of oper at or s and oper ands; because t his pr ogr am is r equir ed t o
per f or m it s ar it hmet ic st ar t ing f r om t he r ight , t his subl ist must be cal cul at ed f ir st .
Line 13 checks whet her t her e is a subl ist t hat needs t o be eval uat ed f ir st . To do t his, it
checks whet her t her e ar e mor e t han t hr ee el ement s in t he l ist . If t her e ar e onl y t hr ee
el ement s in t he l ist , t he l ist consist s of onl y one oper at or and t wo oper ands, and t he
ar it hmet ic can be per f or med r ight away. If t her e ar e mor e t han t hr ee el ement s in t he
l ist , a subl ist exist s.
To eval uat e t he subl ist when it exist s, l ine 16 cal l s rightcalc r ecur sivel y. The index
val ue passed t o t his second copy of rightcalc is 2; t his ensur es t hat t he f ir st el ement of
t he l ist examined by t he second copy of rightcalc is t he el ement wit h subscr ipt 2, which
is *.
At t his point , t he f ol l owing is t he chain of subr out ine invocat ions, t heir ar gument s, and
t he par t of t he l ist on which t hey ar e wor king:
Level 1 Main pr ogr am
Level 2
rightcalc(0)-list ("-", "98", "*", "4", "+", "12",
"11")
Level 3 rightcalc(2)-list ("*", "4", "+", "12", "11")
When t his copy of rightcalc r eaches l ine 13, it checks whet her t he subl ist being wor ked
on has just t hr ee el ement s. Because t his subl ist has f ive el ement s, l ine 16 cal l s yet
anot her copy of rightcalc, t his t ime set t ing t he val ue of $index t o 4. The f ol l owing is
t he chain of subr out ine invocat ions af t er t his t hir d cal l :
Level 1 Main pr ogr am
Level 2
rightcalc(0)-list ("-", "98", "*", "4", "+", "12",
"11")
Level 3 rightcalc(2)-list ("*", "4", "+", "12", "11")
Level 4 rightcalc(4)-list ("+", "12", "11")
When t he t hir d copy of t his subr out ine r eaches l ine 13, it checks whet her t his por t ion of
t he l ist cont ains onl y t hr ee el ement s. Because it does, t he condit ional expr ession in l ine
13 is t r ue. At t his point , l ine 14 is execut ed f or t he f ir st t ime (by any copy of rightcalc);
it t akes t he val ue st or ed in $index-in t his case, 4, adds 2 t o it , and uses t he r esul t as t he
subscr ipt int o @list. This assigns 11, t he sevent h el ement of @list, t o $operand2.
Lines 18-27 per f or m an ar it hmet ic oper at ion. Line 18 adds one t o t he val ue in $index t o
r et r ieve t he l ocat ion of t he f ir st oper and; t his oper and is assigned t o $operand1. In t his
copy of rightcalc, t he subscr ipt is 5 (4+1), and t he sixt h el ement of @list, 12, is assigned
t o $operand1.
Line 19 uses $index as t he subscr ipt int o t he l ist t o access t he ar it hmet ic oper at or f or
t his oper at ion. In t his case, t he f if t h el ement of $index (subscr ipt 4) is +, and t he
expr ession in l ine 19 is t r ue. Line 20 t hen adds $operand1 t o $operand2, yiel ding $result,
which is 23. This val ue is r et ur ned by t his copy of rightcalc.
When t he t hir d copy of rightcalc r et ur ns, execut ion cont inues wit h t he second copy of
rightcalc because t he second copy cal l ed t he t hir d copy. Line 16 of t he second copy
assigns t he r et ur n val ue of t he t hir d copy, 23, t o $operand2. The f ol l owing is t he st at e
of t he pr ogr am af t er l ine 16 has f inished execut ing:
Level 1 Main pr ogr am
Level 2
rightcalc(0)-list ("-", "98", "*", "4", "+", "12",
"11")
Level 3
rightcalc(2)-list ("*", "4", "+", "12", "11"),
$operand2 is 23
The Per l int er pr et er now execut es l ines 18-27. Because $index is 2 in t his copy of
rightcalc, l ine 18 assigns t he f our t h el ement of @list, 4, t o $operand1. Line 21 is t r ue in
t his case because t he oper at or is *; t his means t hat l ine 22 mul t ipl ies $operand1 (4) by
$operand2 (23), yiel ding 92, which is assigned t o $result.
At t his point , t he second copy of rightcalc is f inished, and pr ogr am execut ion r et ur ns t o
l ine 16. This assigns t he r et ur n val ue f r om t he second copy, 92, t o $operand2.
The f ol l owing is t he st at e of t he pr ogr am af t er t he second copy of rightcalc is f inished:
Level 1 Main pr ogr am
Level 2
rightcalc(0)-list ("-", "98", "*", "4", "+", "12",
"11"), $operand2 is 92
Now you'r e al most f inished; t he pr ogr am is execut ing onl y one copy of rightcalc.
Because $index is 0 in t his copy of rightcalc, l ine 18 assigns 98 t o $operand1. Line 23 is
t r ue in t his case because t he oper at or her e is -; l ine 24 t hen t akes 98 and subt r act s 92
f r om it , yiel ding a f inal r esul t of 6.
This f inal r esul t of 6 is passed t o t he main pr ogr am and is assigned t o $result. (Not e t hat
t her e is no conf l ict bet ween $result in t he main pr ogr am and t he var ious copies of
$result in rightcalc because $result is def ined as a l ocal var iabl e in rightcalc.) Line 7,
f inal l y, pr int s t his r esul t .
NOTE
Recur sive subr out ines ar e usef ul when handl ing
compl icat ed dat a st r uct ur es such as t r ees. You wil l see
exampl es of such compl icat ed dat a st r uct ur es on Day 10,
"Associat ive Ar r ays."
Passing Arrays by Name Using Aliases
As you have seen, Per l enabl es you t o pass an ar r ay as an ar gument t o a subr out ine.
&my_sub(@array);
When t he subr out ine my_sub is cal l ed, t he l ist st or ed in t he ar r ay var iabl e @array is
copied t o t he var iabl e @_ def ined in t he subr out ine.
sub my_sub {
my (@subarray) = @_;
$arraylength = @subarray;
}
If t he ar r ay being passed is l ar ge, it might t ake some t ime (and consider abl e space) t o
cr eat e a copy of t he ar r ay. If your appl icat ion is oper at ing under t ime or space
l imit at ions, or you just want t o make it mor e ef f icient , you can specif y t hat t he ar r ay is
t o be passed by name.
The f ol l owing is an exampl e of a simil ar subr out ine t hat r ef er s t o an ar r ay by name:
sub my_sub {
my (*subarray) = @_;
$arraylength = @subarray;
}
The *subarray def init ion t el l s t he Per l int er pr et er t o oper at e on t he act ual l ist passed
t o
my_sub inst ead of making a copy.
To cal l t his subr out ine, specif y * inst ead of @ wit h t he ar r ay var iabl e name, as in t he
f ol l owing:
@myarray = (1, 2, 3, 4, 5);
&my_sub(*myarray);
Specif ying *myarray inst ead of @myarray indicat es t hat t he act ual cont ent s of @myarray
ar e t o be used (and modif ied if desir ed) in my_sub. In f act , whil e t he subr out ine is being
execut ed, t he name @subarray becomes ident ical t o t he name @myarray. This pr ocess of
cr eat ing anot her name t o r ef er t o t he same var iabl e is known as aliasing. @subarray is
now an al ias of @myarray.
When my_sub t er minat es, @subarray st ops being an al ias of @myarray. When my_sub is
cal l ed again wit h a dif f er ent ar gument , as in
&my_sub(*anotherarray);
t he var iabl e @subarray in my_sub becomes an al ias f or @anotherarray, which means t hat
you can use t he ar r ay var iabl e @subarray t o access t he st or age in @anotherarray.
Al iasing ar r ays in t his manner has one dist inct advant age and one dist inct dr awback.
The advant age is t hat your pr ogr am becomes mor e ef f icient . You don't need t o copy t he
ent ir e l ist f r om your main pr ogr am t o t he subr out ine. The disadvant age is t hat your
pr ogr am becomes mor e dif f icul t t o f ol l ow. You have t o r emember , f or exampl e, t hat
changing t he cont ent s of @subarray in t he subr out ine my_sub al so changes t he cont ent s
of @myarray and @anotherarray. It is easy t o l ose t r ack of which name r ef er s t o which
var iabl e.
Ther e is al so anot her pr obl em wit h al iasing: al iasing af f ect s al l var iabl es wit h t he same
name, not just ar r ay var iabl es.
For exampl e, consider List ing 9.13, which def ines a scal ar var iabl e named $foo and an
ar r ay named @foo, and t hen al iases @foo. As you'l l see, t he pr ogr am al iases $foo as wel l .

List ing 9.13. A pr ogr am t hat demonst r at es al iasing.
1: #!/usr/local/bin/perl
2:
3: $foo = 26;
4: @foo = ("here's", "a", "list");
5: &testsub (*foo);
6: print ("The value of \$foo is now $foo\n");
7:
8: sub testsub {
9: local (*printarray) = @_;
10: foreach $element (@printarray) {
11: print ("$element\n");
12: }
13: $printarray = 61;
14: }

$ program9_13
here's
a
list
The value of $foo is now 61
$
Line 5 cal l s t he subr out ine testsub. The ar gument , *foo, indicat es t hat t he
ar r ay @foo is t o be passed t o testsub and al iased.
The l ocal var iabl e def init ion in l ine 9 indicat es t hat t he ar r ay var iabl e @printarray is
t o become an al ias of t he ar r ay var iabl e @foo. This means t hat t he name printarray is
def ined t o be equival ent t o t he name foo.
As a consequence, t he scal ar var iabl e $printarray becomes an al ias of t he scal ar
var iabl e $foo. Because of t his, l ine 13, which seems t o assign 61 t o $printarray, act ual l y
assigns 61 t o $foo. This modif ied val ue is pr int ed by l ine 6 of t he main pr ogr am.
NOTE
Al iasing enabl es you t o pass mor e t han one l ist t o a
subr out ine.
@array1 = (1, 2, 3);
@array2 = (4, 5, 6);
&two_array_sub (*array1, *array2);
sub two_array_sub {
my (*subarray1, *subarray2) = @_;
}
In t his case, t he names array1 and array2 ar e passed t o
two_array_sub. subarray1 becomes an al ias f or array1,
and subarray2 becomes an al ias f or array2.
Using the do Statement with Subroutines
Per l enabl es you t o use t he do st at ement t o invoke a subr out ine. For exampl e, t he
f ol l owing st at ement s ar e ident ical :
&my_sub(1, 2, 3);
do my_sub(1, 2, 3);
Ther e is no r eal r eason t o use t he do st at ement in t his cont ext .
Specifying the Sort Order
By def aul t , t he buil t -in f unct ion sort sor t s in al phabet ical or der . The f ol l owing is an
exampl e:
@list = ("words", "to", "sort");
@list2 = sort (@list);
Her e, @list2 is assigned ("sort", "to", "words").
If you want , you can wr it e a subr out ine t hat def ines how sor t ing is t o be accompl ished.
To under st and how t o do t his, f ir st you need t o know a l it t l e about how sor t ing wor ks.
When sort is given a l ist t o sor t , it det er mines t he sor t or der of t he el ement s of t he l ist
by r epeat edl y compar ing pair s of el ement s. To compar e a pair of el ement s, sort cal l s a
special int er nal subr out ine and passes it a pair of ar gument s. Al t hough t he subr out ine is
not accessibl e f r om a Per l pr ogr am, it basical l y behaves as f ol l ows:
sub sort_criteria {
if ($a gt $b) {
retval = -1;
} elsif ($a eq $b) {
retval = 0;
} else
retval = 1;
}
$retval;
}
This subr out ine compar es t wo val ues, which ar e st or ed in $a and $b. It r et ur ns -1 if t he
f ir st val ue is gr eat er , 0 if t he val ues ar e equal , and 1 if t he second val ue is gr eat er .
(This, by t he way, is how t he cmp oper at or wor ks; in f act , t he pr eceding subr out ine coul d
compar e t he t wo val ues using a singl e cmp oper at or .)
To def ine your own sor t ing r ul es, you must wr it e a subr out ine whose behavior is
ident ical t o t he pr eceding subr out ine. This subr out ine must use t wo gl obal var iabl es
named $a and $b t o r epr esent t he t wo it ems in t he l ist cur r ent l y being compar ed, and t he
subr out ine must r et ur n one of t he f ol l owing val ues:
-1
If $a is t o appear bef or e $b in t he r esul t ing sor t ed l ist
0
If $a is t o be t r eat ed as equal t o $b
1
If $a is t o appear af t er $b in t he r esul t ing sor t ed l ist
NOTE
Even t hough $a and $b ar e gl obal var iabl es t hat ar e
used by t he sor t ing subr out ine, you st il l can def ine
gl obal var iabl es of your own named $a and $b wit hout
r isking t heir being over wr it t en.
The buil t -in f unct ion sort saves any exist ing val ues of
$a and $b bef or e sor t ing, and t hen it r est or es t hem when
sor t ing is compl et ed.
Af t er you have wr it t en t he subr out ine, you must specif y t he subr out ine name when
cal l ing t he f unct ion sort. For exampl e, if you def ine a f unct ion named foo t hat pr ovides
a set of sor t ing r ul es, t he f ol l owing st at ement sor t s a l ist using t he r ul es def ined in
foo:
@list2 = sort foo (@list1);
List ing 9.14 shows how you can def ine your own sor t cr it er ia. This pr ogr am sor t s a l ist in
t he nor mal or der , except t hat it put s st r ings st ar t ing wit h a digit l ast . (By def aul t ,
st r ings st ar t ing wit h a number appear bef or e st r ings st ar t ing wit h a l et t er , and bef or e
some-but not al l -special char act er s.) St r ings t hat begin wit h a digit ar e assumed t o be
number s and ar e sor t ed in numer ical or der .

List ing 9.14. A pr ogr am t hat def ines sor t cr it er ia.
1: #!/usr/local/bin/perl
2:
3: @list1 = ("test", "14", "26", "test2");
4: @list2 = sort num_last (@list1);
5: print ("@list2\n");
6:
7: sub num_last {
8: my ($num_a, $num_b);
9:
10: $num_a = $a =~ /^[0-9]/;
11: $num_b = $b =~ /^[0-9]/;
12: if ($num_a && $num_b) {
13: $retval = $a <=> $b;
14: } elsif ($num_a) {
15: $retval = 1;
16: } elsif ($num_b) {
17: $retval = -1;
18: } else {
19: $retval = $a cmp $b;
20: }
21: $retval;
22: }

$ program9_14
test test2 14 26
$
Line 4 sor t s t he pr ogr am accor ding t o t he sor t cr it er ia def ined in t he
subr out ine num_last. This subr out ine is def ined in l ines 7-22.
This subr out ine f ir st det er mines whet her t he it ems ar e st r ings t hat begin wit h a digit .
Line 10 set s t he l ocal var iabl e $num_a t o a nonzer o val ue if t he val ue st or ed in $a
st ar t s wit h a digit ; simil ar l y, l ine 11 set s $num_b t o a nonzer o val ue if t he val ue of $b
st ar t s wit h a digit .
Lines 12 and 13 handl e t he case in which bot h $num_a and $num_b ar e t r ue. In t his case,
t he t wo st r ings ar e assumed t o be digit s, and t he numer ic compar ison oper at or <=>
compar es t heir val ues. The r esul t of t he <=> oper at ion is -1 if t he f ir st number is l ar ger ,
0 if t hey ar e equal , and 1 if t he second number is l ar ger .
If $num_a is t r ue but $num_b is f al se, l ine 15 set s t he r et ur n val ue f or t his subr out ine t o
1, indicat ing t hat t he st r ing t hat does not st ar t wit h a digit , $b, is t o be t r eat ed as
gr eat er . Simil ar l y, l ine 17 set s t he r et ur n val ue t o -1 if $b st ar t s wit h a digit and $a
does not .
If neit her st r ing st ar t s wit h a digit , l ine 19 uses t he nor mal sor t cr it er ion-al phabet ical
or der -t o det er mine which val ue is l ar ger . Her e, t he cmp oper at or is usef ul . It r et ur ns -1
if t he f ir st st r ing is al phabet ical l y gr eat er , 0 if t he st r ings ar e equal , and 1 if t he
second st r ing is al phabet ical l y gr eat er .
Predefined Subroutines
Per l 5 def ines t hr ee special subr out ines t hat ar e execut ed at specif ic t imes.
G The BEGIN subr out ine, which is cal l ed when your pr ogr am st ar t s r unning
G The END subr out ine, which is cal l ed when your pr ogr am t er minat es
G The AUTOLOAD subr out ine, which is cal l ed when your pr ogr am can't f ind a
subr out ine it is supposed t o execut e
NOTE
These subr out ines ar e not suppor t ed in Per l 4.
Creating Startup Code Using BEGIN
Per l 5 enabl es you t o cr eat e code t hat is execut ed when your pr ogr am is st ar t ed. To do
t his, cr eat e a special subr out ine named BEGIN. For exampl e:
BEGIN {
print("Hi! Welcome to Perl!\n");
}
When your pr ogr am begins execut ion, t he f ol l owing l ine appear s on your scr een:
Hi! Welcome to Perl!
The BEGIN subr out ine behaves just l ike any ot her Per l subr out ine. For exampl e, you can
def ine l ocal var iabl es f or it or cal l ot her subr out ines f r om it .
NOTE
If you l ike, you can def ine mul t ipl e BEGIN subr out ines.
These subr out ines ar e cal l ed in t he or der in which t hey
appear in t he pr ogr am.
Creating Termination Code Using END
Per l 5 enabl es you t o cr eat e code t o be execut ed when your pr ogr am t er minat es
execut ion. To do t his, def ine an END subr out ine, as in t he f ol l owing exampl e:
END {
print("Thank you for using Perl!\n");
}
The code cont ained in t he END subr out ine is al ways execut ed by your pr ogr am, even if
t he pr ogr am is t er minat ed using die. For exampl e, t he code
die("Prepare to die!\n");
END {
print("Ha! You can't kill me!\n");
}
displ ays t he f ol l owing on your scr een:
Prepare to die!
Ha! You can't kill me!
NOTE
You can def ine mul t ipl e END subr out ines in your
pr ogr am. In t his case, t he subr out ines ar e execut ed in
r ever se or der of appear ance, wit h t he l ast one execut ed
f ir st .
Handling Non-Existent Subroutines Using AUTOLOAD
Per l 5 enabl es you t o def ine a special subr out ine named AUTOLOAD t hat is cal l ed
whenever t he Per l int er pr et er is t ol d t o cal l a subr out ine t hat does not exist . List ing
9.15 il l ust r at es t he use of AUTOLOAD.

List ing 9.15. A pr ogr am t hat uses AUTOLOAD.
1: #!/usr/local/bin/perl
2:
3: &nothere("hi", 46);
4:
5: AUTOLOAD {
6: print("subroutine $AUTOLOAD not found\n");
7: print("arguments passed: @_\n");
8: }

$ program9_15
subroutine main::nothere not found
arguments passed: hi 46
$
This pr ogr am t r ies t o cal l t he non-exist ent subr out ine nothere. When t he
Per l int er pr et er discover s t hat nothere does not exist , it cal l s t he AUTOLOAD subr out ine.
Line 6 uses a special scal ar var iabl e, $AUTOLOAD, which cont ains t he name of t he
subr out ine you t r ied t o cal l . (The main:: t ext t hat appear s bef or e t he subr out ine name,
nothere, is t he name of t he package in which t he subr out ine is f ound. By def aul t , al l
your code is pl aced in one package, cal l ed main, so you nor mal l y won't need t o wor r y
about packages. For mor e inf or mat ion on cr eat ing ot her packages, see Day 19, "Object -
Or ient ed Pr ogr amming in Per l .")
When AUTOLOAD is cal l ed, t he ar gument s t hat wer e t o be passed t o t he non-exist ent
subr out ine ar e passed t o AUTOLOAD inst ead. This means t hat t he @ ar r ay var iabl e cont ains
t he l ist ("hi", 46), because t hese ar e t he ar gument s t hat wer e t o be passed t o nothere.
TIP
AUTOLOAD is usef ul if you pl an t o or ganize your Per l
pr ogr am int o modul es, because you can use it t o ensur e
t hat cr ucial subr out ines f r om ot her f il es act ual l y exist
when you need t hem. For mor e inf or mat ion on or ganizing
Per l pr ogr ams int o modul es, see Day 19.
Summary
Today, you l ear ned about subr out ines, which ar e separ at ed chunks of code int ended t o
per f or m specif ic t asks. A subr out ine can appear anywher e in your pr ogr am.
To invoke a subr out ine, specif y it s name pr eceded by t he & char act er . In Per l 5, t he &
char act er is not r equir ed if t he subr out ine exist s, or if a f or war d r ef er ence is def ined.
A subr out ine can r et ur n a val ue (eit her a scal ar val ue or a l ist ). This r et ur n val ue is
t he val ue of t he l ast expr ession eval uat ed inside t he subr out ine. If t his l ast expr ession
is at t he end of t he subr out ine, t he subr out ine is a singl e-exit modul e.
You can def ine l ocal var iabl es f or use inside subr out ines. These l ocal var iabl es exist
onl y whil e t he subr out ine is being execut ed. When a subr out ine f inishes, it s l ocal
var iabl es ar e dest r oyed; if it is invoked again, new copies of t he l ocal var iabl es ar e
def ined.
You can pass val ues t o subr out ines; t hese val ues ar e cal l ed ar gument s. You can pass as
many ar gument s as you l ike, but onl y one of t hese ar gument s can be a l ist . If a l ist is
passed t o a subr out ine, it must be t he l ast ar gument passed.
The ar gument s passed t o a subr out ine ar e conver t ed int o a l ist and assigned t o a special
syst em var iabl e, @_. One copy of @_ exist s f or each l ist of ar gument s passed t o a
subr out ine (t hat is, @_ is a l ocal var iabl e).
Subr out ines can cal l ot her subr out ines (nest ed subr out ines) and even can cal l
t hemsel ves (r ecur sive subr out ines).
You can pass an ar r ay var iabl e t o a subr out ine by name by def ining an al ias f or t he
var iabl e name. This al ias af f ect s al l var iabl es of t hat name.
You can use t he do st at ement t o invoke a subr out ine, al t hough t her e is no r eal r eason
t o do so.
You can def ine a subr out ine t hat specif ies t he or der in which t he el ement s of a l ist ar e
t o be sor t ed. To use t he sor t cr it er ia def ined by a subr out ine, incl ude it s name wit h t he
cal l t o sort.
The BEGIN subr out ine is al ways execut ed bef or e your pr ogr am begins execut ion. The END
subr out ine is al ways execut ed when your pr ogr am t er minat es, even if it was kil l ed of f
using die. The AUTOLOAD subr out ine is execut ed if your pr ogr am t r ies t o cal l a subr out ine
t hat does not exist .
Q&A
Q: How many l evel s of nest ed subr out ines can a pr ogr am have?
A: This depends on t he amount of memor y in your machine. Nor mal l y, it is l ar ge
enough t o onl y be an issue when you ar e using r ecur sive subr out ines.
Q: Which is bet t er : passing ent ir e l ist s or passing ar r ay var iabl es by name?
A: As wit h so many issues in pr ogr amming, t his depends on t he sit uat ion. If your
pr ogr am needs t o be space-ef f icient or t o r un as quickl y as possibl e, passing ar r ay
var iabl es by name might be t he best choice.
Anot her opt ion is t o use t he gl obal ar r ay var iabl e bot h inside and out side t he
subr out ine. This wor ks wel l if t he ar r ay var iabl e is t he cent r al r eposit or y f or
pr ogr am dat a.
Q: When ar e gl obal var iabl es a good idea? When is it bet t er t o pass t he
cont ent s of a var iabl e t o a subr out ine?
A: If your subr out ine is a gener al -pur pose subr out ine t hat per f or ms a t ask such as
br eaking a scal ar val ue int o wor ds, it 's a good idea t o pass t he val ue as an
ar gument . For exampl e:
sub breakline {
local ($line) = @_;
@words = split(/\s+/, $line);
}
If you do not pass t he l ine as an ar gument , breakline wil l be abl e t o wor k onl y
wit h t he l ine st or ed in a par t icul ar scal ar var iabl e, which makes it l ess usef ul .
On t he ot her hand, if your pr ogr am st or es inf or mat ion in a cent r al ar r ay, t her e's
no r eason t o pass t he ar r ay or t he ar r ay name t o a subr out ine t hat pr ocesses t he
ar r ay. For exampl e, if you ar e using t he ar r ay @occurs t o count al l t he
occur r ences of t he digit s 0 t hr ough 9 in a f il e, t her e's no r eason t o pass @occurs
t o a subr out ine. For exampl e:
sub printcount {
for ($count = 0; $count <= 9; $count++) {
print ("$occurs[$count]\n");
}
}
Because printcount is not l ikel y t o be used wit h any ar r ay except @occurs,
t her e's no need t o pass it as an ar gument .
Q: When Per l def ines an al ias f or an ar r ay-var iabl e name in a subr out ine, such
as @localname f or @name in a subr out ine, why does it al so def ine t he al ias
$localname f or $name?
A: St r ict l y speaking, t he * char act er in an al ias r epr esent s any char act er t hat
pr ecedes a var iabl e name (such as @ or $).
For exampl e, consider t he f ol l owing subr out ine and t he cor r esponding st at ement
t hat cal l s it :
sub arraybyname {
local (*localname) = @_;
}
arraybyname (*name);
When t he Per l int er pr et er sees t he r ef er ence t o *localname in t he subr out ine, it
r epl aces t he al ias f ol l owing t he * wit h t he name f or which t he al ias is def ined.
In t his case, t he Per l int er pr et er r epl aces *localname wit h *name.
The Per l int er pr et er t hen det er mines, f r om cont ext , whet her *name is an ar r ay
var iabl e, a scal ar var iabl e, or somet hing el se. In t his case, *name is int ended t o be
an ar r ay var iabl e, which means t hat *name becomes @name.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. Def ine t he f ol l owing t er ms:
a. subr out ine
b. invocat ion
c. ar gument
d. singl e-exit modul e
e. al iasing
2. Consider t he f ol l owing pr ogr am:
#!/usr/local/bin/perl
$total = 0;
@list = (1, 2, 3);
@list2 = &my_sub;
sub my_sub {
local ($total);
$total = 1;
@list = (4, 5, 6);
}
What ar e t he val ues st or ed in t he f ol l owing var iabl es at t he end of t his pr ogr am?
a. $total
b. @list
c. @list2
3. What does t he f ol l owing subr out ine r et ur n?
sub sub1 {
$count = $sum = 0;
while ($count <= 10) {
$sum += $count;
$count++;
}
}
4. What is t he val ue of @list at t he end of t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
@list = (1, 2, 3);
&testsub(*list);
sub testsub {
local (*sublist) = @_;
$sublist[1] = 5;
}
Exercises
1. Wr it e a subr out ine t hat t akes t wo ar gument s, adds t hem t oget her , and r et ur ns
t he r esul t .
2. Wr it e a subr out ine t hat count s t he number of occur r ences of t he l et t er t in a
st r ing (which is passed t o t he subr out ine). The subr out ine must r et ur n t he number
of occur r ences.
3. Wr it e a subr out ine t hat t akes t wo f il enames as it s ar gument s and r et ur ns a
nonzer o val ue if t he t wo f il es have ident ical cont ent s. Ret ur n 0 if t he f il es
dif f er .
4. Wr it e a subr out ine t hat simul at es t he r ol l of a die (t hat is, it gener at es a r andom
number bet ween 1 and 6) and r et ur ns t he number .
5. Wr it e a subr out ine t hat uses r ecur sion t o pr int a l ist in r ever se or der . The
subr out ine must r ecur sivel y cal l it sel f t o pr int t he ent ir e l ist ; each invocat ion
must pr int one wor d of t he l ist . (Assume t hat t he f ir st cal l t o your subr out ine
passes t he val ue 0 and t he l ist t o be pr int ed.)
6. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
for ($count = 1; $count <= 10; $count++) {
&print_ten ($count);
}
sub print_ten {
local ($multiplier) = @_;
for ($count = 1; $count <= 10; $count++) {
$printval = $multiplier * 10 + $count;
print ("$printval\n");
}
}
7. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
$line = <STDIN>;
@words = split(/\s+/, $line);
$searchword = <STDIN>;
&search_for_word (@words, $searchword);
sub search_for_word {
local (@searchlist, $searchword) = @_;
foreach $word (@searchlist) {
return (1) if ($word eq $searchword);
}
$retval = 0;
}
8. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
$line = <STDIN>;
@words = &split_line($line);
print ("@words\n");
sub split_line {
local ($line) = @_;
local (@words);
@words = split(/\s+/, $line);
if (@words == 0) {
@words = ("empty list");
}
}

Chapter 10
Associative Arrays
CONTENTS
G Limit at ions of Ar r ay Var iabl es
G Def init ion
G Ref er r ing t o Associat ive Ar r ay El ement s
G Adding El ement s t o an Associat ive Ar r ay
G Cr eat ing Associat ive Ar r ays
G Copying Associat ive Ar r ays f r om Ar r ay Var iabl es
G Adding and Del et ing Ar r ay El ement s
G List ing Ar r ay Indexes and Val ues
G Looping Using an Associat ive Ar r ay
G Cr eat ing Dat a St r uct ur es Using Associat ive Ar r ays
H Linked List s
H St r uct ur es
H Tr ees
H Dat abases
H Exampl e: A Cal cul at or Pr ogr am
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson shows you how t o use associat ive ar r ays. You'l l l ear n t he f ol l owing:
G What an associat ive ar r ay is
G How t o access and cr eat e an associat ive ar r ay
G How t o copy t o and f r om an associat ive ar r ay
G How t o add and del et e associat ive ar r ay el ement s
G How t o l ist ar r ay indexes and val ues
G How t o l oop using an associat ive ar r ay
G How t o buil d dat a st r uct ur es using associat ive ar r ays
To st ar t , t ake a l ook at some of t he pr obl ems t hat using ar r ay var iabl es cr eat es. Once
you have seen some of t he dif f icul t ies cr eat ed by ar r ay var iabl es in cer t ain cont ext s,
you'l l see how associat ive ar r ays can el iminat e t hese dif f icul t ies.
Limitations of Array Variables
In t he ar r ay var iabl es you've seen so f ar , you can access an el ement of a st or ed l ist by
specif ying a subscr ipt . For exampl e, t he f ol l owing st at ement accesses t he t hir d el ement
of t he l ist st or ed in t he ar r ay var iabl e @array:
$scalar = $array[2];
The subscr ipt 2 indicat es t hat t he t hir d el ement of t he ar r ay is t o be r ef er enced.
Al t hough ar r ay var iabl es ar e usef ul , t hey have one signif icant dr awback: it 's of t en
dif f icul t t o r emember which el ement of an ar r ay st or es what . For exampl e, suppose you
want t o wr it e a pr ogr am t hat count s t he number of occur r ences of each capit al ized
wor d in an input f il e. You can do t his using ar r ay var iabl es, but it 's ver y dif f icul t .
List ing 10.1 shows you what you have t o go t hr ough t o do t his.

List ing 10.1. A pr ogr am t hat uses ar r ay var iabl es t o keep t r ack of
capit al ized wor ds in an input f il e.
1: #!/usr/local/bin/perl
2:
3: while ($inputline = <STDIN>) {
4: while ($inputline =~ /\b[A-Z]\S+/g) {
5: $word = $&;
6: $word =~ s/[;.,:-]$//; # remove punctuation
7: for ($count = 1; $count <= @wordlist;
8: $count++) {
9: $found = 0;
10: if ($wordlist[$count-1] eq $word) {
11: $found = 1;
12: $wordcount[$count-1] += 1;
13: last;
14: }
15: }
16: if ($found == 0) {
17: $oldlength = @wordlist;
18: $wordlist[$oldlength] = $word;
19: $wordcount[$oldlength] = 1;
20: }
21: }
22: }
23: print ("Capitalized words and number of occurrences:\n");
24: for ($count = 1; $count <= @wordlist; $count++) {
25: print ("$wordlist[$count-1]: $wordcount[$count-1]\n");
26: }

$ program10_1
Here is a line of Input.
This Input contains some Capitalized words.
^D
Capitalized words and number of occurrences:
Here: 1
Input: 2
This: 1
Capitalized: 1
$
This pr ogr am r eads one l ine of input at a t ime f r om t he st andar d input f il e.
The l oop st ar t ing on l ine 4 mat ches each capit al ized wor d in t he l ine; t he l oop it er at es
once f or each mat ch, and it assigns t he mat ch being examined in t his par t icul ar it er at ion
t o t he scal ar var iabl e $word.
Once any cl osing punct uat ion has been r emoved by l ine 6, t he pr ogr am must t hen check
whet her t his wor d has been seen bef or e. Lines 7-15 do t his by examining each el ement of
t he l ist @wordlist in t ur n. If an el ement of @wordlist is ident ical t o t he wor d st or ed in
$word, t he cor r esponding el ement of @wordcount is incr ement ed.
If no el ement of @wordlist mat ches $word, l ines 16-20 add a new el ement t o @wordlist
and @wordcount.
Definition
As you can see, using ar r ay var iabl es cr eat es sever al pr obl ems. Fir st , it 's not obvious
which el ement of @wordlist in List ing 10.1 cor r esponds t o which capit al ized wor d. In t he
exampl e shown, $wordlist[0] cont ains Here because t his is t he f ir st capit al ized wor d in
t he input f il e, but t his is not obvious t o t he r eader .
Wor se st il l , t he pr ogr am has no way of knowing which el ement of @wordlist cont ains
which wor d. This means t hat ever y t ime t he pr ogr am r eads a new wor d, it has t o check
t he ent ir e l ist t o see if t he wor d has al r eady been f ound. This becomes t ime-consuming as
t he l ist gr ows l ar ger .
Al l of t hese pr obl ems wit h ar r ay var iabl es exist because el ement s of ar r ay var iabl es ar e
accessed by numer ic subscr ipt s. To get ar ound t hese pr obl ems, Per l def ines anot her kind
of ar r ay, which enabl es you t o access ar r ay var iabl es using any scal ar val ue you l ike.
These ar r ays ar e cal l ed associative arrays.
To dist inguish an associat ive ar r ay var iabl e f r om an or dinar y ar r ay var iabl e, Per l uses
t he % char act er as t he f ir st char act er of an associat ive ar r ay-var iabl e name, inst ead of
t he @ char act er . As wit h ot her var iabl e names, t he f ir st char act er f ol l owing t he % must
be a l et t er , and subsequent char act er s can be l et t er s, digit s, or under scor es.
The f ol l owing ar e exampl es of associat ive ar r ay-var iabl e names:
%assocarray
%a1
%my_really_long_but_legal_array_variable_name
NOTE
Use t he same name f or an associat ive ar r ay var iabl e and
an or dinar y ar r ay var iabl e. For exampl e, you can def ine
an ar r ay var iabl e named @arrayname and an associat ive
ar r ay var iabl e named %arrayname.
The @ and % char act er s ensur e t hat t he Per l int er pr et er
can t el l one var iabl e name f r om anot her .
Referring to Associative Array Elements
The main dif f er ence bet ween associat ive ar r ays and or dinar y ar r ays is t hat associat ive
ar r ay subscr ipt s can be any scal ar val ue. For exampl e, t he f ol l owing st at ement r ef er s
t o an el ement of t he associat ive ar r ay %fruit:
$fruit{"bananas"} = 1;
The subscr ipt f or t his ar r ay el ement is bananas. Any scal ar val ue can be a subscr ipt . For
exampl e:
$fruit{"black_currant"}
$number{3.14159}
$integer{-7}
A scal ar var iabl e can be used as a subscr ipt , as f ol l ows:
$fruit{$my_fruit}
Her e, t he cont ent s of $my_fruit become t he subscr ipt int o t he associat ive ar r ay %fruit.
When an ar r ay el ement is r ef er enced, as in t he pr evious exampl e, t he name of t he ar r ay
el ement is pr eceded by a $ char act er , not t he % char act er . As wit h ar r ay var iabl es, t his
t el l s t he Per l int er pr et er t hat t his is a singl e scal ar it em and is t o be t r eat ed as such.
NOTE
Subscr ipt s f or associat ive ar r ay el ement s ar e al ways
encl osed in br ace br acket s ({}), not squar e br acket s ([]).
This ensur es t hat t he Per l int er pr et er is al ways abl e t o
dist inguish associat ive ar r ay el ement s f r om ot her ar r ay
el ement s.
Adding Elements to an Associative Array
The easiest way t o cr eat e an associat ive ar r ay it em is just t o assign t o it . For exampl e,
t he st at ement
$fruit{"bananas"} = 1;
assigns 1 t o t he el ement bananas of t he associat ive ar r ay %fruit. If t his el ement does not
exist , it is cr eat ed. If t he ar r ay %fruit has not been r ef er r ed t o bef or e, it al so is cr eat ed.
This f eat ur e makes it easy t o use associat ive ar r ays t o count occur r ences of it ems. For
exampl e, List ing 10.2 shows how you can use associat ive ar r ays t o count t he number of
capit al ized wor ds in an input f il e. Not e how much simpl er t his pr ogr am is t han t he one in
List ing 10.1, which accompl ishes t he same t ask.

List ing 10.2. A pr ogr am t hat uses an associat ive ar r ay t o count t he
number of capit al ized wor ds in a f il e.
1: #!/usr/local/bin/perl
2:
3: while ($inputline = <STDIN>) {
4: while ($inputline =~ /\b[A-Z]\S+/g) {
5: $word = $&;
6: $word =~ s/[;.,:-]$//; # remove punctuation
7: $wordlist{$word} += 1;
8: }
9: }
10: print ("Capitalized words and number of occurrences:\n");
11: foreach $capword (keys(%wordlist)) {
12: print ("$capword: $wordlist{$capword}\n");
13: }

$ program10_2
Here is a line of Input.
This Input contains some Capitalized words.
^D
Capitalized words and number of occurrences:
This: 1
Input: 2
Here: 1
Capitalized: 1
$
As you can see, t his pr ogr am is much simpl er t han t he one in List ing 10.1.
The pr evious pr ogr am r equir ed 20 l ines of code t o r ead input and st or e t he count s
f or each wor d; t his pr ogr am r equir es onl y seven.
As bef or e, t his pr ogr am r eads one l ine of input at a t ime f r om t he st andar d input
f il e. The l oop st ar t ing in l ine 4 it er at es once f or each capit al ized wor d f ound in
t he input l ine; each mat ch is assigned, in t ur n, t o t he scal ar var iabl e $word.
Line 7 uses t he associat ive ar r ay %wordlist t o keep t r ack of t he capit al ized wor ds.
Because associat ive ar r ays can use any val ue as a subscr ipt f or an el ement , t his
l ine uses t he wor d it sel f as a subscr ipt . Then, t he el ement of t he ar r ay
cor r esponding t o t he wor d has 1 added t o it s val ue.
For exampl e, when t he wor d Here is r ead in, t he associat ive ar r ay el ement
$wordlist{"Here"} has 1 added t o it s val ue.
Lines 11-13 pr int t he el ement s of t he associat ive ar r ay. Line 11 cont ains a cal l t o a
special buil t -in f unct ion, keys. This f unct ion r et ur ns a l ist consist ing of t he
subscr ipt s of t he associat ive ar r ay; t he foreach st at ement t hen l oops t hr ough t his
l ist , it er at ing once f or each el ement of t he associat ive ar r ay. Each subscr ipt of
t he associat ive ar r ay is assigned, in t ur n, t o t he l ocal var iabl e $capword; in t his
exampl e, t his means t hat $capword is assigned Here, Input, Capitalized, and This-one
per each it er at ion of t he for each l oop.
An impor t ant f act t o r emember is t hat associat ive ar r ays
always ar e st or ed in "r andom" or der . (Act ual l y, it 's t he
or der t hat ensur es f ast est access, but , ef f ect ivel y, it is
r andom.) This means t hat if you use keys t o access al l of
t he el ement s of an associat ive ar r ay, t her e is no
guar ant ee t hat t he el ement s wil l appear in any given
or der . In par t icul ar , t he el ement s do not al ways appear
in t he or der in which t hey ar e cr eat ed.
To cont r ol t he or der in which t he associat ive ar r ay el ement s appear , use sort t o
sor t t he el ement s r et ur ned by keys.
foreach $capword (sort keys(%wordlist)) {
print ("$capword: $wordlist{$capword}\n");
}
When l ine 10 of List ing 10.2 is modif ied t o incl ude a cal l t o sort, t he associat ive
ar r ay el ement s appear in sor t ed or der .
Creating Associative Arrays
You can cr eat e an associat ive ar r ay wit h a singl e assignment . To do t his, al t er nat e
t he ar r ay subscr ipt s and t heir val ues. For exampl e:
%fruit = ("apples", 17, "bananas", 9, "oranges", "none");
This assignment cr eat es an associat ive ar r ay of t hr ee el ement s:
G An el ement wit h subscr ipt apples, whose val ue is 17
G An el ement wit h subscr ipt bananas, whose val ue is 9
G An el ement wit h subscr ipt oranges, whose val ue is none
Again, it is impor t ant t o r emember t hat t he el ement s of
associat ive ar r ays ar e not guar ant eed t o be in any
par t icul ar or der , even if you cr eat e t he ent ir e ar r ay at
once.
NOTE
Per l ver sion 5 enabl es you t o use eit her => or , t o
separ at e ar r ay subscr ipt s and val ues when you assign a
l ist t o an associat ive ar r ay. For exampl e:
%fruit = ("apples" => 17, "bananas" => 9, "oranges"
=> "none");
This st at ement is ident ical t o t he pr evious one, but is
easier t o under st and; t he use of => makes it easier t o see
which subscr ipt is associat ed wit h which val ue.
As wit h any associat ive ar r ay, you al ways can add mor e el ement s t o t he ar r ay
l at er on. For exampl e:
$fruit{"cherries"} = 5;
This adds a f our t h el ement , cherries, t o t he associat ive ar r ay %fruit, and gives it
t he val ue 5.
Copying Associative Arrays from Array Variables
The l ist of subscr ipt s and val ues assigned t o %fruit in t he pr evious exampl e is an
or dinar y l ist l ike any ot her . This means t hat you can cr eat e an associat ive ar r ay
f r om t he cont ent s of an ar r ay var iabl e. For exampl e:
@fruit = ("apples", 6, "cherries", 8, "oranges", 11);
%fruit = @fruit;
The second st at ement cr eat es an associat ive ar r ay of t hr ee el ement s-apples,
cherries, and oranges-and assigns it t o %fruit.
If you ar e assigning a l ist or t he cont ent s of an ar r ay
var iabl e t o an associat ive ar r ay, make sur e t hat t he l ist
cont ains an even number of el ement s, because each pair
of el ement s cor r esponds t o t he subscr ipt and t he val ue
of an associat ive ar r ay el ement .
Simil ar l y, you can copy one associat ive ar r ay int o anot her . For exampl e:
%fruit1 = ("apples", 6, "cherries", 8, "oranges", 11);
%fruit2 = %fruit1;
You can assign an associat ive ar r ay t o an or dinar y ar r ay var iabl e in t he same way.
For exampl e:
%fruit = ("grapes", 11, "lemons", 27);
@fruit = %fruit;
However , t his might not be as usef ul , because t he or der of t he ar r ay el ement s is
not def ined. Her e, t he ar r ay var iabl e @fruit is assigned eit her t he f our -el ement
l ist
("grapes", 11, "lemons", 27)
or t he l ist
("lemons", 27, "grapes", 11)
depending on how t he associat ive ar r ay is sor t ed.
You can al so assign t o sever al scal ar var iabl es and an associat ive ar r ay at t he
same t ime.
($var1, $var2, %myarray) = @list;
Her e, t he f ir st el ement of @list is assigned t o $var1, t he second t o $var2, and t he
r est t o %myarray.
Final l y, an associat ive ar r ay can be cr eat ed f r om t he r et ur n val ue of a buil t -in
f unct ion or user -def ined subr out ine t hat r et ur ns a l ist . List ing 10.3 is an exampl e
of a simpl e pr ogr am t hat does j ust t hat . It t akes t he r et ur n val ue f r om split,
which is a l ist , and assigns it t o an associat ive ar r ay var iabl e.

List ing 10.3. A pr ogr am t hat uses t he r et ur n val ue f r om a buil t -in
f unct ion t o cr eat e an associat ive ar r ay.
1: #!/usr/local/bin/perl
2:
3: $inputline = <STDIN>;
4: $inputline =~ s/^\s+|\s+\n$//g;
5: %fruit = split(/\s+/, $inputline);
6: print ("Number of bananas: $fruit{\"bananas\"}\n");

$ program10_3
oranges 5 apples 7 bananas 11 cherries 6
Number of bananas: 11
$
This pr ogr am r eads a l ine of input f r om t he st andar d input f il e and
el iminat es t he l eading and t r ail ing whit e space. Line 5 t hen cal l s split, which
br eaks t he l ine int o wor ds. In t his exampl e, split r et ur ns t he f ol l owing l ist :
("oranges", 5, "apples", 7, "bananas", 11, "cherries", 6)
This l ist is t hen assigned t o t he associat ive ar r ay %fruit. This assignment cr eat es
an associat ive ar r ay wit h f our el ement s:
Element Value
oranges
5
apples
7
bananas
11
cherries
6
Line 6 t hen pr int s t he val ue of t he el ement bananas, which is 11.
Adding and Deleting Array Elements
As you' ve seen, you can add an el ement t o an associat ive ar r ay by assigning t o an
el ement not pr eviousl y seen, as f ol l ows:
$fruit{"lime"} = 1;
This st at ement cr eat es a new el ement of %fruit wit h index lime and gives it t he
val ue 1.
To del et e an el ement , use t he buil t -in f unct ion delete. For exampl e, t he f ol l owing
st at ement del et es t he el ement orange f r om t he ar r ay %fruit:
delete($fruit{"orange"});
DO use t he delete f unct ion t o del et e an el ement of an
associat ive ar r ay; it 's t he onl y way t o del et e el ement s.
DON' T use t he buil t -in f unct ions push, pop, shift, or
splice wit h associat ive ar r ays because t he posit ion of
any par t icul ar el ement in t he ar r ay is not guar ant eed.
Listing Array Indexes and Values
As you saw in List ing 10.2, t he keys f unct ion r et r ieves a l ist of t he subscr ipt s used
in an associat ive ar r ay. The f ol l owing is an exampl e:
%fruit = ("apples", 9,
"bananas", 23,
"cherries", 11);
@fruitsubs = keys(%fruits);
Her e, @fruitsubs is assigned t he l ist consist ing of t he el ement s apples, bananas, and
cherries. Not e once again t hat t his l ist is in no par t icul ar or der . To r et r ieve t he
l ist in al phabet ical or der , use sort on t he l ist .
@fruitindexes = sort keys(%fruits));
This pr oduces t he l ist ("apples", "bananas", "cherries").
To r et r ieve a l ist of t he val ues st or ed in an associat ive ar r ay, use t he buil t -in
f unct ion values. The f ol l owing is an exampl e:
%fruit = ("apples", 9,
"bananas", 23,
"cherries", 11);
@fruitvalues = values(%fruits);
Her e, @fruitvalues cont ains t he l ist (9, 23, 11), not necessar il y in t his or der .
Looping Using an Associative Array
As you' ve seen, you can use t he buil t -in f unct ion keys wit h t he foreach st at ement t o
l oop t hr ough an associat ive ar r ay. The f ol l owing is an exampl e:
%records = ("Maris", 61, "Aaron", 755, "Young", 511);
foreach $holder (keys(%records)) {
# stuff goes here
}
The var iabl e $holder is assigned Aaron, Maris, and Young on successive it er at ions of
t he l oop (al t hough not necessar il y in t hat or der ).
This met hod of l ooping is usef ul , but it is inef f icient . To r et r ieve t he val ue
associat ed wit h a subscr ipt , t he pr ogr am must l ook it up in t he ar r ay again, as
f ol l ows:
foreach $holder (keys(%records)) {
$record = %records{$holder};
}
Per l pr ovides a mor e ef f icient way t o wor k wit h associat ive ar r ay subscr ipt s and
t heir val ues, using t he buil t -in f unct ion each, as f ol l ows:
%records = ("Maris", 61, "Aaron", 755, "Young", 511);
while (($holder, $record) = each(%records)) {
# stuff goes here
}
Ever y t ime t he each f unct ion is cal l ed, it r et ur ns a t wo-el ement l ist . The f ir st
el ement of t he l ist is t he subscr ipt f or a par t icul ar el ement of t he associat ive
ar r ay. The second el ement is t he val ue associat ed wit h t hat par t icul ar subscr ipt .
For exampl e, t he f ir st t ime each is cal l ed in t he pr eceding code f r agment , t he pair
of scal ar var iabl es ($holder, $record) is assigned one of t he l ist s ("Maris", 61),
("Aaron", 755), or ("Young", 511). (Because associat ive ar r ays ar e not st or ed in any
par t icul ar or der , any of t hese l ist s coul d be assigned f ir st .) If ("Maris", 61) is
r et ur ned by t he f ir st cal l t o each, Maris is assigned t o $holder and 61 is assigned t o
$record.
When each is cal l ed again, it assigns a dif f er ent l ist t o t he pair of scal ar var iabl es
specif ied. Subsequent cal l s t o each assign f ur t her l ist s, and so on unt il t he
associat ive ar r ay is exhaust ed. When t her e ar e no mor e el ement s l ef t in t he
associat ive ar r ay, each r et ur ns t he empt y l ist .
NOTE
Don't add a new el ement t o an associat ive ar r ay or
del et e an el ement f r om it if you ar e using t he each
st at ement on it . For exampl e, suppose you ar e l ooping
t hr ough t he associat ive ar r ay %records using t he
f ol l owing l oop:
while (($holder, $record) = each(%records)) {
# code goes here
}
Adding a new r ecor d t o %records, such as
$records{"Rose"} = 4256;
or del et ing a r ecor d, as in
delete $records{"Cobb"};
makes t he behavior of each unpr edict abl e. This shoul d be
avoided.
Creating Data Structures Using Associative Arrays
You can use associat ive ar r ays t o simul at e a wide var iet y of dat a st r uct ur es f ound
in high-l evel pr ogr amming l anguages. This sect ion descr ibes how you can
impl ement t he f ol l owing dat a st r uct ur es in Per l using associat ive ar r ays:
G Linked l ist s
G St r uct ur es
G Tr ees
G Dat abases
NOTE
The r emainder of t oday's l esson descr ibes appl icat ions of
associat ive ar r ays but does not int r oduce any new
f eat ur es of Per l . If you ar e not int er est ed in
appl icat ions of associat ive ar r ays, you can skip t o t he
next chapt er wit hout suf f er ing any l oss of gener al
inst r uct ion.
Linked Lists
A linked list is a simpl e dat a st r uct ur e t hat enabl es you t o st or e it ems in a
par t icul ar or der . Each el ement of t he l inked l ist cont ains t wo f iel ds:
G The val ue associat ed wit h t his el ement
G A r ef er ence, or pointer, t o t he next el ement in t he l ist
Al so, a special header variable point s t o t he f ir st el ement in t he l ist .
Pict or ial l y, a l inked l ist can be r epr esent ed as in Figur e 10.1. As you can see, each
el ement of t he l ist point s t o t he next .
Figur e 10.1: A linked list.
In Per l , a l inked l ist can easil y be impl ement ed using an associat ive ar r ay because
t he val ue of one associat ive ar r ay el ement can be t he subscr ipt f or t he next . For
exampl e, t he f ol l owing associat ive ar r ay is act ual l y a l inked l ist of wor ds in
al phabet ical or der :
%words = ("abel", "baker",
"baker", "charlie",
"charlie", "delta",
"delta", "");
$header = "abel";
In t his exampl e, t he scal ar var iabl e $header cont ains t he f ir st wor d in t he l ist .
This wor d, abel, is al so t he subscr ipt of t he f ir st el ement of t he associat ive ar r ay.
The val ue of t he f ir st el ement of t his ar r ay, baker, is t he subscr ipt f or t he second
el ement , and so on, as il l ust r at ed in Figur e 10.2.
Figur e 10.2: A linked list of words in alphabetical order.
The val ue of t he l ast el ement of t he subscr ipt , delta, is t he nul l st r ing. This
indicat es t he end of t he l ist .
Linked l ist s ar e most usef ul in appl icat ions wher e t he amount of dat a t o be
pr ocessed is not known, or gr ows as t he pr ogr am is execut ed. List ing 10.4 is an
exampl e of one such appl icat ion. It uses a l inked l ist t o pr int t he wor ds of a f il e in
al phabet ical or der .

List ing 10.4. A pr ogr am t hat uses an associat ive ar r ay t o buil d a l inked
l ist .
1: #!/usr/local/bin/perl
2:
3: # initialize list to empty
4: $header = "";
5: while ($line = <STDIN>) {
6: # remove leading and trailing spaces
7: $line =~ s/^\s+|\s+$//g;
8: @words = split(/\s+/, $line);
9: foreach $word (@words) {
10: # remove closing punctuation, if any
11: $word =~ s/[.,;:-]$//;
12: # convert all words to lower case
13: $word =~ tr/A-Z/a-z/;
14: &add_word_to_list($word);
15: }
16: }
17: &print_list;
18:
19: sub add_word_to_list {
20: local($word) = @_;
21: local($pointer);
22:
23: # if list is empty, add first item
24: if ($header eq "") {
25: $header = $word;
26: $wordlist{$word} = "";
27: return;
28: }
29: # if word identical to first element in list,
30: # do nothing
31: return if ($header eq $word);
32: # see whether word should be the new
33: # first word in the list
34: if ($header gt $word) {
35: $wordlist{$word} = $header;
36: $header = $word;
37: return;
38: }
39: # find place where word belongs
40: $pointer = $header;
41: while ($wordlist{$pointer} ne "" &&
42: $wordlist{$pointer} lt $word) {
43: $pointer = $wordlist{$pointer};
44: }
45: # if word already seen, do nothing
46: return if ($word eq $wordlist{$pointer});
47: $wordlist{$word} = $wordlist{$pointer};
48: $wordlist{$pointer} = $word;
49: }
50:
51: sub print_list {
52: local ($pointer);
53: print ("Words in this file:\n");
54: $pointer = $header;
55: while ($pointer ne "") {
56: print ("$pointer\n");
57: $pointer = $wordlist{$pointer};
58: }
59: }

$ program10_4
Here are some words.
Here are more words.
Here are still more words.
^D
Words in this file:
are
here
more
some
still
words
$
The l ogic of t his pr ogr am is a l it t l e compl icat ed, but don' t despair . Once
you under st and how t his wor ks, you have al l t he inf or mat ion you need t o buil d any
dat a st r uct ur e you l ike, no mat t er how compl icat ed.
This pr ogr am is divided int o t hr ee par t s, as f ol l ows:
G The main pr ogr am, which r eads input and t r ansf or ms it int o t he desir ed
f or mat
G The subr out ine add_word_to_list, which buil ds t he l inked l ist of sor t ed
wor ds
G The subr out ine print_list, which pr int s t he l ist of wor ds
Lines 3-17 cont ain t he main pr ogr am. Line 4 init ial izes t he l ist of wor ds by set t ing
t he header var iabl e $header t o t he nul l st r ing. The l oop beginning in l ine 5 r eads
one l ine of input at a t ime. Line 7 r emoves l eading and t r ail ing spaces f r om t he
l ine, and l ine 8 spl it s t he l ine int o wor ds.
The inner foreach l oop in l ines 9-15 pr ocesses one wor d of t he input l ine at a t ime. If
t he f inal char act er of a wor d is a punct uat ion char act er , l ine 11 r emoves it ; t his
ensur es t hat , f or exampl e, word. (word wit h a per iod) is consider ed ident ical t o word
(wit hout a per iod). Line 13 conver t s t he wor d t o al l l ower case char act er s, and
l ine 14 passes t he wor d t o t he subr out ine add_word_to_list.
This subr out ine f ir st execut es l ine 24, which checks whet her t he l inked l ist of
wor ds is empt y. If it is, l ine 25 assigns t his wor d t o $header, and l ine 26 cr eat es t he
f ir st el ement of t he l ist , which is st or ed in t he associat ive ar r ay %wordlist. In t his
exampl e, t he f ir st wor d r ead in is here (Here conver t ed t o l ower case), and t he l ist
l ooks l ike Figur e 10.3.
Figur e 10.3: The linked list with one element in it.
At t his point , t he header var iabl e $header cont ains t he val ue here, which is al so
t he subscr ipt f or t he el ement of %wordlist t hat has j ust been cr eat ed. This means
t hat t he pr ogr am can r ef er ence %wordlist by using $header as a subscr ipt , as
f ol l ows:
$wordlist{$header}
Var iabl es such as $header t hat cont ain a r ef er ence t o anot her dat a it em ar e
cal l ed pointers. Her e, $header point s t o t he f ir st el ement of %wordlist.
If t he l ist is not empt y, l ine 31 checks whet her t he f ir st it em of t he l ist is
ident ical t o t he wor d cur r ent l y being checked. To do t his, it compar es t he
cur r ent wor d t o t he cont ent s of $header, which is t he f ir st it em in t he l ist . If t he
t wo ar e ident ical , t her e is no need t o add t he new wor d t o t he l ist , because it is
al r eady t her e; t her ef or e, t he subr out ine r et ur ns wit hout doing anyt hing.
The next st ep is t o check whet her t he new wor d shoul d be t he f ir st wor d in t he
l ist , which is t he case if t he new wor d is al phabet ical l y ahead of t he exist ing f ir st
wor d. Line 34 checks t his.
If t he new wor d is t o go f ir st , t he l ist is adj ust ed as f ol l ows:
1. A new l ist el ement is cr eat ed. The subscr ipt of t his el ement is t he new wor d,
and it s val ue is t he exist ing f ir st wor d.
2. The new wor d is assigned t o t he header var iabl e.
To see how t his adj ust ment wor ks, consider t he sampl e input pr ovided. In t his
exampl e, t he second wor d t o be pr ocessed is are. Because are bel ongs bef or e here,
t he ar r ay el ement $wordlist{"are"} is cr eat ed, and is given t he val ue here. The
header var iabl e $header is assigned t he val ue are. This means t he l ist now l ooks
l ike Figur e 10.4.
Figur e 10.4: The linked list with two elements in it.
The header var iabl e $header now point s t o t he l ist el ement wit h t he subscr ipt are,
which is $wordlist{"are"}. The val ue of $wordlist{"are"} is here, which means t hat
t he pr ogr am can access $wordlist{"here"} f r om $wordlist{"are"}. For exampl e:
$reference = $wordlist{"are"};
print ("$wordlist{$reference}\n");
The val ue here is assigned t o $reference, and print pr int s $wordlist{$reference},
which is $wordlist{"here"}.
Because you can access $wordlist{"here"} f r om $wordlist{"are"}, $wordlist{"are"} is
a point er t o $wordlist{"here"}.
If t he wor d does not bel ong at t he f r ont of t he l ist , l ines 40-44 sear ch f or t he
pl ace in t he l ist wher e t he wor d does bel ong, using a l ocal var iabl e, $pointer.
Lines 41-44 l oop unt il t he val ue st or ed in $wordlist{$pointer} is gr eat er t han or
equal t o $word. For exampl e, Figur e 10.5 il l ust r at es wher e l ine 42 is t r ue when t he
subr out ine pr ocesses more.
Figur e 10.5: The linked list when more is processed.
Not e t hat because t he l ist is in al phabet ical or der , t he val ue st or ed in $pointer is
al ways l ess t han t he val ue st or ed in $word.
If t he wor d being added is gr eat er t han any wor d in t he l ist , t he condit ional
expr ession in l ine 41 event ual l y becomes t r ue. This occur s, f or exampl e, when t he
subr out ine pr ocesses some, as in Figur e 10.6.
Figur e 10.6: The linked list when some is processed.
Once t he l ocat ion of t he new wor d has been det er mined, l ine 46 checks whet her
t he wor d al r eady is in t he l ist . If it is, t her e is no need t o do anyt hing.
If t he wor d does not exist , l ines 47 and 48 add t he wor d t o t he l ist . Fir st , l ine 47
cr eat es a new el ement of %wordlist, which is $wordlist{$word}; it s val ue is t he
val ue of $wordlist{$pointer}. This means t hat $wordlist{$word} and
$wordlist{$pointer} now point t o t he same wor d, as in Figur e 10.7.
Figur e 10.7: The linked list as a new word is being added.
Next , l ine 48 set s t he val ue of $wordlist{$pointer} t o t he val ue st or ed in $word.
This means t hat $wordlist{$pointer} now point s t o t he new el ement ,
$wordlist{$word}, t hat was j ust cr eat ed, as in Figur e 10.8.
Figur e 10.8: The linked list after the new word is added.
Once t he input f il e has been compl et el y pr ocessed, t he subr out ine print_list
pr int s t he l ist , one el ement at a t ime. The l ocal var iabl e $pointer cont ains t he
cur r ent val ue being pr int ed, and $wordlist{$pointer} cont ains t he next val ue t o be
pr int ed.
NOTE
Nor mal l y, you won't want t o use a l inked l ist in a
pr ogr am. It 's easier just t o use sort and keys t o l oop
t hr ough an associat ive ar r ay in al phabet ical or der , as
f ol l ows:
foreach $word (sort keys(%wordlist)) {
# print the sorted list, or whatever
}
However , t he basic idea of a point er , which is int r oduced
her e, is usef ul in ot her dat a st r uct ur es, such as t r ees,
which ar e descr ibed l at er on.
Structures
Many pr ogr amming l anguages enabl e you t o def ine col l ect ions of dat a cal l ed
structures. Like l ist s, st r uct ur es ar e col l ect ions of val ues; each el ement of a
st r uct ur e, however , has it s own name and can be accessed by t hat name.
Per l does not pr ovide a way of def ining st r uct ur es dir ect l y. However , you can
simul at e a st r uct ur e using an associat ive ar r ay. For exampl e, suppose you want t o
simul at e t he f ol l owing var iabl e def init ion wr it t en in t he C pr ogr amming
l anguage:
struct {
int field1;
int field2;
int field3;
} mystructvar;
This C st at ement def ines a var iabl e named mystructvar, which cont ains t hr ee
el ement s, named field1, field2, and field3.
To simul at e t his using an associat ive ar r ay, al l you need t o do is def ine an
associat ive ar r ay wit h t hr ee el ement s, and set t he subscr ipt s f or t hese el ement s
t o field1, field2, and field3. The f ol l owing is an exampl e:
%mystructvar = ("field1", "",
"field2", "",
"field3", "");
Like t he pr eceding C def init ion, t his associat ive ar r ay, named %mystructvar, has
t hr ee el ement s. The subscr ipt s f or t hese el ement s ar e field1, field2, and field3.
The def init ion set s t he init ial val ues f or t hese el ement s t o t he nul l st r ing.
As wit h any associat ive ar r ay, you can r ef er ence or assign t he val ue of an el ement
by specif ying it s subscr ipt , as f ol l ows:
$mystructvar{"field1"} = 17;
To def ine ot her var iabl es t hat use t he same " st r uct ur e," al l you need t o do is
cr eat e ot her ar r ays t hat use t he same subscr ipt names.
Trees
Anot her dat a st r uct ur e t hat is of t en used in pr ogr ams is a tree. A t r ee is simil ar t o
a l inked l ist , except t hat each el ement of a t r ee point s t o mor e t han one ot her
el ement .
The simpl est exampl e of a t r ee is a binary tree. Each el ement of a binar y t r ee, cal l ed
a node, point s t o t wo ot her el ement s, cal l ed t he left child and t he right child. Each of
t hese chil dr en point s t o t wo chil dr en of it s own, and so on, as il l ust r at ed in
Figur e 10.9.
Figur e 10.9: A binary tree.
Not e t hat t he t r ee, l ike a l inked l ist , is a one-way st r uct ur e. Nodes point t o
chil dr en, but chil dr en don' t point t o t heir par ent s.
The f ol l owing t er minol ogy is used when descr ibing t r ees:
G Because each of t he chil dr en of a node is a t r ee of it s own, t he l ef t chil d and
t he r ight chil d ar e of t en cal l ed t he left subtree and t he right subtree of t he
node. (The t er ms left branch and right branch ar e al so used.)
G The " f ir st " node of t he t r ee (t he node t hat is not a chil d of anot her node), is
cal l ed t he root of t he t r ee.
G Nodes t hat have no chil dr en ar e cal l ed leaf nodes.
Ther e ar e sever al ways of impl ement ing a t r ee st r uct ur e using associat ive ar r ays.
To il l ust r at e one way of doing so, suppose t hat you wish t o cr eat e a t r ee whose
r oot has t he val ue alpha and whose chil dr en have t he val ues beta and gamma, as in
Figur e 10.10.
Figur e 10.10: A binary tree with three nodes.
Her e, t he l ef t chil d of alpha is beta, and t he r ight chil d of alpha is gamma.
The pr obl em t o be sol ved is t his: How can a pr ogr am associat e bot h beta and gamma
wit h alpha? If t he associat ive ar r ay t hat is t o r epr esent t he t r ee is named %tree, do
you assign t he val ue of $tree{"alpha"} t o be beta, or gamma, or bot h? How do you
show t hat an el ement point s t o t wo ot her el ement s?
Ther e ar e sever al sol ut ions t o t his pr obl em, but one of t he most el egant is as
f ol l ows: Append t he char act er st r ings left and right, r espect ivel y, t o t he name of
a node in or der t o r et r ieve it s chil dr en. For exampl e, def ine alphaleft t o point t o
beta and alpharight t o point t o gamma. In t his scheme, if beta has chil dr en, betaleft
and betaright point t o t heir l ocat ions; simil ar l y, gammaleft and gammaright point t o
t he l ocat ions of t he chil dr en of gamma, and so on.
List ing 10.5 is an exampl e of a pr ogr am t hat cr eat es a binar y t r ee using t his met hod
and t hen traverses it (accesses ever y node in t he t r ee).

List ing 10.5. A pr ogr am t hat uses an associat ive ar r ay t o r epr esent a
binar y t r ee.
1: #!/usr/local/bin/perl
2:
3: $rootname = "parent";
4: %tree = ("parentleft", "child1",
5: "parentright", "child2",
6: "child1left", "grandchild1",
7: "child1right", "grandchild2",
8: "child2left", "grandchild3",
9: "child2right", "grandchild4");
10: # traverse tree, printing its elements
11: &print_tree($rootname);
12:
13: sub print_tree {
14: local ($nodename) = @_;
15: local ($leftchildname, $rightchildname);
16:
17: $leftchildname = $nodename . "left";
18: $rightchildname = $nodename . "right";
19: if ($tree{$leftchildname} ne "") {
20: &print_tree($tree{$leftchildname});
21: }
22: print ("$nodename\n");
23: if ($tree{$rightchildname} ne "") {
24: &print_tree($tree{$rightchildname});
25: }
26: }

$ program10_5
grandchild1
child1
grandchild2
parent
grandchild3
child2
grandchild4
$
This pr ogr am cr eat es t he t r ee depict ed in Figur e 10.11.
Figur e 10.11: The tree created by Listing 10.5.
The associat ive ar r ay %tree st or es t he t r ee, and t he scal ar var iabl e $rootname
hol ds t he name of t he r oot of t he t r ee. (Not e t hat t he gr andchil d nodes, such as
grandchild1, ar e l eaf nodes. Ther e is no need t o expl icit l y cr eat e grandchild1left,
grandchild1right, and so on because t he val ue of any undef ined associat ive ar r ay
el ement is, by def aul t , t he nul l st r ing.)
Af t er t he t r ee has been cr eat ed, t he pr ogr am cal l s t he subr out ine print_tree t o
t r aver se it and pr int it s val ues. print_tree does t his as f ol l ows:
1. Line 17 appends left t o t he name of t he node being examined t o pr oduce t he
name of t he l ef t chil d, which is st or ed in $leftchildname. For exampl e, if t he
r oot node, parent, is being examined, t he val ue st or ed in $leftchildname is
parentleft.
2. Simil ar l y, l ine 18 appends right t o t he node name and st or es t he r esul t in
$rightchildname.
3. Line 19 checks whet her t he cur r ent node has a l ef t chil d, which is t r ue if
$tree{$leftchildname} is def ined. (For exampl e, parent has a l ef t chil d,
because $tree{"parentleft"} is def ined.) If t he cur r ent node has a l ef t chil d,
l ine 20 r ecur sivel y cal l s print_tree t o pr int t he l ef t subt r ee (t he l ef t chil d
and it s chil dr en).
4. Line 22 pr int s t he name of t he cur r ent node.
5. Line 23 checks whet her t he cur r ent node has a r ight chil d. If it does, l ine 24
r ecur sivel y cal l s print_tree t o pr int t he r ight subt r ee.
Not e t hat print_tree pr int s t he names of t he nodes of t he t r ee in t he f ol l owing
or der : l ef t subt r ee, node, r ight subt r ee. This or der of t r aver sal is cal l ed infix
mode or infix traversal. If you move l ine 22 t o pr ecede l ine 19, t he node is pr int ed
f ir st , f ol l owed by t he l ef t subt r ee and t he r ight subt r ee; t his or der of t r aver sal
is cal l ed prefix mode. If you move l ine 22 t o f ol l ow l ine 25, t he node is pr int ed af t er
t he subt r ees ar e pr int ed; t his is cal l ed postfix mode.
Databases
As you have seen, you can buil d a t r ee using an associat ive ar r ay. To do t his, you
buil d t he associat ive ar r ay subscr ipt s by j oining char act er st r ings t oget her (such
as j oining t he node name and " l ef t " ). You can use t his t echnique of j oining st r ings
t oget her t o use associat ive ar r ays t o buil d ot her dat a st r uct ur es.
For exampl e, suppose you want t o cr eat e a dat abase t hat cont ains t he l if et ime
r ecor ds of basebal l pl ayer s. Each r ecor d is t o consist of t he f ol l owing:
G For non-pit cher s, a r ecor d consist s of games pl ayed (GP), home r uns (HR),
r uns bat t ed in (RBI) and bat t ing aver age (AVG). For exampl e, t he r ecor d on
Lou Gehr ig woul d r ead as f ol l ows:
Gehrig: 2164 GP, 493 HR, 1991 RBI, .340 BA
G For pit cher s, a r ecor d consist s of games pit ched (GP), wins (W), and ear ned
r un aver age (ERA). For exampl e, t he r ecor d on Lef t y Gr ove woul d r ead as
f ol l ows:
Grove: 616 GP, 300 W, 3.05 ERA
To cr eat e a dat abase cont aining pl ayer and pit cher r ecor ds, you need t he
f ol l owing f iel ds:
G A name f iel d, f or t he pl ayer ' s name
G A key indicat ing whet her t he pl ayer was a pit cher
G The f iel ds def ined above
You can use an associat ive ar r ay t o simul at e t his in Per l . To do t his, buil d t he
subscr ipt s f or t he associat ive ar r ay by concat enat ing t he name of t he pl ayer wit h
t he name of t he f iel d being st or ed by t his el ement of t he ar r ay. For exampl e, if
t he associat ive ar r ay is named %playerbase, $playerbase{"GehrigRBI"}, it cont ains
t he car eer RBI t ot al f or Lou Gehr ig.
List ing 10.6 shows how t o buil d a pl ayer dat abase and how t o sequent ial l y pr int
f iel ds f r om each of t he pl ayer r ecor ds.

List ing 10.6. A pr ogr am t hat buil ds and pr int s a dat abase.
1: #!/usr/local/bin/perl
2:
3: @pitcherfields = ("NAME", "KEY", "GP", "W", "ERA");
4: @playerfields = ("NAME", "KEY", "GP", "HR", "RBI", "BA");
5:
6: # Build the player database by reading from standard input.
7: # %playerbase contains the database, @playerlist the list of
8: # players (for later sequential access).
9: $playercount = 0;
10: while ($input = <STDIN>) {
11: $input =~ s/^\s+|\s+$//g;
12: @words = split (/\s+/, $input);
13: $playerlist[$playercount++] = $words[0];
14: if ($words[1] eq "player") {
15: @fields = @playerfields;
16: } else {
17: @fields = @pitcherfields;
18: }
19: for ($count = 1; $count <= @words; $count++) {
20: $playerbase{$words[0].$fields[$count-1]} =
21: $words[$count-1];
22: }
23: }
24:
25: # now, print out pitcher win totals and player home run totals
26: foreach $player (@playerlist) {
27: print ("$player: ");
28: if ($playerbase{$player."KEY"} eq "player") {
29: $value = $playerbase{$player."HR"};
30: print ("$value home runs\n");
31: } else {
32: $value = $playerbase{$player."W"};
33: print ("$value wins\n");
34: }
35: }

$ program10_6
Gehrig player 2164 493 1991 .340
Ruth player 2503 714 2217 .342
Grove pitcher 616 300 3.05
Williams player 2292 521 1839 .344
Koufax pitcher 397 165 2.76
^D
Gehrig: 493 home runs
Ruth: 714 home runs
Grove: 300 wins
Williams: 521 home runs
Koufax: 165 wins
$
This pr ogr am has been designed so t hat it is easy t o add new f iel ds t o t he
dat abase. Wit h t his in mind, l ines 3 and 4 def ine t he f iel ds t hat ar e t o be used when
buil ding t he pl ayer and pit cher r ecor ds.
Lines 9-23 buil d t he dat abase. Fir st , l ine 9 init ial izes $playercount t o 0; t his gl obal
var iabl e keeps t r ack of t he number of pl ayer s in t he dat abase.
Lines 10-12 r ead a l ine f r om t he st andar d input f il e, check whet her t he f il e is
empt y, r emove l eading and t r ail ing whit e space f r om t he l ine, and spl it t he l ine
int o wor ds.
Line 13 adds t he pl ayer name (t he f ir st wor d in t he input l ine) t o t he l ist of pl ayer
names st or ed in @playerlist. The count er $playercount t hen has 1 added t o it ; t his
r ef l ect s t he new t ot al number of pl ayer s st or ed in t he dat abase.
Lines 14-18 det er mine whet her t he new pl ayer is a pit cher or not . If t he pl ayer is a
pit cher , t he names of t he f iel ds t o be st or ed in t his pl ayer r ecor d ar e t o be t aken
f r om @pitcherfields; ot her wise, t he names ar e t o be t aken f r om @playerfields. To
simpl if y pr ocessing l at er on, anot her ar r ay var iabl e, @fields, is used t o st or e t he
l ist of f iel ds act ual l y being used f or t his pl ayer .
Lines 19-22 copy t he f iel ds int o t he associat ive ar r ay, one at a t ime. Each ar r ay
subscr ipt is made up of t wo par t s: t he name of t he pl ayer and t he name of t he f iel d
being st or ed. For exampl e, Sandy Kouf ax' s pit ching wins ar e st or ed in t he ar r ay
el ement KoufaxW. Not e t hat neit her t he pl ayer name nor t he f iel d names appear in
t his l oop; t his means t hat you can add new f iel ds t o t he l ist of f iel ds wit hout
having t o change t his code.
Lines 26-35 now sear ch t he dat abase f or al l t he win and home r un t ot al s j ust r ead
in. Each it er at ion of t he foreach l oop assigns a dif f er ent pl ayer name t o t he l ocal
var iabl e $player. Line 28 examines t he cont ent s of t he ar r ay el ement named
$player."KEY" t o det er mine whet her t he pl ayer is a pit cher .
If t he pl ayer is not a pit cher , l ines 29-30 pr int out t he pl ayer ' s home-r un t ot al by
accessing t he ar r ay el ement $player."HR". If t he pl ayer is a pit cher , t he pit cher ' s
win t ot al is pr int ed out by l ines 32-33; t hese l ines access t he ar r ay el ement
$player."W".
Not e t hat t he dat abase can be accessed r andoml y as wel l as sequent ial l y. To
r et r ieve, f or exampl e, Babe Rut h' s l if et ime bat t ing aver age, you woul d access t he
ar r ay el ement $playerbase{"RuthAVG"}. If t he r ecor d f or a par t icul ar pl ayer is not
st or ed in t he dat abase, at t empt ing t o access it wil l r et ur n t he nul l st r ing. For
exampl e, t he f ol l owing assigns t he nul l st r ing t o $cobbavg because Ty Cobb is not
in t he pl ayer dat abase:
$cobbavg = $playerbase{"CobbAVG"};
As you can see, associat ive ar r ays enabl e you t o def ine dat abases wit h var iabl e
r ecor d l engt hs, accessibl e eit her sequent ial l y or r andoml y. This gives you al l t he
f l exibil it y you need t o use Per l as a dat abase l anguage.
Example: A Calculator Program
List ing 10.7 pr ovides an exampl e of what you can do wit h associat ive ar r ays and
r ecur sive subr out ines. This pr ogr am r eads in an ar it hmet ic expr ession, possibl y
spr ead over sever al l ines, and buil ds a t r ee f r om it . The pr ogr am t hen eval uat es
t he t r ee and pr int s t he r esul t . The oper at or s suppor t ed ar e +, -, *, /, and
par ent heses (t o f or ce pr ecedence).
This pr ogr am is l onger and mor e compl icat ed t han t he pr ogr ams you have seen so
f ar , but st ick wit h it . Once you under st and t his pr ogr am, you wil l know enough t o
be abl e t o wr it e an ent ir e compil er in Per l !

List ing 10.7. A cal cul at or pr ogr am t hat uses t r ees.
1: #!/usr/local/bin/perl
2: # statements which initialize the program
3: $nextnodenum = 1; # initialize node name generator
4: &get_next_item; # read first value from file
5: $treeroot = &build_expr;
6: $result = &get_result ($treeroot);
7: print ("the result is $result\n");
8: # Build an expression.
9: sub build_expr {
10: local ($currnode, $leftchild, $rightchild);
11: local ($operator);
12: $leftchild = &build_add_operand;
13: if (&is_next_item("+") || &is_next_item("-")) {
14: $operator = &get_next_item;
15: $rightchild = &build_expr;
16: $currnode = &get_new_node ($operator,
17: $leftchild, $rightchild);
18: } else {
19: $currnode = $leftchild;
20: }
21: }
22: # Build an operand for a + or - operator.
23: sub build_add_operand {
24: local ($currnode, $leftchild, $rightchild);
25: local ($operator);
26: $leftchild = &build_mult_operand;
27: if (&is_next_item("*") || &is_next_item("/")) {
28: $operator = &get_next_item;
29: $rightchild = &build_add_operand;
30: $currnode = &get_new_node ($operator,
31: $leftchild, $rightchild);
32: } else {
33: $currnode = $leftchild;
34: }
35: }
36: # Build an operand for the * or / operator.
37: sub build_mult_operand {
38: local ($currnode);
39: if (&is_next_item("(")) {
40: # handle parentheses
41: &get_next_item; # get rid of "("
42: $currnode = &build_expr;
43: if (! &is_next_item(")")) {
44: die ("Invalid expression");
45: }
46: &get_next_item; # get rid of ")"
47: } else {
48: $currnode = &get_new_node(&get_next_item,
49: "", "");
50: }
51: $currnode; # ensure correct return value
52: }
53: # Check whether the last item read matches
54: # a particular operator.
55: sub is_next_item {
56: local ($expected) = @_;
57: $curritem eq $expected;
58: }
59: # Return the last item read; read another item.
60: sub get_next_item {
61: local ($retitem);
62: $retitem = $curritem;
63: $curritem = &read_item;
64: $retitem;
65: }
66: # This routine actually handles reading from the standard
67: # input file.
68: sub read_item {
69: local ($line);
70: if ($curritem eq "EOF") {
71: # we are already at end of file; do nothing
72: return;
73: }
74: while ($wordsread == @words) {
75: $line = <STDIN>;
76: if ($line eq "") {
77: $curritem = "EOF";
78: return;
79: }
80: $line =~ s/\(/ ( /g;
81: $line =~ s/\)/ ) /g;
82: $line =~ s/^\s+|\s+$//g;
83: @words = split(/\s+/, $line);
84: $wordsread = 0;
85: }
86: $curritem = $words[$wordsread++];
87: }
88: # Create a tree node.
89: sub get_new_node {
90: local ($value, $leftchild, $rightchild) = @_;
91: local ($nodenum);
92: $nodenum = $nextnodenum++;
93: $tree{$nodenum} = $value;
94: $tree{$nodenum . "left"} = $leftchild;
95: $tree{$nodenum . "right"} = $rightchild;
96: $nodenum; # return value
97: }
98: # Calculate the result.
99: sub get_result {
100: local ($node) = @_;
101: local ($nodevalue, $result);
102: $nodevalue = $tree{$node};
103: if ($nodevalue eq "") {
104: die ("Bad tree");
105: } elsif ($nodevalue eq "+") {
106: $result = &get_result($tree{$node . "left"}) +
107: &get_result($tree{$node . "right"});
108: } elsif ($nodevalue eq "-") {
109: $result = &get_result($tree{$node . "left"}) -
110: &get_result($tree{$node . "right"});
111: } elsif ($nodevalue eq "*") {
112: $result = &get_result($tree{$node . "left"}) *
113: &get_result($tree{$node . "right"});
114: } elsif ($nodevalue eq "/") {
115: $result = &get_result($tree{$node . "left"}) /
116: &get_result($tree{$node . "right"});
117: } elsif ($nodevalue =~ /^[0-9]+$/) {
118: $result = $nodevalue;
119: } else {
120: die ("Bad tree");
121: }
122:}

$ program10_7
11 + 5 *
(4 - 3)
^D
the result is 16
$
This pr ogr am is divided int o t wo main par t s: a par t t hat r eads t he input
and pr oduces a t r ee, and a par t t hat cal cul at es t he r esul t by t r aver sing t he t r ee.
The subr out ines build_expr, build_add_operand, and build_mult_operand buil d t he
t r ee. To see how t hey do t his, f ir st l ook at Figur e 10.12 t o see what t he t r ee f or
t he exampl e, 11 + 5 * (4 - 3), shoul d l ook l ike.
Figur e 10.12: The tree for the example in Listing 10.7.
When t his t r ee is eval uat ed, t he nodes ar e sear ched in post f ix or der . Fir st , t he
l ef t subt r ee of t he r oot is eval uat ed, t hen t he r ight subt r ee, and f inal l y t he
oper at ion at t he r oot .
The r ul es f ol l owed by t he t hr ee subr out ines ar e spel l ed out in t he f ol l owing
descr ipt ion:
1. An expression consist s of one of t he f ol l owing:
1. An add_operand
2. An add_operand, a + or - oper at or , and an expression
2. An add_operand consist s of one of t he f ol l owing:
1. A mult_operand
2. A mult_operand, a * or / oper at or , and an add_operand
3. A mult_operand consist s of one of t he f ol l owing:
1. A number (a gr oup of digit s)
2. An expression encl osed in par ent heses
The subr out ine build_expr handl es al l occur r ences of condit ion 1; it is cal l ed
(possibl y r ecur sivel y) whenever an expression is pr ocessed. Condit ion 1a cover s t he
case in which t he expr ession cont ains no + or - oper at or s (unl ess t hey ar e encl osed
in par ent heses). Condit ion 1b handl es expr essions t hat cont ain one or mor e + or -
oper at or s.
The subr out ine build_add_operand handl es condit ion 2; it is cal l ed whenever an
add_operand is pr ocessed. Condit ion 2a cover s t he case in which t he add oper and
cont ains no * or / oper at or s (except possibl y in par ent heses). Condit ion 2b handl es
add oper ands t hat cont ain one or mor e * or / oper at or s.
The subr out ine build_mult_operand handl es condit ion 3 and is cal l ed whenever a
mult_operand is pr ocessed. Condit ion 3a handl es mul t ipl icat ion oper ands t hat
consist of a number . Condit ion 3b handl es mul t ipl icat ion oper at or s t hat consist of
an expr ession in par ent heses; t o obt ain t he subt r ee f or t his expr ession,
build_mult_operand cal l s build_expr r ecur sivel y and t hen t r eat s t he r et ur ned
subt r ee as a chil d of t he node cur r ent l y being buil t .
Not e t hat t he t r ee buil t by build_expr, build_mult_operand, and build_add_operand is
sl ight l y dif f er ent f r om t he t r ee you saw in List ing 10.5. In t hat t r ee, t he val ue of
t he node coul d al so be used as t he subscr ipt int o t he associat ive ar r ay. In t his
t r ee, t he val ue of t he node might not be unique. To get ar ound t his pr obl em, a
separ at e count er cr eat es number s f or each node, which ar e used when buil ding t he
subscr ipt s. For each node number ed n (wher e n is an int eger ), t he f ol l owing ar e
t r ue:
G $tree{n} cont ains t he val ue of t he node, which is t he number or oper at or
associat ed wit h t he node.
G $tree{n."left"} cont ains t he number of t he l ef t chil d of t he node.
G $tree{n."right"} cont ains t he number of t he r ight chil d of t he node.
The subr out ines is_next_item, get_next_item, and read_item r ead t he input f r om t he
st andar d input f il e and br eak it int o number s and oper at or s. The subr out ine
get_next_item " pr e-r eads" t he next it em and st or es it in t he gl obal var iabl e
$curritem; t his l et s is_next_item check whet her t he next it em t o be r ead mat ches a
par t icul ar oper at or . To r ead an it em, get_next_item cal l s read_item, which r eads
l ines of input , br eaks t hem int o wor ds, and r et ur ns t he next wor d t o be r ead.
The subr out ine get_new_node cr eat es a t r ee node. To do t his, it uses t he cont ent s of
t he gl obal var iabl e $nextnodenum t o buil d t he associat ive ar r ay subscr ipt s
associat ed wit h t he node. $nextnodenum al ways cont ains a posit ive int eger n, which
means t hat t he val ue associat ed wit h t his node (which is a number or oper at or ) is
st or ed in $tree{n}. The l ocat ion of t he l ef t and r ight chil dr en, if any, ar e st or ed
in $tree{n."left"} and $tree {n."right"}.
The subr out ine get_result t r aver ses t he t r ee buil t by build_expr in post f ix or der
(subt r ees f ir st ), per f or ming t he ar it hmet ic oper at ions as it does so. get_result
r et ur ns t he f inal r esul t , which is t hen pr int ed.
Not e t hat t he main par t of t his pr ogr am is onl y eight l ines l ong! This of t en
happens in mor e compl ex pr ogr ams. The main par t of t he pr ogr am j ust cal l s
subr out ines, and t he subr out ines do t he act ual wor k.
NOTE
This pr ogr am is just t he t ip of t he iceber g: you can use
associat ive ar r ays t o simul at e any dat a st r uct ur e in any
pr ogr amming l anguage.
Summary
In t oday' s l esson, you l ear ned about associat ive ar r ays, which ar e ar r ays whose
subscr ipt s can be any scal ar val ue.
You can copy a l ist t o an associat ive ar r ay, pr ovided t her e is an even number of
el ement s in t he l ist . Each pair of el ement s in t he l ist is t r eat ed as an associat ed
ar r ay subscr ipt and it s val ue. You al so can copy an associat ive ar r ay t o an
or dinar y ar r ay var iabl e.
To add an el ement t o an associat ive ar r ay, j ust assign a val ue t o an el ement whose
subscr ipt has not been pr eviousl y seen. To del et e an el ement , cal l t he buil t -in
f unct ion delete.
The f ol l owing t hr ee buil t -in f unct ions enabl e you t o use associat ive ar r ays wit h
foreach l oops:
G The buil t -in f unct ion keys r et r ieves each associat ive ar r ay subscr ipt in t ur n.
G The buil t -in f unct ion values r et r ieves each associat ive ar r ay val ue in t ur n.
G The buil t -in f unct ion each r et r ieves each subscr ipt -val ue pair in t ur n (as a
t wo-el ement l ist ).
Associat ive ar r ays ar e not guar ant eed t o be st or ed in any par t icul ar or der . To
guar ant ee a par t icul ar or der , use sort wit h keys, values, or each.
Associat ive ar r ays can be used t o simul at e a wide var iet y of dat a st r uct ur es,
incl uding l inked l ist s, st r uct ur es, t r ees, and dat abases.
Q&A
Q: Ar e point er s impl ement ed in Per l ?
A: Yes, if you ar e using Per l 5; t hey ar e discussed on Day 18, "Ref er ences in Per l 5."
Per l 4 does not suppor t point er s.
Q: How can I impl ement mor e compl icat ed dat a st r uct ur es using associat ive
ar r ays?
A: Al l you need t o do is design t he st r uct ur e you want t o impl ement , name each of
t he f iel ds in t he st r uct ur e, and use t he name-concat enat ion t r ick t o buil d your
associat ive ar r ay subscr ipt names.
Q: What do I do if I want t o buil d a t r ee t hat has mul t ipl e val ues at each
node?
A: Ther e ar e many ways t o do t his. One way is t o append value1, value2, and so on, t o
t he name of each node; f or exampl e, if t he node is named n7, n7value1 coul d be
t he associat ive ar r ay subscr ipt f or t he f ir st val ue associat ed wit h t he node,
n7value2 coul d be t he subscr ipt f or t he second, and so on.
Q: What do I do if I want t o buil d a t r ee t hat has mor e t han t wo chil dr en per
node?
A: Again, t her e ar e many ways t o do t his. A possibl e sol ut ion is t o use child1,
child2, child3, and so on, inst ead of left and right.
Q: How do I dest r oy a t r ee t hat I have cr eat ed?
A: To dest r oy a t r ee, wr it e a subr out ine t hat t r aver ses t he t r ee in post f ix or der
(subt r ees f ir st ). Dest r oy each subt r ee (by r ecur sivel y cal l ing your subr out ine),
and t hen dest r oy t he node you ar e l ooking at by cal l ing delete.
Not e t hat you shoul dn't use keys or each t o access each el ement of t he l oop
bef or e del et ing it . Del et ing an el ement af f ect s how t he associat ive ar r ay is
st or ed, which means t hat keys and each might not behave t he way you want t hem
t o.
If you want t o dest r oy t he ent ir e associat ive ar r ay in which t he t r ee is st or ed,
you can use t he undef f unct ion, which is descr ibed on Day 14, "Scal ar -Conver sion
and List -Manipul at ion Funct ions."
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of
t he mat er ial cover ed and exer cises t o give you exper ience in using what you' ve
l ear ned. Tr y and under st and t he quiz and exer cise answer s bef or e you go on t o
t omor r ow' s l esson.
Quiz
1. Def ine t he f ol l owing t er ms:
1. associat ive ar r ay
2. point er
3. l inked l ist
4. binar y t r ee
5. node
6. chil d
2. What ar e t he el ement s of t he associat ive ar r ay cr eat ed by t he f ol l owing
assignment ?
%list = ("17.2", "hello", "there", "46", "e+6", "88");
3. What happens when you assign an associat ive ar r ay t o an or dinar y ar r ay
var iabl e?
4. How can you cr eat e a l inked l ist using an associat ive ar r ay?
5. How many t imes does t he f ol l owing l oop it er at e?
%list = ("first", "1", "second", "2", "third", "3");
foreach $word (keys(%list)) {
last if ($word == "second");
}
Exercises
1. Wr it e a pr ogr am t hat r eads l ines of input consist ing of t wo wor ds per l ine,
such as
bananas 16
and cr eat es an associat ive ar r ay f r om t hese l ines. (The f ir st wor d is t o be
t he subscr ipt and t he second wor d t he val ue.)
2. Wr it e a pr ogr am t hat r eads a f il e and sear ches f or l ines of t he f or m
index word
wher e word is a wor d t o be indexed. Each indexed wor d is t o be st or ed in an
associat ive ar r ay, al ong wit h t he l ine number on which it f ir st occur s.
(Subsequent occur r ences can be ignor ed.) Pr int t he r esul t ing index.
3. Modif y t he pr ogr am cr eat ed in Exer cise 2 t o st or e ever y occur r ence of each
index l ine. (Hint : Tr y buil ding t he associat ive ar r ay subscr ipt s using t he
indexed wor d, a non-pr int abl e char act er , and a number .) Pr int t he r esul t ing
index.
4. Wr it e a pr ogr am t hat r eads input l ines consist ing of a st udent name and f ive
number s r epr esent ing t he st udent ' s mar ks in Engl ish, hist or y, mat hemat ics,
science, and geogr aphy, as f ol l ows:
Jones 61 67 75 80 72
Use an associat ive ar r ay t o st or e t hese number s in a dat abase, and t hen pr int
out t he names of al l st udent s wit h f ail ing gr ades (l ess t han 50) al ong wit h
t he subj ect s t hey f ail ed.
5. BUG BUSTER: What is wr ong wit h t he f ol l owing code?
%list = ("Fred", 61, "John", 72,
"Jack", 59, "Mary", 80);
$surname = "Smith";
foreach $firstname (keys (%list)) {
%list{$firstname." ".$surname} = %list{$firstname};
}

Chapter 11
Formatting Your Output
CONTENTS
G Def ining a Pr int For mat
G Displ aying a Pr int For mat
G Displ aying Val ues in a Pr int For mat
H Cr eat ing a Gener al -Pur pose Pr int For mat
H Choosing a Val ue-Fiel d For mat
H Pr int ing Val ue-Fiel d Char act er s
H Using t he Mul t il ine Fiel d For mat
G Wr it ing t o Ot her Out put Fil es
H Saving t he Def aul t Fil e Var iabl e
G Specif ying a Page Header
H Changing t he Header Pr int For mat
G Set t ing t he Page Lengt h
H Using print wit h Paginat ion
G For mat t ing Long Char act er St r ings
H El iminat ing Bl ank Lines When For mat t ing
H Suppl ying an Indef init e Number of Lines
G For mat t ing Out put Using printf
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
The Per l pr ogr ams you've seen so f ar pr oduce out put using t he print f unct ion, which
wr it es r aw, unf or mat t ed t ext t o a f il e.
Per l al so enabl es you t o pr oduce f or mat t ed out put , using pr int f or mat s and t he buil t -in
f unct ion write. Today's l esson descr ibes how t o pr oduce f or mat t ed out put . You'l l l ear n
t he f ol l owing:
G How t o def ine a pr int f or mat (al so somet imes known as a "pict ur e f or mat ")
G How t o use t he write f unct ion
G How t o add f or mat t ed val ues t o a pr int f or mat
G Which val ue-f iel d f or mat s ar e avail abl e
G How t o wr it e t o ot her out put f il es
G How t o specif y page header s and t he page l engt h
G How t o f or mat l ong char act er st r ings
G How t o use t he buil t -in f unct ion printf
Defining a Print Format
The f ol l owing is an exampl e of a simpl e pr int f or mat :
format MYFORMAT =
===================================
Here is the text I want to display.
===================================
.
This def ines t he pr int f or mat MYFORMAT.
The synt ax f or pr int f or mat s is
format formatname =
lines_of_output
.
The special keywor d f or mat t el l s t he Per l int er pr et er t hat t he f ol l owing l ines ar e a
pr int -f or mat def init ion. The formatname is a pl acehol der f or t he name of t he pr int
f or mat being def ined (f or exampl e, MYFORMAT). This name must st ar t wit h an al phabet ic
char act er and can consist of any sequence of l et t er s, digit s, or under scor es.
The lines_of_output consist s of one or mor e l ines of t ext t hat ar e t o be pr int ed when
t he pr int f or mat is ut il ized; t hese l ines ar e somet imes cal l ed picture lines. In t he MYFORMAT
exampl e, t her e ar e t hr ee l ines of t ext pr int ed: t wo l ines cont aining = char act er s, and
t he l ine
Here is the text I want to display.
A pr int -f or mat def init ion is t er minat ed wit h a l ine cont aining a per iod char act er . This
l ine can cont ain not hing el se; t her e can be no whit e space, and t he per iod must be t he
f ir st char act er on t he l ine.
Like subr out ines, pr int -f or mat def init ions can appear anywher e in pr ogr am code (even,
f or exampl e, in t he middl e of a condit ional st at ement ). However , it usual l y is best t o
cl ust er t hem eit her at t he beginning or t he end of t he pr ogr am.
Displaying a Print Format
To displ ay out put using a pr int f or mat , you need t o do t wo t hings:
G Set t he syst em var iabl e $~ t o t he f or mat you want t o use
G Cal l t he buil t -in f unct ion write
List ing 11.1 is an exampl e of a simpl e pr ogr am t hat displ ays out put using a pr int f or mat .

List ing 11.1. A pr ogr am t hat uses a pr int f or mat .
1: #!/usr/local/bin/perl
2:
3: $~ = "MYFORMAT";
4: write;
5:
6: format MYFORMAT =
7: ===================================
8: Here is the text I want to display.
9: ===================================
10: .

$ program11_1
===================================
Here is the text I want to display.
===================================
$
Line 3 of t his pr ogr am assigns t he char act er st r ing MYFORMAT t o t he syst em
var iabl e $~. This t el l s t he Per l int er pr et er t hat MYFORMAT is t he pr int f or mat t o use
when cal l ing write.
Line 4 cal l s write, which sends t he t ext def ined in MYFORMAT t o t he st andar d out put f il e.
Lines 6-10 cont ain t he def init ion of t he pr int f or mat MYFORMAT.
NOTE
If you don't specif y a pr int f or mat by assigning t o $~, t he
Per l int er pr et er assumes t hat t he pr int f or mat t o use has
t he same name as t he f il e var iabl e being wr it t en t o. In
t his exampl e pr ogr am, if l ine 3 had not specif ied MYFORMAT
as t he pr int f or mat t o use, t he Per l int er pr et er woul d
have t r ied t o use a pr int f or mat named STDOUT when
execut ing t he cal l t o write in l ine 4, because t he cal l t o
write is wr it ing t o t he st andar d out put f il e
Displaying Values in a Print Format
Of cour se, t he main r eason t o use pr int f or mat s is t o f or mat val ues st or ed in scal ar
var iabl es or ar r ay var iabl es t o pr oduce r eadabl e out put . Per l enabl es you t o do t his by
specif ying value fields as par t of a f or mat def init ion.
Each val ue f iel d specif ies a val ue: t he name of a scal ar var iabl e, f or exampl e, or an
expr ession. When t he write st at ement is invoked, t he val ue is displ ayed in t he f or mat
specif ied by t he val ue f iel d.
List ing 11.2 shows how val ue f iel ds wor k. This pr ogr am keeps t r ack of t he number of
occur r ences of t he l et t er s a, e, i, o, and u in a t ext f il e.

List ing 11.2. A pr ogr am t hat uses val ue f iel ds t o pr int out put .
1: #!/usr/local/bin/perl
2:
3: while ($line = <STDIN>) {
4: $line =~ s/[^aeiou]//g;
5: @vowels = split(//, $line);
6: foreach $vowel (@vowels) {
7: $vowelcount{$vowel} += 1;
8: }
9: }
10: $~ = "VOWELFORMAT";
11: write;
12:
13: format VOWELFORMAT =
14: ==========================================================
15: Number of vowels found in text file:
16: a: @<<<<< e: @<<<<<
17: $vowelcount{"a"}, $vowelcount{"e"}
18: i: @<<<<< o: @<<<<<
19: $vowelcount{"i"}, $vowelcount{"o"}
20: u: @<<<<<
21: $vowelcount{"u"}
22: ==========================================================
23: .

$ program11_2
This is a test file.
This test file contains some vowels.
The quick brown fox jumped over the lazy dog.
^D
==========================================================
Number of vowels found in text file:
a: 3 e: 10
i: 7 o: 7
u: 2
==========================================================
$
This pr ogr am r eads one l ine of input at a t ime. Line 4 r emoves ever yt hing t hat
is not a, e, i, o, or u f r om t he input l ine, and l ine 5 spl it s t he r emaining char act er s int o
t he ar r ay @vowels. Each el ement of @vowels is one char act er of t he input l ine.
Lines 6-8 count t he vowel s in t he input l ine by examining t he el ement s of @vowels and
adding t o t he associat ive ar r ay %vowelcount.
Line 10 set s t he cur r ent pr int f or mat t o VOWELFORMAT; l ine 11 pr int s using VOWELFORMAT.
The pr int f or mat VOWELFORMAT is def ined in l ines 13-23. Line 16 is an exampl e of a pr int
f or mat l ine t hat cont ains val ue f iel ds; in t his case, t wo val ue f iel ds ar e def ined. Each
val ue f iel d has t he f or mat @<<<<<, which indicat es six l ef t -just if ied char act er s. (For a
compl et e descr ipt ion of t he possibl e val ue f iel ds, see t he sect ion cal l ed "Choosing a
Val ue-Fiel d For mat ," l at er t oday.)
When one or mor e val ue f iel ds appear in a pr int -f or mat l ine, t he next l ine must def ine
t he val ue or val ues t o be pr int ed in t his val ue f iel d. Because l ine 16 def ines t wo val ue
f iel ds, l ine 17 def ines t he t wo val ues t o be pr int ed. These val ues ar e $vowelcount{"a"}
and $vowelcount{"e"}, which ar e t he number of occur r ences of a and e, r espect ivel y.
Simil ar l y, l ine 18 def ines t wo mor e val ue f iel ds t o be pr int ed, and l ine 19 indicat es t hat
t he val ues t o be pr int ed in t hese f iel ds ar e $vowelcount{"i"} and $vowelcount{"o"}.
Final l y, l ine 20 def ines a f if t h val ue f iel d, and l ine 21 specif ies t hat $vowelcount{"u"} is
t o be pr int ed in t his f iel d.
NOTE
Thr ee t hings t o not e about t he val ues t hat ar e specif ied
f or val ue-f iel d f or mat s:
G The l ines cont aining val ues t o be pr int ed ar e not t hemsel ves
pr int ed. For exampl e, in List ing 11.2, l ines 16, 18, and 20 ar e
pr int ed, but l ines 17, 19, and 21 ar e not .
G The Per l int er pr et er ignor es spacing when it l ooks f or val ues
cor r esponding t o val ue f iel ds. Many peopl e pr ef er t o l ine up
t heir val ues wit h t he cor r esponding val ue f iel ds on t he
pr evious l ine, but t her e is no need t o do so.
G The number of val ues specif ied must mat ch t he number of val ue
f iel ds def ined on t he pr evious l ine
Creating a General-Purpose Print Format
One disadvant age of pr int f or mat s as def ined in Per l is t hat scal ar -var iabl e names ar e
incl uded as par t of t he def init ion. For exampl e, in t he f ol l owing def init ion, t he scal ar
var iabl e $winnum is buil t int o t he pr int f or mat def init ion MYFORMAT:
format MYFORMAT =
==========================================================
The winning number is @<<<<<<!
$winnum
==========================================================
.
When write is cal l ed wit h t his pr int f or mat , as in t he f ol l owing, you have t o r emember
t hat $winnum is being used by MYFORMAT.
$~ = "MYFORMAT";
write;
If , l at er on, you accident al l y del et e al l r ef er ences t o $winnum in t he pr ogr am, t he cal l
t o write wil l st op wor king pr oper l y.
One way t o get ar ound t his pr obl em is t o cal l write f r om wit hin a subr out ine, and t o use
var iabl es l ocal t o t he subr out ine in t he pr int f or mat t hat write uses. List ing 11.3 is a
pr ogr am t hat does t his. It r eads a f il e f r om t he st andar d input f il e and pr int s out t he
number of occur r ences of t he f ive most f r equent l y occur r ing l et t er s.

List ing 11.3. A pr ogr am t hat cal l s write f r om wit hin a subr out ine.
1: #!/usr/local/bin/perl
2:
3: while ($line = <STDIN>) {
4: $line =~ tr/A-Z/a-z/;
5: $line =~ s/[^a-z]//g;
6: @letters = split(//, $line);
7: foreach $letter (@letters) {
8: $lettercount{$letter} += 1;
9: }
10: }
11:
12: $~ = "WRITEHEADER";
13: write;
14: $count = 0;
15: foreach $letter (reverse sort occurrences
16: (keys(%lettercount))) {
17: &write_letter($letter, $lettercount{$letter});
18: last if (++$count == 5);
19: }
20:
21: sub occurrences {
22: $lettercount{$a} <=> $lettercount{$b};
23: }
24: sub write_letter {
25: local($letter, $value) = @_;
26:
27: $~ = "WRITELETTER";
28: write;
29: }
30: format WRITEHEADER =
31: The five most frequently occurring letters are:
32: .
33: format WRITELETTER =
34: @: @<<<<<<
35: $letter, $value
36: .

$ program11_3
This is a test file.
This test file contains some input.
The quick brown fox jumped over the lazy dog.
^D
The five most frequently occurring letters are:
t: 10
e: 9
i: 8
s: 7
o: 6
$
Like t he vowel -count ing pr ogr am in List ing 11.2, t his pr ogr am pr ocesses one
l ine of input at a t ime. Line 4 t r ansl at es al l upper case al phabet ic char act er s int o
l ower case, so t hat t hey can be incl uded in t he l et t er count . Line 5 get s r id of al l
char act er s t hat ar e not l et t er s, incl uding any whit e space.
Line 6 spl it s t he l ine int o it s individual l et t er s; l ines 7-9 examine each l et t er and
incr ement t he appr opr iat e l et t er count er s, which ar e st or ed in t he associat ive ar r ay
%lettercount.
Lines 12 and 13 pr int t he f ol l owing l ine by set t ing t he cur r ent pr int f or mat t o
WRITEHEADER and cal l ing write:
The five most frequently occurring letters are:
Except in ver y special cases, never mix cal l s t o write
wit h cal l s t o print. Your pr ogr am shoul d use one
pr int ing f unct ion or t he ot her , not bot h
Lines 15-19 sor t t he ar r ay %lettercount in or der of occur r ence. The f ir st l et t er t o
appear in t he foreach l oop is t he l et t er t hat appear s most of t en in t he f il e. To sor t t he
ar r ay in or der of occur r ence, l ines 15 and 16 specif y t hat sor t ing is t o be per f or med
accor ding t o t he r ul es def ined in t he subr out ine occurrences. This subr out ine t el l s t he
Per l int er pr et er t o use t he val ues of t he associat ive ar r ay el ement s as t he sor t
cr it er ion.
Line 17 passes t he l et t er and it s occur r ence count t o t he subr out ine write_letter. This
subr out ine set s t he cur r ent pr int f or mat t o WRITELETTER; t his pr int f or mat r ef er s t o t he
l ocal scal ar var iabl es $letter and $value, which cont ain t he val ues passed t o
write_letter by l ine 17. This means t hat each cal l t o write_letter pr int s t he l et t er and
val ue cur r ent l y being examined by t he foreach l oop.
Not e t hat t he f ir st val ue f iel d in t he pr int f or mat WRITELETTER cont ains onl y a singl e
char act er , @. This indicat es t hat t he wr it e f iel d is onl y one char act er l ong (which makes
sense, because t his is a singl e l et t er ).
Line 18 ensur es t hat t he foreach l oop quit s af t er t he f ive most f r equent l y used l et t er s
have been examined and pr int ed.
TIP
Some pr ogr ams, such as t he one in List ing 11.3, use mor e
t han one pr int -f or mat def init ion. To make it easier t o see
which pr int f or mat is being used by a par t icul ar cal l t o
write, al ways keep t he pr int f or mat specif icat ion
st at ement and t he write cal l t oget her . For exampl e:
$~ = "WRITEFORMAT";
write;
Her e, it is obvious t hat t he cal l t o write is using t he
pr int f or mat WRITEFORMAT
Formats and Local Variables
In List ing 11.3, you might have not iced t hat t he subr out ine write_letter cal l s a
subr out ine t o wr it e out a l et t er and it s val ue:
sub write_letter {
local($letter, $value) = @_;
$~ = "WRITELETTER";
write;
}
This subr out ine wor ks pr oper l y even t hough t he WRITELETTER pr int f or mat is def ined
out side t he subr out ine.
Not e, however , t hat l ocal var iabl es def ined using my cannot be wr it t en out using a pr int
f or mat unl ess t he f or mat is def ined inside t he subr out ine. (To see t his f or your sel f ,
change l ine 25 of List ing 11.3 t o t he f ol l owing and r un t he pr ogr am again:
my($letter,$value) = @_;
You wil l not ice t hat t he l et t er count s do not appear .) This l imit at ion is a r esul t of t he
way l ocal var iabl es def ined using my ar e st or ed by t he Per l int er pr et er . To avoid t his
dif f icul t y, use local inst ead of my when you def ine l ocal var iabl es t hat ar e t o be
wr it t en out using write. (For a discussion of local and my, see Day 9, "Using
Subr out ines.")
Per l 4 user s wil l not r un int o t his pr obl em, because my is not def ined f or t hat ver sion of
t he l anguage.
NOTE
In ver sions of Per l 5 ear l ier t han ver sion 5.001, l ocal
var iabl es def ined using my cannot be wr it t en out at al l .
Even in ver sion 5.001, var iabl es def ined using my might
not behave in t he way you expect t hem t o. As a
consequence, it is best t o avoid using my wit h pr int
f or mat s
Choosing a Value-Field Format
Now t hat you know how pr int f or mat s and write wor k, it 's t ime t o l ook at t he val ue-
f iel d f or mat s t hat ar e avail abl e. Tabl e 11.1 l ist s t hese f or mat s.
Tabl e 11.1. Val id val ue-f iel d f or mat s.
Fiel d Val ue-f iel d f or mat
@<<<
Lef t -just if ied out put
@>>>
Right -just if ied out put
@|||
Cent er ed out put
@##.##
Fixed-pr ecision numer ic
@*
Mul t il ine t ext
NOTE
In left-justified out put , t he val ue being displ ayed appear s
at t he l ef t end of t he val ue f iel d. In right-justified out put ,
t he val ue being displ ayed appear s at t he r ight end of t he
val ue f iel d
In each of t he f iel d f or mat s, t he f ir st char act er is a line-fill character. It indicat es
whet her t ext f or mat t ing is r equir ed. If t he @ char act er is specif ied as t he l ine f il l
char act er , t ext f or mat t ing is not per f or med. (For a discussion of t ext f or mat t ing, see t he
sect ion t it l ed "For mat t ing Long Char act er St r ings," l at er t oday.)
In al l cases, except f or t he mul t il ine val ue f iel d @*, t he widt h of t he f iel d is equal t o
t he number of char act er s specif ied. The @ char act er is incl uded when count ing t he
number of char act er s in t he val ue f iel d. For exampl e, t he f ol l owing f iel d is f ive
char act er s wide-one @ char act er and f our > char act er s:
@>>>>
Simil ar l y, t he f ol l owing f iel d is seven char act er s wide-f our bef or e t he decimal point ,
t wo af t er t he decimal point , and t he decimal point it sel f :
@###.##
List ing 11.4 il l ust r at es how you can use t he val ue f iel d f or mat s t o pr oduce a neat l y
pr int ed r epor t . The r epor t is r edir ect ed t o a f il e f or l at er pr int ing.

List ing 11.4. A pr ogr am t hat uses t he var ious val ue-f iel d f or mat s.
1: #!/usr/local/bin/perl
2:
3: $company = <STDIN>;
4: $~ = "COMPANY";
5: write;
6:
7: $grandtotal = 0;
8: $custline = <STDIN>;
9: while ($custline ne "") {
10: $total = 0;
11: ($customer, $date) = split(/#/, $custline);
12: $~ = "CUSTOMER";
13: write;
14: while (1) {
15: $orderline = <STDIN>;
16: if ($orderline eq "" || $orderline =~ /#/) {
17: $custline = $orderline;
18: last;
19: }
20: ($item, $cost) = split(/:/, $orderline);
21: $~ = "ORDERLINE";
22: write;
23: $total += $cost;
24: }
25: &write_total ("Total:", $total);
26: $grandtotal += $total;
27: }
28: &write_total ("Grand total:", $grandtotal);
29:
30: sub write_total {
31: local ($totalstring, $total) = @_;
32: $~ = "TOTAL";
33: write;
34: }
35:
36: format COMPANY =
37: ************* @|||||||||||||||||||||||||||||| *************
38: $company
39: .
40: format CUSTOMER =
41: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>>>>>
42: $customer, $date
43: .
44: format ORDERLINE =
45: @<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @####.##
46: $item, $cost
47: .
48: format TOTAL =
49: @<<<<<<<<<<<<<< @#####.##
50: $totalstring, $total
51:
52: .

$ program11_4 >report
Consolidated Widgets, Inc.
John Doe#Feb 11, 1994
1 flying widget:171.42
1 crawling widget:89.99
Mary Smith#May 4, 1994
2 swimming widgets:203.43
^D
$
The f ol l owing r epor t is wr it t en t o t he report f il e:
************* Consolidated Widgets, Inc. *************
John Doe Feb 11, 1994
1 flying widget 171.42
1 crawling widget 89.99
Total: 261.41
Mary Smith May 4, 1994
2 swimming widgets 203.43
Total: 203.43
Grand total: 464.84
This pr ogr am st ar t s of f by r eading t he company name f r om t he st andar d input
f il e and t hen wr it ing it out . Line 5 wr it es t he company name using t he pr int f or mat
COMPANY, which uses a cent er ed out put f iel d t o displ ay t he company name in t he cent er of
t he l ine.
Af t er t he company name has been pr int ed, t he pr ogr am st ar t s pr ocessing dat a f or one
cust omer at a t ime. Each cust omer r ecor d is assumed t o consist of a cust omer name and
dat e f ol l owed by l ines of or der s. The cust omer name r ecor d uses a # char act er as t he
f iel d separ at or , and t he or der r ecor ds use : char act er s as t he separ at or ; t his enabl es
t he pr ogr am t o dist inguish one t ype of r ecor d f r om t he ot her .
Line 13 pr int s t he cust omer inf or mat ion using t he CUSTOMER pr int f or mat . This f or mat
cont ains t wo f iel ds: a l ef t -just if ied out put f iel d f or t he cust omer name, and a r ight -
just if ied out put f iel d f or t he dat e of t he t r ansact ion.
Line 22 pr int s an or der l ine using t he ORDERLINE pr int f or mat . This pr int f or mat al so
cont ains t wo f iel ds: a l ef t -just if ied out put f iel d indicat ing t he it em or der ed, and a
numer ic f iel d t o displ ay t he cost of t he it em.
The val ue f iel d f or mat @####.## indicat es t hat t he cost is t o be displ ayed as a f l oat ing-
point number . This number is def ined as cont aining at most f ive digit s bef or e t he decimal
point , and t wo digit s af t er .
Final l y, t he pr int f or mat TOTAL pr int s t he cust omer t ot al and t he gr and t ot al . Because
t his pr int f or mat is used inside a subr out ine, t he same pr int f or mat can be used t o pr int
bot h t ot al s.
Nor mal l y, any f l oat ing-point number you pr int is
r ounded up when necessar y. For exampl e, when you pr int
43.999 in t he val ue f iel d @#.##, it appear s as 44.00.
However , a f l oat ing-point number whose l ast decimal
pl ace is 5 might or might not r ound cor r ect l y. For
exampl e, if you ar e wr it ing using t he val ue f iel d @#.##,
some number s whose t hir d and l ast decimal pl ace is 5 wil l
r ound and ot her s wil l not . This happens because some
f l oat ing-point number s cannot be st or ed exact l y, and
t he near est equival ent number t hat can be st or ed is a
sl ight l y smal l er number (which r ounds down, not up)
Printing Value-Field Characters
As you have seen, cer t ain char act er s such as @, <, and > ar e t r eat ed as val ue f iel ds when
t hey ar e encount er ed in pr int f or mat s. List ing 11.5 shows how t o act ual l y pr int one of
t hese special char act er s using write.

List ing 11.5. A pr ogr am t hat pr int s a val ue-f iel d char act er .
1: #!/usr/local/bin/perl
2:
3: format SPECIAL =
4: This line contains the special character @.
5: "@"
6: .
7:
8: $~ = "SPECIAL";
9: write;

$ program11_5
This line contains the special character @.
$
The pr int f or mat l ine in l ine 4 cont ains t he special char act er @, which is a one-
char act er val ue f iel d. Line 5 specif ies t hat t he st r ing @ is t o be displ ayed in t his val ue
f iel d when t he l ine is pr int ed.
Using the Multiline Field Format
List ing 11.6 uses t he mul t il ine f iel d f or mat @* t o wr it e a char act er st r ing over sever al
l ines.

List ing 11.6. A pr ogr am t hat wr it es a st r ing using t he mul t il ine f iel d
f or mat .
1: #!/usr/local/bin/perl
2:
3: @input = <STDIN>;
4: $string = join("", @input);
5: $~ = "MULTILINE";
6: write;
7:
8: format MULTILINE =
9: ****** contents of the input file: ******
10: @*
11: $string
12: *****************************************
13: .

$ program11_6
Here is a line of input.
Here is another line.
Here is the last line.
^D
****** contents of the input file: ******
Here is a line of input.
Here is another line.
Here is the last line.
*****************************************
$
Line 3 r eads t he ent ir e input f il e int o t he ar r ay var iabl e @input. Each
el ement of t he l ist st or ed in @input is one l ine of t he input f il e.
Line 4 joins t he input l ines int o a singl e char act er st r ing, st or ed in $string. This
char act er st r ing st il l cont ains t he newl ine char act er s t hat end each l ine.
Line 6 cal l s write using t he pr int f or mat MULTILINE. The @* val ue f iel d in t his pr int -
f or mat def init ion indicat es t hat t he val ue st or ed in $string is t o be wr it t en out using as
many l ines as necessar y. This ensur es t hat t he ent ir e st r ing st or ed in $string is wr it t en
out .
If a char act er st r ing cont ains a newl ine char act er , t he
onl y way t o displ ay t he ent ir e st r ing using write is t o
use t he @* mul t il ine val ue f iel d. If you use any ot her
val ue f iel d, onl y t he par t of t he st r ing pr eceding t he
f ir st newl ine char act er is displ ayed
Writing to Other Output Files
So f ar , al l of t he exampl es t hat have used t he f unct ion write have wr it t en t o t he
st andar d out put f il e. However , you can use write al so t o send out put t o ot her f il es.
The simpl est way t o do t his is t o pass t he f il e t o wr it e t o as an ar gument t o write. For
exampl e, t o wr it e t o t he f il e r epr esent ed by t he f il e var iabl e MYFILE using t he pr int
f or mat MYFILE, you can use t he f ol l owing st at ement :
write (MYFILE);
Her e, write wr it es t o t he f il e named MYFILE using t he def aul t pr int f or mat , which is al so
MYFILE. This is t idy and ef f icient , but somewhat r est r ict ing because, in t his case, you can't
use $~ t o choose t he pr int f or mat t o use.
The $~ syst em var iabl e onl y wor ks wit h t he default file variable, which is t he f il e var iabl e
t o which write sends out put . To change t he def aul t f il e var iabl e, and t her ef or e change
t he f il e t hat $~ af f ect s, cal l t he buil t -in f unct ion select, as f ol l ows:
select (MYFILE);
select set s t he def aul t f il e var iabl e t o use when wr it ing. For exampl e, t o wr it e t o t he
f il e r epr esent ed by t he f il e var iabl e MYFILE using t he pr int f or mat MYFORMAT, you can use
t he f ol l owing st at ement s:
select(MYFILE);
$~ = "MYFORMAT";
write;
Her e, t he buil t -in f unct ion select indicat es t hat t he f il e t o be wr it t en t o is t he f il e
r epr esent ed by t he f il e var iabl e MYFILE. The st at ement
$~ = "MYFORMAT";
sel ect s t he pr int f or mat t o be associat ed wit h t his par t icul ar f il e handl e; in t his case,
t he pr int f or mat MYFORMAT is now associat ed wit h t he f il e var iabl e MYFILE.
NOTE
This is wor t h r epeat ing: Each f il e var iabl e has it s own
cur r ent pr int f or mat . An assignment t o $~ onl y changes
t he pr int f or mat f or t he cur r ent f il e var iabl e (t he l ast
one passed t o select)
Because select has changed t he f il e t o be wr it t en t o, t he cal l t o write no l onger wr it es
t o t he st andar d out put f il e. Inst ead, it wr it es t o MYFILE. Cal l s t o write cont inue t o
wr it e t o MYFILE unt il t he f ol l owing st at ement is seen:
select(STDOUT);
This st at ement r eset s t he wr it e f il e t o be t he st andar d out put f il e.
Changing t he wr it e f il e using sel ect not onl y af f ect s
write; it al so af f ect s print. For exampl e, consider t he
f ol l owing:
select (MYFILE);
print ("Here is a line of text.\n");
This cal l t o print wr it es t o MYFILE, not t o t he st andar d
out put f il e. As wit h write, cal l s t o print cont inue t o
wr it e t o MYFILE unt il anot her cal l t o select is seen
The select f unct ion is usef ul if you want t o be abl e t o use t he same subr out ine t o wr it e
t o mor e t han one f il e at a t ime. List ing 11.7 is an exampl e of a simpl e pr ogr am t hat does
t his.

List ing 11.7. A pr ogr am t hat uses t he select f unct ion.
1: #!/usr/local/bin/perl
2:
3: open (FILE1, ">file1");
4: $string = "junk";
5: select (FILE1);
6: &writeline;
7: select (STDOUT);
8: &writeline;
9: close (FILE1);
10:
11: sub writeline {
12: $~ = "WRITELINE";
13: write;
14: }
15:
16: format WRITELINE =
17: I am writing @<<<<< to my output files.
18: $string
19: .

$ program11_7
I am writing junk to my output files.
$
Line 5 of t his pr ogr am cal l s select, which set s t he def aul t f il e var iabl e t o
FILE1. Now, al l cal l s t o write or print wr it e t o FILE, not t he st andar d out put f il e.
Line 6 cal l s writeline t o wr it e a l ine. This subr out ine set s t he cur r ent pr int f or mat f or
t he def aul t f il e var iabl e t o WRITELINE. This means t hat t he f il e FILE1 now is using t he
pr int f or mat WRITELINE, and, t her ef or e, t he subr out ine wr it es t he f ol l owing l ine t o t he
f il e FILE1 (which is file1):
I am writing junk to my output files.
Line 7 set s t he def aul t f il e var iabl e back t o t he st andar d out put f il e var iabl e, STDOUT.
This means t hat write and print now send out put t o t he st andar d out put f il e. Not e t hat
t he cur r ent pr int f or mat f or t he st andar d out put f il e is STDOUT (t he def aul t ), not
WRITELINE; t he assignment t o $~ in t he subr out ine WRITELINE af f ect s onl y FILE1, not
STDOUT.
Line 8 cal l s writeline again; t his t ime, t he subr out ine wr it es a l ine t o t he st andar d
out put f il e. The assignment
$~ = "WRITELINE";
in l ine 12 associat es t he pr int f or mat WRITELINE wit h t he st andar d out put f il e. This
means t hat WRITELINE is now associat ed wit h bot h STDOUT and FILE1.
At t his point , t he cal l t o write in l ine 13 wr it es t he l ine of out put t hat you see on t he
st andar d out put f il e.
DO, whenever possibl e, cal l select and assign t o $~
immediat el y bef or e cal l ing write, as f ol l ows:
select (MYFILE);
$~ = "MYFORMAT";
write;
Keeping t hese st at ement s t oget her makes it cl ear which
f il e is being wr it t en t o and which pr int f or mat is being
used.
DON' T use select and $~ indiscr iminat el y, because you
might l ose t r ack of which pr int f or mat goes wit h which
f il e var iabl e, and you might f or get which f il e var iabl e is
t he def aul t f or pr int ing
Saving the Default File Variable
When select changes t he def aul t f il e var iabl e, it r et ur ns an int er nal r epr esent at ion of
t he f il e var iabl e t hat was l ast sel ect ed. For exampl e:
$oldfile = select(NEWFILE);
This cal l t o select is set t ing t he cur r ent f il e var iabl e t o NEWFILE. The ol d f il e var iabl e
is now st or ed in $oldfile. To r est or e t he pr evious def aul t f il e var iabl e, you can cal l
select as f ol l ows:
select ($oldfile);
At t his point , t he def aul t f il e var iabl e r ever t s back t o it s or iginal val ue (what it was
bef or e NEWFILE was sel ect ed).
The int er nal r epr esent at ion of t he f il e var iabl e
r et ur ned by select is not necessar il y t he name of t he
f il e var iabl e
You can use t he r et ur n val ue f r om select t o cr eat e subr out ines t hat wr it e t o t he f il e
you want t o wr it e wit h, using t he pr int f or mat you want t o use, wit hout af f ect ing t he
r est of t he pr ogr am. For exampl e:
sub write_to_stdout {
local ($savefile, $saveformat);
$savefile = select(STDOUT);
$saveformat = $~;
$~ = "MYFORMAT";
write;
$~ = $saveformat;
select($savefile);
}
This subr out ine cal l s select t o set t he def aul t out put f il e t o STDOUT, t he st andar d
out put f il e. The r et ur n val ue f r om select, t he pr evious def aul t f il e, is saved in
$savefile.
Now t hat t he def aul t out put f il e is STDOUT, t he next st ep is t o save t he cur r ent pr int
f or mat being used t o wr it e t o STDOUT. The subr out ine does t his by saving t he pr esent
val ue of $~ in anot her l ocal var iabl e, $saveformat. Af t er t his is saved, t he subr out ine
can set t he cur r ent pr int f or mat t o MYFORMAT. The cal l t o write now wr it es t o t he
st andar d out put f il e using MYFORMAT.
Af t er t he cal l t o write is compl et e, t he subr out ine put s t hings back t he way t hey wer e.
The f ir st st ep is t o r eset $~ t o t he val ue st or ed in $saveformat. The f inal st ep is t o set
t he def aul t out put f il e back t o t he f il e var iabl e whose r epr esent at ion is saved in
$savefile.
Not e t hat t he cal l t o select must appear af t er t he assignment t o $~. If t he cal l t o
select had been f ir st , t he assignment t o $~ woul d change t he pr int f or mat associat ed
wit h t he or iginal def aul t f il e var iabl e, not STDOUT.
As you can see, t his subr out ine doesn't need t o know what t he def aul t val ues out side
t he subr out ine ar e. Al so, it does not af f ect t he def aul t val ues out side t he subr out ine.
Specifying a Page Header
If you ar e sending your out put t o a pr int er , you can make your out put l ook smar t er by
suppl ying t ext t o appear at t he t op of ever y page in your out put . This special t ext is
cal l ed a page header.
If a page header is def ined f or a par t icul ar out put f il e, write aut omat ical l y paginat es
t he out put t o t hat f il e. When t he number of l ines pr int ed is gr eat er t han t he l engt h of
a page, write st ar t s a new page.
To def ine a page header f or a f il e, cr eat e a pr int f or mat def init ion wit h t he name of
filename_TOP, wher e filename is a pl acehol der f or t he name of t he f il e var iabl e
cor r esponding t o t he f il e t o which you ar e wr it ing. For exampl e, t o def ine a header f or
wr it ing t o st andar d out put , def ine a pr int f or mat named STDOUT_TOP, as f ol l ows:
format STDOUT_TOP =
Consolidated Widgets Inc. 1994 Annual Report
.
In t his case, when t he Per l int er pr et er st ar t s a new page of st andar d out put , t he
cont ent s of t he pr int f or mat STDOUT_TOP ar e pr int ed aut omat ical l y.
Pr int f or mat s t hat gener at e header s can cont ain val ue f iel ds which ar e r epl aced by
scal ar val ues, just l ike any ot her pr int f or mat . One par t icul ar val ue t hat is of t en used
in page header s is t he cur r ent page number , which is st or ed in t he syst em var iabl e $%. For
exampl e:
format STDOUT_TOP =
Page @<<.
$%
.
In t his case, when t he f ir st page is pr int ed, t he pr ogr am pr int s t he f ol l owing header at
t he t op of t he page:
Page 1.
NOTE
By def aul t , $% is init ial l y set t o zer o and is incr ement ed
ever y t ime a new page begins.
To change t he paginat ion, change t he val ue of $% bef or e
(or dur ing) pr int ing
Changing the Header Print Format
To change t he name of t he pr int f or mat t hat pr int s a page header f or a par t icul ar f il e,
change t he val ue st or ed in t he special syst em var iabl e $^.
As wit h $~, onl y t he val ue f or t he cur r ent def aul t f il e can be changed. For exampl e, t o
use t he pr int f or mat MYHEADER as t he header f il e f or t he f il e MYFILE, add t he f ol l owing
st at ement s:
$oldfile = select(MYFILE);
$^ = "MYHEADER";
select($oldfile);
.
These st at ement s set MYFILE t o be t he cur r ent def aul t f il e, change t he header f or
MYFILE t o be t he pr int f or mat MYHEADER, and t hen r eset t he cur r ent def aul t f il e t o it s
or iginal val ue.
Setting the Page Length
By def aul t , t he page l engt h is 60 l ines. To specif y a dif f er ent page l engt h, change t he
val ue st or ed in t he syst em var iabl e $=:
$= = 66; # set the page length to 66 lines
This assignment must appear bef or e t he f ir st write st at ement .
If t he page l engt h is changed in t he middl e of t he
pr ogr am, t he new page l engt h wil l not be used unt il a
new page is st ar t ed
List ing 11.8 shows how you can set t he page l engt h and def ine a page-header pr int
f or mat f or your out put f il e.

List ing 11.8. A pr ogr am t hat set s t he l engt h and pr int f or mat f or a
page.
1: #!/usr/local/bin/perl
2:
3: open (OUTFILE, ">file1");
4: select (OUTFILE);
5: $~ = "WRITELINE";
6: $^ = "TOP_OF_PAGE";
7: $= = 60;
8: while ($line = <STDIN>) {
9: write;
10: }
11: close (OUTFILE);
12:
13: format TOP_OF_PAGE =
14: - page @<
15: $%
16: .
17: format WRITELINE =
18: @>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
19: $line
20: .

Suppose t hat you suppl y t he f ol l owing input :
$ program11_8
Here is a line of input.
Here is another line.
Here is the last line.
^D
$
The f ol l owing out put is wr it t en t o t he f il e file1:
- page 1
Here is a line of input.
Here is another line.
Here is the last line.
Line 3 opens t he f il e file1 f or out put and associat es it wit h t he f il e var iabl e
OUTFILE.
Line 4 set s t he cur r ent def aul t f il e t o OUTFILE. Now, when write or print is cal l ed wit h
no f il e var iabl e suppl ied, t he out put is sent t o OUTFILE.
Line 5 indicat es t hat WRITELINE is t he pr int f or mat t o be used when wr it ing t o t he f il e
OUTFILE. To do t his, it assigns WRITELINE t o t he syst em var iabl e $~. This assignment does
not af f ect t he page header .
Line 6 indicat es t hat TOP_OF_PAGE is t he pr int f or mat t o be used when pr int ing t he page
header s f or t he f il e OUTFILE. This assignment does not af f ect t he pr int f or mat used t o
wr it e t o t he body of t he page.
Line 7 set s t he page l engt h t o 60 l ines. This page l engt h t akes ef f ect immediat el y,
because no out put has been wr it t en t o OUTFILE.
Using print with Pagination
Nor mal l y, you won't want t o use print if you ar e using paginat ion, because t he Per l
int er pr et er keeps t r ack of t he cur r ent l ine number on t he page by monit or ing t he cal l s
t o write. If you must use a cal l t o print in your pr ogr am and you want t o ensur e t hat
t he page count er incl udes t he cal l in it s l ine count , adjust t he syst em var iabl e $-. This
syst em var iabl e indicat es t he number of l ines bet ween t he cur r ent l ine and t he bot t om
of t he page. When $- r eaches 0, a t op-of -f or m char act er is gener at ed, which st ar t s a new
page.
The f ol l owing is a code f r agment t hat cal l s print and t hen adjust s t he $- var iabl e:
print ("Here is a line of output\n");
$- -= 1;
When $- has 1 subt r act ed f r om it s val ue, t he page count er becomes cor r ect .
Formatting Long Character Strings
As you've seen, t he @* val ue f iel d pr int s mul t ipl e l ines of t ext . However , t his f iel d pr int s
t he out put exact l y as it is st or ed in t he char act er st r ing. For exampl e, consider List ing
11.9, which uses @* t o wr it e a mul t il ine char act er st r ing.

List ing 11.9. A pr ogr am t hat il l ust r at es t he l imit at ions of t he @* val ue
f iel d.
1: #!/usr/local/bin/perl
2:
3: $string = "Here\nis an unbalanced line of\ntext.\n";
4: $~ = "OUTLINE";
5: write;
6:
7: format OUTLINE =
8: @*
9: $string
10: .

$ program11_9
Here
is an unbalanced line of
text.
$
This cal l t o write displ ays t he char act er st r ing st or ed in $string exact l y as
is. Per l enabl es you t o def ine val ue f iel ds in pr int -f or mat def init ions t hat f or mat t ext .
To do t his, r epl ace t he init ial @ char act er in t he val ue f iel d wit h a ^ char act er . When
t ext f or mat t ing is specif ied, t he Per l int er pr et er t r ies t o f it as many wor ds as possibl e
int o t he out put l ine.
List ing 11.10 is an exampl e of a simpl e pr ogr am t hat does t his.

List ing 11.10. A pr ogr am t hat uses a val ue f iel d t hat does f or mat t ing.
1: #!/usr/local/bin/perl
2:
3: $string = "Here\nis an unbalanced line of\ntext.\n";
4: $~ = "OUTLINE";
5: write;
6:
7: format OUTLINE =
8: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<
9: $string
10: .

$ program11_10
Here is an unbalanced line
$
Line 5 cal l s write using t he pr int f or mat OUTLINE. This pr int f or mat cont ains a
val ue f iel d t hat specif ies t hat f or mat t ing is t o t ake pl ace; t his means t hat t he Per l
int er pr et er t r ies t o f it as many wor ds as possibl e int o t he l ine of out put . In t his case, t he
f ir st l ine Here and t he f our -wor d st r ing is an unbalanced line f it int o t he out put l ine.
Not e t hat t her e ar e t wo char act er s l ef t over in t he out put l ine af t er t he f our wor ds
have been f il l ed in. These char act er s ar e not f il l ed, because t he next wor d is not shor t
enough t o f it int o t he space r emaining. Onl y ent ir e wor ds ar e f il l ed.
One ot her f eat ur e of t he l ine-f il l ing oper at ion is t hat t he subst r ing pr int ed out is
act ual l y del et ed f r om t he scal ar var iabl e $string. This means t hat t he val ue of
$string is now of\ntext.\n. This happens because subsequent l ines of out put in t he same
pr int -f or mat def init ion can be used t o pr int t he r est of t he st r ing.
NOTE
Because t he l ine-f il l ing write oper at ion updat es t he
val ue used, t he val ue must be cont ained in a scal ar
var iabl e and cannot be t he r esul t of an expr ession
To see how mul t ipl e l ines of f or mat t ed out put wor k, l ook at List ing 11.11. This pr ogr am
r eads a quot at ion f r om t he st andar d input f il e and wr it es it out on t hr ee f or mat t ed
l ines of out put .

List ing 11.11. A pr ogr am t hat wr it es out mul t ipl e f or mat t ed l ines of
out put .
1: #!/usr/local/bin/perl
2:
3: @quotation = <STDIN>;
4: $quotation = join("", @quotation);
5: $~ = "QUOTATION";
6: write;
7:
8: format QUOTATION =
9: Quotation for the day:
10: -----------------------------
11: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
12: $quotation
13: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
14: $quotation
15: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
16: $quotation
17: -----------------------------
18: .

$ program11_11
Any sufficiently advanced programming
language is indistinguishable from magic.
^D
Quotation for the day:
-----------------------------
Any sufficiently advanced programming language is
indistinguishable from magic.
-----------------------------
$
The pr int f or mat QUOTATION def ines t hr ee val ue f iel ds on which f or mat t ing is
t o be empl oyed. Each of t he t hr ee val ue f iel ds uses t he val ue of t he scal ar var iabl e
$quotation.
Bef or e write is cal l ed, $quotation cont ains t he ent ir e quot at ion wit h newl ine
char act er s appear ing at t he end of each input l ine. When write is cal l ed, t he f ir st val ue
f iel d in t he pr int f or mat uses as much of t he quot at ion as possibl e. This means t hat t he
f ol l owing subst r ing is wr it t en t o t he st andar d out put f il e:
Any sufficiently advanced programming language is
Af t er t he subst r ing is wr it t en, it is r emoved f r om $quotation, which now cont ains t he
f ol l owing:
indistinguishable from magic.
Because t he wr it t en subst r ing has been r emoved f r om $quotation, t he r emainder of t he
st r ing can be used in subsequent out put l ines. Because t he next val ue f iel d in t he pr int
f or mat al so want s t o use $quotation, t he r emainder of t he st r ing appear s on t he second
out put l ine and is del et ed. $quotation is now t he empt y st r ing.
This means t hat t he t hir d val ue f iel d, which al so r ef er s t o $quotation, is r epl aced by t he
empt y st r ing, and a bl ank l ine is wr it t en out .
The scal ar var iabl e cont aining t he out put t o be pr int ed
is changed by a write oper at ion. If you need t o pr eser ve
t he inf or mat ion, copy it t o anot her scal ar var iabl e
bef or e cal l ing write
Eliminating Blank Lines When Formatting
You can el iminat e bl ank l ines such as t he one gener at ed by List ing 11.11. To do t his, put
a ~ char act er at t he beginning of any out put l ine t hat is t o be pr int ed onl y when
needed.
List ing 11.12 modif ies t he quot at ion-pr int ing pr ogr am t o pr int l ines onl y when t hey ar e
not bl ank.

List ing 11.12. A pr ogr am t hat wr it es out mul t ipl e f or mat t ed l ines of
out put and suppr esses bl ank l ines.
1: #!/usr/local/bin/perl
2:
3: @quotation = <STDIN>;
4: $quotation = join("", @quotation);
5: $~ = "QUOTATION";
6: write;
7:
8: format QUOTATION =
9: Quotation for the day:
10: -----------------------------
11: ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
12: $quotation
13: ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
14: $quotation
15: ~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
16: $quotation
17: -----------------------------
18: .

$ program11_12
Any sufficiently advanced programming
language is indistinguishable from magic.
^D
Quotation for the day:
-----------------------------
Any sufficiently advanced programming language is
indistinguishable from magic.
-----------------------------
$
If t he quot at ion is t oo shor t t o r equir e al l t he l ines, r emaining l ines ar e l ef t
bl ank. In t his case, t he quot at ion r equir es onl y t wo l ines of out put , so t he t hir d isn't
pr int ed.
The pr ogr am is ident ical t o t he one in List ing 11.11 in al l ot her r espect s. In par t icul ar ,
t he val ue of $quotation af t er t he cal l t o write is st il l t he empt y st r ing.
Supplying an Indefinite Number of Lines
Whil e List ing 11.12 suppr esses bl ank l ines, it imposes an upper l imit of t hr ee l ines.
Quot at ions l onger t han t hr ee l ines ar e not pr int ed in t heir ent ir et y. To indicat e t hat
t he f or mat t ed out put is t o use as many l ines as necessar y, specif y t wo ~ char act er s at
t he beginning of t he out put l ine cont aining t he val ue f iel d. List ing 11.13 modif ies t he
quot at ion pr ogr am t o al l ow quot at ions of any l engt h.

List ing 11.13. A pr ogr am t hat wr it es out as many f or mat t ed l ines of
out put as necessar y.
1: #!/usr/local/bin/perl
2:
3: @quotation = <STDIN>;
4: $quotation = join("", @quotation);
5: $~ = "QUOTATION";
6: write;
7:
8: format QUOTATION =
9: Quotation for the day:
10: -----------------------------
11: ~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
12: $quotation
13: -----------------------------
14: .

$ program11_13
Any sufficiently advanced programming
language is indistinguishable from magic.
^D
Quotation for the day:
----------------------------
Any sufficiently advanced programming language is
indistinguishable from magic.
-----------------------------
$
The ~~ char act er s at t he beginning of t he out put f iel d indicat e t hat mul t ipl e
copies of t he out put l ine ar e t o be suppl ied. The out put l ine is t o be pr int ed unt il t her e is
not hing mor e t o pr int .
In List ing 11.13, t wo copies of t he l ine ar e needed.
Formatting Output Using printf
If you want t o wr it e out put t hat l ooks r easonabl e wit hout going t o al l t he t r oubl e of
using write and print f or mat s, Per l pr ovides a buil t -in f unct ion, printf, t hat pr int s
f or mat t ed out put .
NOTE
If you ar e f amil iar wit h t he C pr ogr amming l anguage,
t he behavior of printf in Per l wil l be f amil iar ; t he Per l
printf and t he C printf ar e basical l y t he same
The ar gument s passed t o t he printf f unct ion ar e as f ol l ows:
G The st r ing t o be pr int ed, which can cont ain one or mor e field specifiers
G One val ue f or each f iel d specif ier appear ing in t he st r ing t o be pr int ed
When printf sees a f iel d specif ier , it subst it ut es t he cor r esponding val ue in t he printf
ar gument l ist . The r epr esent at ion of t he subst it ut ed val ue in t he st r ing depends on t he
f iel d specif ier t hat is suppl ied.
Fiel d specif ier s consist of t he % char act er f ol l owed by a singl e char act er t hat
r epr esent s t he f or mat t o use when pr int ing. Tabl e 11.2 l ist s t he f iel d-specif ier f or mat s
and t he f iel d-specif ier char act er t hat r epr esent s each.
Tabl e 11.2. Fiel d specif ier s f or printf.
Specif ier Descr ipt ion
%c
Singl e char act er
%d
Int eger in decimal (base-10) f or mat
%e
Fl oat ing-point number in scient if ic
not at ion
%f
Fl oat ing-point number in "nor mal "
(f ixed-point ) not at ion
%g
Fl oat ing-point number in compact
f or mat
%o
Int eger in oct al (base-8) f or mat
%s
Char act er st r ing
%u
Unsigned int eger
%x
Int eger in hexadecimal (base-16)
f or mat
Her e is a simpl e exampl e of a cal l t o printf:
printf("The number I want to print is %d.\n", $number);
The st r ing t o be pr int ed cont ains one f iel d specif ier , %d, which r epr esent s an int eger . The
val ue st or ed in $number is subst it ut ed f or t he f iel d specif ier and pr int ed.
Fiel d specif ier s al so suppor t a var iet y of opt ions, as f ol l ows:
G If you ar e pr int ing an int eger using t he d, o, u, or x f or mat , you can put an l
char act er in f r ont of t he f iel d-specif ier char act er (as in, f or exampl e, %ld). This
char act er specif ies t hat t he number is a decimal int eger in t he machine's "l ong
int eger " f or mat (cor r esponding t o t he C t ype long). This is usef ul if your int eger is
l ar ge or might be.
G A posit ive int eger f ol l owing t he % char act er indicat es t he minimum widt h of t he
f iel d. For exampl e, %20s pr int s a char act er st r ing in a f iel d of 20 char act er s. If t he
st r ing is not l ar ge enough t o f il l t he ent ir e f iel d, it is r ight just if ied (pl aced at
t he r ight end of t he f iel d) and padded wit h bl anks. (If t he int eger st ar t s wit h a
l eading 0, as in %08d, t he f iel d is padded wit h zer os, not bl anks.)
G A negat ive int eger f ol l owing t he % char act er indicat es t he widt h of t he f iel d and
r equest s l ef t just if icat ion. For exampl e, %-15s pr int s a char act er st r ing in a f iel d
of 15 char act er s, and it f il l s t he r ight end of t he f iel d wit h bl anks if t he st r ing is
not l ar ge enough.
G If you ar e using a f iel d specif ier t hat pr int s a f l oat ing-point number (%e, %f, or %g),
you can specif y t he number of digit s t hat ar e t o appear af t er t he decimal point . To
do t his, specif y a f l oat ing-point number af t er t he % char act er . For exampl e:
%8.3f
G Her e, t he number pr eceding t he decimal point is t he f iel d widt h (as bef or e), and t he
number af t er t he decimal point is t he number of decimal pl aces t o pr int .
If a f l oat ing-point number cont ains mor e digit s t han t he
f iel d specif ier want s, t he number is r ounded t o t he
number of decimal pl aces needed. For exampl e, if 43.499 is
being pr int ed using t he f iel d %5.2f, t he number act ual l y
pr int ed is 43.50.
As wit h t he wr it e val ue f iel d @##.##, printf might not
al ways r ound up when it is handl ing number s whose l ast
decimal pl ace is 5. This happens because some f l oat ing-
point number s cannot be st or ed exact l y, and t he near est
equival ent number t hat can be st or ed is a sl ight l y
smal l er number (which r ounds down, not up). For
exampl e, 43.495 when pr int ed by %5.2f might pr int 43.49,
depending on how 43.495 is st or ed
G If you ar e using a f iel d specif ier t hat pr int s an int eger , char act er , or st r ing,
suppl ying a f l oat ing-point number af t er t he % char act er specif ies t he maximum
l engt h of t he val ue t o be pr int ed. In t he f ol l owing exampl e a char act er st r ing is
pr int ed in a 15-char act er f iel d, but t he st r ing it sel f can be at most 10 char act er s
l ong:
%15.10s
G This guar ant ees t hat at l east f ive spaces wil l appear in t he pr int ed l ine.
NOTE
You can use printf t o pr int t o ot her f il es. To do t his,
specif y t he f il e var iabl e cor r esponding t o t he f il e t o
which you want t o pr int , just as you woul d wit h print or
write
printf MYFILE ("I am printing %d.\n", $value);
This means t hat changing t he cur r ent def aul t f il e using
select af f ect s printf.
Summary
Per l enabl es you t o f or mat your out put using pr int -f or mat def init ions and t he buil t -in
f unct ion write. In pr int -f or mat def init ions, you can specif y val ue f iel ds t hat ar e t o be
r epl aced by eit her t he cont ent s of scal ar var iabl es or t he val ues of expr essions.
Val ue f iel ds indicat e how t o pr int t he cont ent s of a scal ar var iabl e or t he val ue of an
expr ession. Wit h a val ue f iel d, you can specif y t hat t he val ue is t o be l ef t just if ied
(bl anks added on t he r ight ), r ight just if ied (bl anks added on t he l ef t ), cent er ed, or
displ ayed as a f l oat ing-point number .
You al so can def ine val ue f iel ds t hat f or mat a mul t il ine char act er st r ing. Bl ank l ines
can be suppr essed, and t he f iel d can be def ined t o use as many out put l ines as necessar y.
The buil t -in f unct ion select enabl es you t o change t he def aul t f il e t o which write and
print send out put .
You can br eak your out put int o pages by def ining a special header pr int f or mat t hat
pr int s header inf or mat ion at t he t op of each page.
The f ol l owing syst em var iabl es enabl e you t o cont r ol how write sends out put t o a f il e:
G The syst em var iabl e $~ cont ains t he name of t he pr int f or mat being used by t he
cur r ent def aul t f il e.
G The syst em var iabl e $^ cont ains t he name of t he pr int f or mat being used as a page
header by t he cur r ent def aul t f il e.
G The syst em var iabl e $= cont ains t he number of l ines per pr int ed page.
G The syst em var iabl e $- cont ains t he number of l ines l ef t on t he cur r ent page.
The buil t -in f unct ion printf enabl es you t o f or mat an individual l ine of t ext using
f or mat specif ier s.
Q&A
Q: Which is bet t er , write or printf?
A: It depends on what you want t o do. If you want t o pr int r epor t s or cont r ol
paginat ion, you'l l need t o use write. If you just want individual l ines of out put
t o l ook neat , printf might be what you need.
Q: How do I gener at e a page br eak?
A: To do t his, set $- t o zer o. This gener at es a t op-of -f or m char act er .
Q: Why do val ue f iel ds t hat f or mat t ext modif y t he cont ent s of t he scal ar
var iabl e cont aining t he t ext ?
A: When f or mat t ed t ext is pr int ed, t he pr int ed t ext is r emoved f r om t he scal ar
var iabl e, and t he par t of t he st r ing t hat is not pr int ed is r et ained. This enabl es
you t o use ot her cal l s t o write t o pr int t he r emainder of t he t ext . In f act , you
can pr int t he r est of t he t ext in t he scal ar var iabl e using a compl et el y dif f er ent
pr int f or mat .
Q: How many pr int f or mat s can I def ine?
A: Basical l y, as many as you l ike, pr ovided t he r esul t ing Per l pr ogr am can st il l f it
in your machine.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
t o under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. Def ine val ue f iel ds t hat pr int t he f ol l owing:
a. Ten l ef t -just if ied char act er s
b. Five r ight -just if ied char act er s
c. Two cent er ed char act er s
d. A f l oat ing-point number wit h f ive digit s bef or e t he decimal point and t hr ee
af t er it
e. A f iel d t hat pr int s as many f or mat t ed l ines of 30 l ef t -just if ied char act er s as
necessar y
2. What do t hese f iel ds pr int ?
a. @<<<<
b. @||||||
c. @
d. @*
e. ~ ^>>>>>>>>>
3. What do t hese printf f iel d specif ier s pr int ?
a. %5d
b. %11.4f
c. %010d
d. %-12s
e. %x
4. Why do cer t ain f l oat ing-point number s have r ound-of f pr obl ems?
5. How do you cr eat e a page header f or an out put f il e?
Exercises
1. Wr it e a pr ogr am t hat pr int s t he power s of 2 f r om 2**1 t o 2**10. Use write and a
pr int f or mat t o pr int t hem t hr ee t o a l ine. Al ign t he l ines so t hat t he r ight end of
each number is l ined up wit h t he r ight end of t he cor r esponding number on t he
pr evious l ine.
2. Repeat Exer cise 1 using printf.
3. Wr it e a pr ogr am t hat r eads t ext and f or mat s it int o 40-char act er l ines, l ef t -
just if ied. Put l ines of ast er isks above and bel ow t he t ext .
4. Wr it e a pr ogr am t hat r eads a set of dol l ar val ues such as 71.43 (one per l ine).
Wr it e out t wo val ues per l ine (t he f ir st and second on t he f ir st l ine, and so on).
Tot al each of t he r esul t ing col umns, and pr oduce a gr and t ot al .
5. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
format STDOUT =
@*
.
while ($line = <STDIN>) {
chop ($line);
if ($line eq "") {
print ("<blank line>\n");
next;
}
write;
}

Chapter 12
Working with the File System
CONTENTS
G Fil e Input and Out put Funct ions
H Basic Input and Out put Funct ions
H Skipping and Rer eading Dat a
H Syst em Read and Wr it e Funct ions
H Reading Char act er s Using getc
H Reading a Binar y Fil e Using binmode
G Dir ect or y-Manipul at ion Funct ions
H The mkdir Funct ion
H The chdir Funct ion
H The opendir Funct ion
H The closedir Funct ion
H The readdir Funct ion
H The telldir and seekdir Funct ions
H The rewinddir Funct ion
H The rmdir Funct ion
G Fil e-At t r ibut e Funct ions
H Fil e-Rel ocat ion Funct ions
H Link and Symbol ic Link Funct ions
H Fil e-Per mission Funct ions
H Miscel l aneous At t r ibut e Funct ions
G Using DBM Fil es
H The dbmopen Funct ion
H The dbmclose Funct ion
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson t eaches you how t o manipul at e your machine's f il e syst em using some of
Per l 's buil t -in l ibr ar y f unct ions. Today, you l ear n about t he f ol l owing:
G The f il e input and out put f unct ions
G The dir ect or y-manipul at ion f unct ions
G The f il e-at t r ibut e manipul at ion f unct ions
G The DBM f il e f unct ions
Many of t he f unct ions descr ibed in t oday's l esson use
f eat ur es of t he UNIX oper at ing syst em. If you ar e using
Per l on a machine t hat is not r unning UNIX, some of
t hese f unct ions might not be def ined or might behave
dif f er ent l y.
Check t he document at ion suppl ied wit h your ver sion of
Per l f or det ail s on which f unct ions ar e suppor t ed or
emul at ed on your machine
File Input and Output Functions
The f ol l owing sect ions descr ibe t he buil t -in l ibr ar y f unct ions t hat r ead inf or mat ion
f r om f il es and wr it e inf or mat ion t o f il es. These l ibr ar y f unct ions per f or m t he f ol l owing
t asks:
G Basic input and out put
G Skipping or r e-r eading dat a f r om a f il e
G Reading individual char act er s f r om a f il e
G Indicat ing t hat a f il e is a binar y f il e
Basic Input and Output Functions
Some of t he input and out put f unct ions suppl ied by Per l have been discussed in ear l ier
chapt er s. These ar e
G open, which l et s a pr ogr am access a f il e
G close, which t er minat es f il e access
G print, which wr it es a st r ing t o a f il e
G write, which wr it es inf or mat ion t o a f il e using a pr int f or mat
G printf, which f or mat s a st r ing and sends it t o a f il e
The f ol l owing sect ions br ief l y descr ibe t hese f unct ions again, al ong wit h some f eat ur es
of t hese f unct ions t hat have not been discussed pr eviousl y.
The open Function
The open f unct ion enabl es a Per l pr ogr am t o access a f il e. It associat es a special f il e
var iabl e wit h each accessed f il e. The f ol l owing is an exampl e:
open (MYVAR, "/u/jqpublic/file");
Her e, open r equest s access t o t he f il e /u/jqpublic/file, and it associat es t he f il e MYVAR
wit h t his f il e af t er it is open. open r et ur ns a nonzer o val ue if t he open succeeds, and
zer o if t he open f ail s.
By def aul t , open opens a f il e f or r eading onl y. To open a f il e f or wr it ing, put a >
char act er in f r ont of t he f il ename, as f ol l ows:
open (MYVAR, ">/u/jqpublic/file");
To append inf or mat ion t o an exist ing f il e, put t wo > char act er s in f r ont of t he f il ename,
as f ol l ows:
open (MYVAR, ">>/u/jqpublic/file");
To t r eat t he open f il e as a command t o which t o pipe dat a, put a pipe (|) char act er in
f r ont of t he f il ename, as f ol l ows:
open (MAIL, "|mail dave");
(For mor e inf or mat ion, r ef er t o Day 6, "Reading f r om and Wr it ing t o Fil es.")
Piping Input Using open
The open f unct ion enabl es you t o open f il es in sever al ot her ways not pr eviousl y
discussed. For exampl e, t o t r eat t he open f il e as a command t hat is piping dat a t o t his
pr ogr am, put a | char act er af t er t he f il ename. For exampl e:
open (CAT, "cat file*|");
This cal l t o open execut es t he command cat file*. This command cr eat es a t empor ar y
f il e consist ing of t he cont ent s of al l f il es whose name st ar t s wit h file; t hese cont ent s
ar e joined (concat enat ed) int o a singl e f il e. This f il e is t r eat ed as an input f il e t hat is
accessibl e using t he f il e var iabl e CAT.
$input = <CAT>;
List ing 12.1 is anot her exampl e of a pr ogr am t hat uses piped input . This pr ogr am uses t he
out put f r om t he w command t o l ist t he user s who ar e cur r ent l y l ogged on t o t he
machine.

List ing 12.1. A pr ogr am t hat r eceives input f r om a piped command.
1: #!/usr/local/bin/perl
2:
3: open (WOUT, "w|");
4: $time = <WOUT>;
5: $time =~ s/^ *//;
6: $time =~ s/ .*//;
7: <WOUT>; # skip headings line
8: @users = <WOUT>;
9: close (WOUT);
10: foreach $user (@users) {
11: $user =~ s/ .*//;
12: }
13: print ("Current time: $time");
14: print ("Users logged on:\n");
15: $prevuser = "";
16: foreach $user (sort @users) {
17: if ($user ne $prevuser) {
18: print ("\t$user");
19: $prevuser = $user;
20: }
21: }

$ program12_1
Current time: 4:25pm
Users logged on:
dave
kilroy
root
zarquon
$
The w command l ist s t he cur r ent t ime, t he machine l oad, and t he user s l ogged
ont o t he machine. It al so l ist s t he job t ime and t he cur r ent l y execut ing command f or
each user .
Her e is sampl e out put f or t he w command:
4:25pm up 1 day, 6:37, 6 users, load average: 0.79, 0.36, 0.28
User tty login@ idle JCPU PCPU what
dave ttyp0 2:26pm 27 3 w
kilroy ttyp1 9:01am 2:27 1:04 11 -csh
kilroy ttyp2 9:02am 43 1:46 27 rn
root ttyp3 4:22pm 2 -csh
zarquon ttyp4 1:26pm 4 43 16 cc myprog.c
kilroy ttyp5 9:03am 2:14 48 /usr/games/hack
This Per l pr ogr am t akes t he out put f r om t he w command and massages it t o r et r ieve onl y
t he inf or mat ion needed: t he cur r ent t ime and t he user s who ar e cur r ent l y l ogged on.
Line 3 st ar t s t he w command. The cal l t o open specif ies t hat t he out put f r om w is t o be
t r eat ed as input t o t his pr ogr am, and t hat t he f il e var iabl e WOUT is t o be used t o access
t his input .
Line 4 r eads t he f ir st l ine of t he input piped f r om WOUT. This is t he l ine r ead:
4:25pm up 1 day, 6:37, 6 users, load average: 0.79, 0.36, 0.28
The f ol l owing t wo l ines ext r act t he cur r ent t ime f r om t his l ine. Fir st , l ine 5 r emoves
t he l eading spaces. Then, l ine 6 r emoves ever yt hing af t er t he f ir st wor d, except f or t he
t r ail ing newl ine char act er . This l eaves t he t ime, 4:25pm, al ong wit h t he t r ail ing
newl ine, st or ed in $time.
Line 7 r eads t he second l ine f r om WOUT. Because t his l ine cont ains no usef ul inf or mat ion,
t her e is no need t o assign it t o any scal ar var iabl e.
Line 8 r eads t he r est of t he out put f r om w t o t he ar r ay var iabl e @users. Af t er t his
out put has been r ead, l ine 9 cl oses WOUT, which t er minat es t he pr ocess t hat is r unning
t he w command.
Each el ement of t he l ist st or ed in @users cont ains one l ine of user inf or mat ion. Because
t his pr ogr am needs onl y t he f ir st wor d of each l ine, l ines 10-12 get r id of ever yt hing
el se (except , again, f or t he t r ail ing newl ine char act er ). Af t er t his l oop is compl et e, t he
ar r ay in @users cont ains a l ist of user s l ogged on.
Line 13 pr int s t he cur r ent t ime, as st or ed in $time. Not e t hat print does not need t o
specif y a t r ail ing newl ine char act er , because $time cont ains one.
Lines 16-21 sor t t he l ist of user s in @users and pr int s t hem. Because a user can be l ogged
on mor e t han once, $prevuser st or es t he l ast user name pr int ed. The val ue st or ed in
$user is not pr int ed unl ess it is not t he same as t he val ue st or ed in $prevuser.
Redirecting One File to Another
Many UNIX shel l s enabl e you t o dir ect bot h t he st andar d out put f il e and t he st andar d
er r or f il e t o t he same out put f il e. For exampl e, in t he Bour ne shel l sh, t he command
$ foo >file1 2>&1
r uns t he command foo and st or es t he out put f r om t he st andar d out put f il e and t he
st andar d er r or f il e in file1.
List ing 12.2 shows how you can do t his in Per l .

List ing 12.2. A pr ogr am t hat r edir ect s t he st andar d out put and
st andar d er r or f il es.
1: #!/usr/local/bin/perl
2:
3: open (STDOUT, ">file1") || die ("open STDOUT failed");
4: open (STDERR, ">&STDOUT") || die ("open STDERR failed");
5: print STDOUT ("line 1\n");
6: print STDERR ("line 2\n");
7: close (STDOUT);
8: close (STDERR);

This pr ogr am pr oduces no out put .
The f ol l owing ar e t he cont ent s of t he out put f il e file1:
line 2
line 1
As you can see, t hese l ines ar en't in t he or der int ended. To under st and what is
happening, l et 's examine t his pr ogr am in mor e det ail .
Line 3 r edir ect s t he st andar d out put f il e. To do t his, it opens t he out put f il e file1 and
associat es it wit h t he f il e var iabl e STDOUT; t his cl oses t he st andar d out put f il e.
Line 4 r edir ect s t he st andar d er r or f il e. The ar gument >&STDOUT t el l s t he Per l
int er pr et er t o use t he f il e al r eady opened and associat ed wit h STDOUT. This means t hat
t he f il e var iabl e STDERR r ef er s t o t he same f il e as STDOUT.
Lines 5 and 6 wr it e t o STDOUT and STDERR, r espect ivel y. Because t hese f il e var iabl es r ef er
t o t he same f il e, bot h l ines ar e wr it t en t o file1. Unf or t unat el y, t hey ar e wr it t en in
t he wr ong or der . What has happened?
The pr obl em ar ises because of how UNIX handl es t he wr it ing of out put . When you use
print (or any ot her f unct ion) t o wr it e t o a f il e such as t he st andar d out put f il e, what
t he UNIX oper at ing syst em r eal l y does is copy t he out put t o a special int er nal st or age
ar ea cal l ed a buffer. (You can t hink of a buf f er as a giant char act er st r ing or as an
ar r ay of char act er s.) Subsequent out put oper at ions cont inue wr it ing t o t he buf f er
unt il it is f ul l ; when t he buf f er is f ul l , t he ent ir e buf f er is wr it t en out . Copying t o a
buf f er and t hen wr it ing out t he ent ir e buf f er t akes much l ess t ime t han wr it ing
individual l ines of t ext . (This is because, on most machines, input -out put oper at ions ar e
sl ower t han memor y-access oper at ions.)
When a pr ogr am ends, any non-empt y buf f er s ar e wr it t en out . However , t he syst em
maint ains separ at e buf f er s f or STDERR and STDOUT, and it wr it es out t he buf f er f or
STDERR f ir st . This means t hat line 2, which is st or ed in t he STDERR buf f er , appear s bef or e
line 1, which is st or ed in t he STDOUT buf f er .
To get ar ound t his pr obl em, you can t el l t he Per l int er pr et er not t o use a buf f er f or a
par t icul ar f il e. To do t his, do t he f ol l owing:
1. Sel ect t he f il e using t he select f unct ion.
2. Assign 1 t o t he syst em var iabl e $|.
The syst em var iabl e $| indicat es whet her a par t icul ar f il e is t o be buf f er ed (in ot her
wor ds, whet her it shoul d use a buf f er or not ). If $| is assigned a nonzer o val ue, no
buf f er is used. As wit h $~ and $^, assigning t o $| af f ect s t he cur r ent def aul t f il e, which
is t he f il e l ast specif ied in a cal l t o select (or STDOUT, if select has not been cal l ed).
List ing 12.3 shows how you can use $| t o ensur e t hat your out put l ines appear in t he
cor r ect or der .
List ing 12.3. A pr ogr am t hat r edir ect s st andar d input and out put and
t ur ns of f buf f er ing.
1: #!/usr/local/bin/perl
2:
3: open (STDOUT, ">file1") || die ("open STDOUT failed");
4: open (STDERR, ">&STDOUT") || die ("open STDERR failed");
5: $| = 1;
6: select (STDERR);
7: $| = 1;
8: print STDOUT ("line 1\n");
9: print STDERR ("line 2\n");
10: close (STDOUT);
11: close (STDERR);

This pr ogr am pr oduces no out put .
The cont ent s of t he out put f il e file1 ar e now t he f ol l owing:
line 1
line 2
Line 5 set s $| t o 1, which t el l s t he Per l int er pr et er t hat t he cur r ent def aul t f il e does
not need t o be buf f er ed. Because select has not yet been cal l ed, t he cur r ent def aul t
f il e is STDOUT, which means t hat l ine 5 t ur ns of f buf f er ing f or t he st andar d out put f il e
(which has been r edir ect ed t o file1).
Line 6 set s t he cur r ent def aul t f il e t o STDERR, and l ine 7 once again set s $| t o 1. This
t ur ns of f buf f er ing f or t he st andar d er r or f il e (which has al so been r edir ect ed t o
file1).
Because buf f er ing has been t ur ned of f f or bot h STDERR and STDOUT, l ines 8 and 9 wr it e t o
file1 r ight away. This means t hat t he out put l ines appear in file1 in t he or der in which
t hey ar e pr int ed.
Specifying Read and Write Access
To open a f il e f or bot h r ead and wr it e access, specif y +> bef or e t he f il ename, as f ol l ows:
open (READWRITE, "+>file1");
This opens t he f il e named file1 f or bot h r eading and wr it ing. This enabl es you t o
over wr it e por t ions of a f il e.
Opening a f il e f or r eading and wr it ing wor ks best in conjunct ion wit h t he l ibr ar y
f unct ions seek and tell, which enabl e you t o skip t o t he middl e of a f il e. (For mor e
inf or mat ion on seek and t el l , r ef er t o t he sect ion cal l ed "Skipping and Rer eading Dat a,"
l at er in t oday's l esson.)
NOTE
You al so can use +< as t he pr ef ix t o specif y bot h r eading
and wr it ing, as f ol l ows:
open (READWRITE, "+<file1");
The pr ef ix <, by it sel f , specif ies t hat t he f il e is t o be
opened f or r eading. This means t hat t he f ol l owing t wo
st at ement s ar e ident ical :
open (READONLY, "<read");
open (READONLY, "read")
The close Function
The l ibr ar y f unct ion close was discussed on Day 6, "Reading f r om and Wr it ing t o Fil es."
It cl oses a f il e opened by open, as f ol l ows:
close (MYFILE);
Her e, MYFILE is t he f il e var iabl e (passed t o open) t hat is associat ed wit h t he open f il e.
NOTE
If you use close t o cl ose a pipe, t he pr ogr am wil l wait
f or t he piped pr ogr am t o t er minat e. For exampl e:
open (MYPIPE, "cat file*|");
close (MYPIPE);
When close is cal l ed, t he pr ogr am suspends execut ion
unt il t he command cat file* is t er minat ed
The print, printf, and write Functions
The print, printf, and write f unct ions have been cover ed al so in pr evious chapt er s, but
I'l l br ief l y r ecap t hem her e.
The print f unct ion is t he simpl est f unct ion. It wr it es t o t he f il e specif ied, or t o t he
cur r ent def aul t f il e if no f il e is specif ied. For exampl e:
print ("Hello, there!\n");
print OUTFILE ("Hello, there!\n");
The f ir st st at ement wr it es t o t he cur r ent def aul t f il e (which is STDOUT unl ess select
has been cal l ed). The second st at ement wr it es t o t he f il e specif ied by OUTFILE.
The printf f unct ion f or mat s a st r ing and sends it t o eit her t he f il e specif ied or t he
cur r ent def aul t f il e. For exampl e, t he st at ement
printf OUTFILE ("You owe me %8.2f", $owing);
t akes t he val ue st or ed in $owing and subst it ut es it f or %8.2f in t he specif ied st r ing.
%8.2f is an exampl e of a field specifier and indicat es t hat t he val ue st or ed in $owing is t o
be t r eat ed as a f l oat ing-point number .
The write f unct ion uses a pr int f or mat t o send f or mat t ed out put t o t he f il e t hat is
specif ied or t o t he cur r ent def aul t f il e. For exampl e:
select (OUTFILE);
$~ = "MYFORMAT";
write;
This cal l t o write uses t he pr int f or mat MYFORMAT t o send out put t o t he f il e OUTFILE.
For mor e inf or mat ion on printf or write, r ef er t o Day 11, "For mat t ing Your Out put ."
The select Function
The select f unct ion al so is cover ed on Day 11. This f unct ion is passed a f il e var iabl e,
which becomes t he new cur r ent def aul t f il e. For exampl e:
select (MYFILE);
In t his case, MYFILE is now t he cur r ent def aul t f il e, which means t hat cal l s t o print,
write, and printf wr it e t o MYFILE unl ess a f il e var iabl e is expl icit l y specif ied.
The eof Function
The l ibr ar y f unct ion eof checks whet her t he l ast input f il e r ead has been exhaust ed. If
al l of t he input has been r ead, eof r et ur ns a nonzer o val ue. If t her e is input r emaining,
eof r et ur ns zer o.
The eof f unct ion was f ir st int r oduced on Day 6. You might have not iced t hat , on t hat
day, t he exampl es t hat use eof use it wit hout par ent heses. This is because t he behavior
of eof is a l it t l e t r icky if you ar e using it in conjunct ion wit h t he <> oper at or ; in t his
case, eof and eof() behave dif f er ent l y.
List ing 12.4 shows how eof int er act s wit h <>. It pr int s t he cont ent s of one or mor e input
f il es whose names ar e suppl ied on t he command l ine. A l ine of dashes is pr int ed af t er
each input f il e is compl et ed.
To r un t his pr ogr am your sel f , cr eat e t wo f il es named file1 and file2. Put t he
f ol l owing in file1:
This is a line from the first file.
Here is the last line of the first file.
Then, put t he f ol l owing in file2:
This is a line from the second and last file.
Here is the last line of the last file.
Final l y, specif y file1 and file2 on t he command l ine when you r un t his pr ogr am. For
exampl e, if you have cal l ed t his pr ogr am program 12_4, r un it as f ol l ows:
$ program12_4 file1 file2
This wil l give you t he out put shown in t he input -out put exampl e.

List ing 12.4. A pr ogr am t hat uses eof and <> t oget her .
1: #!/usr/local/bin/perl
2:
3: while ($line = <>) {
4: print ($line);
5: if (eof) {
6: print ("-- end of current file --\n");
7: }
8: }

$ program12_4 file1 file2
This is a line from the first file.
Here is the last line of the first file.
-- end of current file --
This is a line from the second and last file.
Here is the last line of the last file.
-- end of current file --
$
The <> oper at or in l ine 3 t el l s t he pr ogr am t o r ead t he next l ine of input
f r om t he input f il es suppl ied on t he command l ine. Line 4 t hen pr int s t he l ine.
Line 5 cal l s eof wit hout par ent heses. This is t he f or m of eof t hat you ar e f amil iar wit h.
It r et ur ns t r ue if t he cur r ent input f il e has been compl et el y r ead.
When you t est f or end-of -f il e, use eit her eof or eof()
but not bot h
Compar e t he pr ogr am in List ing 12.4 wit h List ing 12.5, which uses eof() inst ead of eof.

List ing 12.5. A pr ogr am t hat uses eof() and <> t oget her .
1: #!/usr/local/bin/perl
2:
3: while ($line = <>) {
4: print ($line);
5: if (eof()) {
6: print ("-- end of output --\n");
7: }
8: }

$ program12_5 file1 file2
This is a line from the first file.
Here is the last line of the first file.
This is a line from the second and last file.
Here is the last line of the last file.
-- end of output --
$
Line 5 of t his pr ogr am cal l s eof wit h par ent heses. Cal l s t o eof wit h
par ent heses onl y r et ur n t r ue when al l of t he f il es have been r ead. If t he pr ogr am is at
t he end of t he f ir st input f il e, eof() r et ur ns f al se because t her e is st il l input t o be r ead.
NOTE
If you l ike, you can use eof wit h a par t icul ar f il e. For
exampl e:
if (eof(MYFILE)) {
# do end-of-file stuff
}
Her e, t he condit ional expr ession r et ur ns t r ue if al l of
MYFILE has been r ead.
Al so, not e t hat t he dist inct ion bet ween eof and eof() is
onl y meaningf ul when you ar e using t he <> oper at or . If
you ar e just r eading f r om a singl e f il e, it doesn't mat t er
whet her you suppl y par ent heses or not . For exampl e:
while ($line = <STDIN>) {
# stuff goes here
if (eof) { # you can also use eof() here
# more stuff here
}
}
Indirect File Variables
When you cal l any of t he f unct ions descr ibed so f ar in t oday's l esson, you can indicat e
which f il e t o use by specif ying a f il e var iabl e. However , t hese f unct ions al so enabl e you
t o suppl y a scal ar var iabl e in pl ace of a f il e var iabl e; when you do, t he Per l int er pr et er
t r eat s t he val ue st or ed in t he scal ar var iabl e as t he name of t he f il e var iabl e. For
exampl e, consider t he f ol l owing:
$filename = "MYFILENAME";
open ($filename, ">file1");
This cal l t o open t akes t he val ue st or ed in $filename-MYFILENAME-and uses it as t he f il e-
var iabl e name. This means t hat t he f il e var iabl e MYFILENAME is now associat ed wit h t he
out put f il e file1.
List ing 12.6 is an exampl e of a pr ogr am t hat st or es a f il e-var iabl e name in a scal ar
var iabl e and passes t he l ibr ar y var iabl e t o Per l input and out put f unct ions.

List ing 12.6. A pr ogr am t hat uses a scal ar var iabl e t o st or e a f il e
var iabl e name.
1: #!/usr/local/bin/perl
2:
3: &open_file("INFILE", "", "file1");
4: &open_file("OUTFILE", ">", "file2");
5: while ($line = &read_from_file("INFILE")) {
6: &print_to_file("OUTFILE", $line);
7: }
8:
9: sub open_file {
10: local ($filevar, $filemode, $filename) = @_;
11:
12: open ($filevar, $filemode . $filename) ||
13: die ("Can't open $filename");
14: }
15: sub read_from_file {
16: local ($filevar) = @_;
17:
18: <$filevar>;
19: }
20: sub print_to_file {
21: local ($filevar, $line) = @_;
22:
23: print $filevar ($line);
24: }

This pr ogr am pr oduces no out put .
This pr ogr am is just a f ancy way of copying t he cont ent s of file1 t o file2.
Line 3 opens t he input f il e, file1, f or r eading by cal l ing t he subr out ine open_file. This
subr out ine is passed t he name of t he f il e var iabl e t o use, which is INFILE.
Line 4 uses t he same subr out ine, open_file, t o open t he out put f il e, file2, f or wr it ing.
The f il e var iabl e OUTFILE is used in t his open oper at ion.
Line 5 cal l s read_from_file t o r ead a l ine of input and passes it t he f il e var iabl e name
INFILE. Line 18 subst it ut es t he val ue of $filevar, INFILE, int o <$filevar>, yiel ding t he
r esul t <INFILE>; t hen, it r eads a l ine f r om t his input f il e. Because t his l ine-r eading
oper at ion is t he l ast expr ession eval uat ed in t he subr out ine, t he l ine r ead is r et ur ned by
t he subr out ine and assigned t o $line.
Line 6 t hen passes OUTFILE and t he input l ine just r ead t o t he subr out ine print_to_file.
NOTE
Al l of t he f unct ions you've seen so f ar in t his chapt er -
open, close, print, printf, write, select, and eof-enabl e
you t o use a scal ar var iabl e in pl ace of a f il e var iabl e.
The f unct ions open, close, write, select, and eof al so
enabl e you t o use an expr ession in pl ace of a f il e
var iabl e. The val ue of t he expr ession must be a
char act er st r ing t hat can be used as a f il e var iabl e
Skipping and Rereading Data
In t he pr ogr ams you've seen so f ar ,i nput f il es have al ways been r ead in or der , st ar t ing
wit h t he f ir st l ine of input and cont inuing on t o t he end. Per l pr ovides t wo special
f unct ions, seek and tell, which enabl e you t o skip f or war d or backwar d in a f il e so t hat
you can skip or r e-r ead dat a.
The seek Function
The seek f unct ion moves backwar d or f or war d in a f il e.
The synt ax f or t he seek f unct ion is
seek (filevar, distance, relative_to);
As you can see, seek r equir es t hr ee ar gument s:
G filevar, which is t he f il e var iabl e r epr esent ing t he f il e in which t o skip
G distance, which is an int eger r epr esent ing t he number of byt es (char act er s) t o skip
G relative_to, which is eit her 0, 1, or 2
If relative_to is 0, t he number of byt es t o skip is r el at ive t o t he beginning of t he f il e. If
relative_to is 1, t he skip is r el at ive t o t he cur r ent posit ion in t he f il e (t he cur r ent
posit ion is t he l ocat ion of t he next l ine t o be r ead). If relative_to is 2, t he skip is
r el at ive t o t he end of t he f il e.
For exampl e, t o skip back t o t he beginning of t he f il e MYFILE, use t he f ol l owing:
seek(MYFILE, 0, 0);
The f ol l owing st at ement skips f or war d 80 byt es:
seek(MYFILE, 80, 1);
The f ol l owing st at ement skips backwar d 80 byt es:
seek(MYFILE, -80, 1);
And t he f ol l owing st at ement skips t o t he end of t he f il e (which is usef ul when t he f il e
has been opened f or r eading and wr it ing):
seek(MYFILE, 0, 2);
The seek f unct ion r et ur ns t r ue (nonzer o) if t he skip was successf ul , and 0 if it f ail ed. It
is of t en used in conjunct ion wit h t he tell f unct ion, descr ibed in t he next sect ion.
The tell Function
The tell f unct ion r et ur ns t he dist ance, in byt es, bet ween t he beginning of t he f il e and
t he cur r ent posit ion of t he f il e (t he l ocat ion of t he next l ine t o be r ead).
The synt ax f or t he tell f unct ion is
tell (filevar);
filevar, which is r equir ed, r epr esent s t he f il e whose cur r ent posit ion is needed.
For exampl e, t he f ol l owing st at ement r et r ieves t he cur r ent posit ion of t he f il e MYFILE:
$offset = tell (MYFILE);
NOTE
tell and seek accept an expr ession in pl ace of a f il e
var iabl e, pr ovided t he val ue of t he expr ession is t he
name of a f il e var iabl e
You can use tell and seek t o skip t o a par t icul ar posit ion in a f il e. For exampl e, List ing
12.7 uses t hese f unct ions t o pr int pair s of l ines t wice each. (This is, of cour se, not t he
f ast est way t o do t his.)

List ing 12.7. A pr ogr am t hat demonst r at es seek and tell.
1: #!/usr/local/bin/perl
2:
3: @array = ("This", "is", "a", "test");
4: open (TEMPFILE, ">file1");
5: foreach $element (@array) {
6: print TEMPFILE ("$element\n");
7: }
8: close (TEMPFILE);
9: open (TEMPFILE, "file1");
10: while (1) {
11: $skipback = tell(TEMPFILE);
12: $line = <TEMPFILE>;
13: last if ($line eq "");
14: print ($line);
15: $line = <TEMPFILE>; # assume the second line exists
16: print ($line);
17: seek (TEMPFILE, $skipback, 0);
18: $line = <TEMPFILE>;
19: print ($line);
20: $line = <TEMPFILE>;
21: print ($line);
22: }

$ program12_7
This
is
This
is
a
test
a
test
$
Lines 3-8 of t his pr ogr am cr eat e a t empor ar y f il e named file1 consist ing of
f our l ines: This, is, a, and test. Line 9 opens t his t empor ar y f il e f or r eading.
Lines 10-22 l oop t hr ough t he t est f il e. Line 11 cal l s tell t o obt ain t he cur r ent posit ion
of t he f il e bef or e r eading t he pair of l ines. Lines 12-16 r ead t he l ines and pr int t hem
(f ir st t est ing whet her t he end of t he f il e has been r eached).
Line 17 t hen cal l s seek, which posit ions t he f il e at t he point r et ur ned by tell in l ine 11.
This means t hat t he pair of l ines r ead by l ines 12 and 15 ar e r ead again by l ines 18 and 20.
Ther ef or e, l ines 19 and 21 pr int a second copy of t he input l ines.
NOTE
You cannot use seek and tell if t he f il e var iabl e
act ual l y r ef er s t o a pipe. For exampl e, if you open a pipe
using t he st at ement
open (MYPIPE, "cat file*|");
t hen t he f ol l owing st at ement makes no sense:
$illegal = tell (MYPIPE)
System Read and Write Functions
In Per l , t he easiest way t o r ead input f r om a f il e is t o use t he <filevar> oper at or , wher e
filevar is t he f il e var iabl e r epr esent ing t he f il e t o r ead. Per l al so pr ovides t wo ot her
f unct ions t hat r ead f r om an input f il e:
G read, which is equival ent t o t he UNIX fread f unct ion
G sysread, which is equival ent t o t he read f unct ion
Per l al so enabl es you t o wr it e out put using t he buil t -in f unct ion syswrite, which cal l s
t he UNIX write f unct ion.
These f unct ions ar e descr ibed in t he f ol l owing sect ions.
The read Function
The read f unct ion is designed t o be equival ent t o t he UNIX f unct ion fread. It enabl es
you t o r ead an ar bit r ar y number of char act er s (byt es) int o a scal ar var iabl e.
The synt ax f or t he read f unct ion is
read (filevar, result, length, skipval);
Her e, filevar is t he f il e var iabl e r epr esent ing t he f il e t o r ead, result is t he scal ar
var iabl e (or ar r ay var iabl e el ement ) int o which t he byt es ar e t o be st or ed, and length is
t he number of byt es t o r ead.
skipval is an opt ional ar gument which specif ies t he number of byt es t o skip bef or e
r eading.
For exampl e:
read (MYFILE, $scalar, 80);
This cal l t o read t r ies t o r ead 80 byt es f r om t he f il e r epr esent ed by t he f il e var iabl e
MYFILE, st or ing t he r esul t ing char act er st r ing in $scalar. It r et ur ns t he number of
byt es act ual l y r ead; if MYFILE is at end-of -f il e, it r et ur ns 0 (read r et ur ns t he nul l
st r ing if an er r or occur s).
You can use read t o append t o an exist ing scal ar var iabl e by specif ying a f our t h
ar gument , which indicat es t he number of byt es t o skip in t he scal ar var iabl e.
read (MYFILE, $scalar, 40, 80);
This cal l t o read r eads anot her 40 byt es f r om MYFILE. When copying t hese byt es int o
$scalar, read f ir st skips t he f ir st 80 byt es al r eady st or ed t her e.
The sysread and syswrite Functions
If you want t o r ead dat a as quickl y as possibl e, you can cal l sysread inst ead of read.
The synt ax f or t he sysread f unct ion is
sysread (filevar, result, length, skipval);
These ar gument s ar e t he same as f or read.
For exampl e:
sysread (MYFILE, $scalar, 80);
sysread (MYFILE, $scalar, 40, 80);
sysread is equival ent t o t he UNIX f unct ion read. The ar gument s t o sysread ar e t he same
as t hose f or t he Per l read f unct ion.
To wr it e as quickl y as possibl e, cal l t he syswrite f unct ion, which is equival ent t o t he
UNIX f unct ion write.
The synt ax of t he syswrite f unct ion is
syswrite (filevar, data, length, skipval);
Her e, filevar is t he f il e t o wr it e t o, data is t he pl ace wher e t he dat a is l ocat ed, length
is t he number of byt es t o wr it e, and skipval is t he number of byt es t o skip bef or e wr it ing.
For inst ance, t he f ol l owing cal l wr it es t he f ir st 80 byt es of $scalar t o t he f il e specif ied
by MYFILE:
syswrite (MYFILE, $scalar, 80);
Simil ar l y, t he f ol l owing st at ement skips t he f ir st 80 byt es st or ed in $scalar, and t hen
wr it es t he next 40 byt es t o t he f il e specif ied by MYFILE:
syswrite (MYFILE, $scalar, 40, 80);
Don't use sysread and syswrite unl ess you know what
you ar e doing. For mor e inf or mat ion on t hese f unct ions,
r ef er t o t he UNIX syst em manual pages f or t he read and
write f unct ions
Reading Characters Using getc
Per l pr ovides one ot her buil t -in f unct ion, getc, which r eads a singl e char act er of input
f r om a f il e.
The synt ax f or cal l s t o t he getc f unct ion is
char = getc (infile);
infile is t he f il e f r om which t o r ead, and char is t he char act er r et ur ned.
For exampl e:
$singlechar = getc(INFILE);
This st at ement r eads a char act er f r om t he f il e r epr esent ed by INFILE and st or es it (as a
char act er st r ing) in t he scal ar var iabl e $singlechar.
The getc is usef ul f or "hot key" appl icat ions. These appl icat ions accept and pr ocess input
one char act er at a t ime r at her t han one l ine at a t ime. List ing 12.8 is an exampl e of such
a pr ogr am. It r eads one char act er at a t ime and checks whet her t he char act er is
al phanumer ic. If it is, it wr it es out t he next higher l et t er or number . For exampl e, when
you ent er a, t he pr ogr am pr int s out b, and so on. In t his exampl e, t he al phabet ic l et t er s a
t hr ough z and t he digit s 0 t hr ough 9 ar e t yped in.

List ing 12.8. A pr ogr am t hat demonst r at es t he use of getc.
1: #!/usr/local/bin/perl
2:
3: &start_hot_keys;
4: while (1) {
5: $char = getc(STDIN);
6: last if ($char eq "\\");
7: $char =~ tr/a-zA-Z0-9/b-zaB-ZA1-90/;
8: print ($char);
9: }
10: &end_hot_keys;
11: print ("\n");
12:
13: sub start_hot_keys {
14: system ("stty cbreak");
15: system ("stty -echo");
16: }
17:
18: sub end_hot_keys {
19: system ("stty -cbreak");
20: system ("stty echo");
21: }

$ program12_8
bcdefghijklmnopqrstuvwxyza1234567890
$
The subr out ine start_hot_keys modif ies t he r unt ime envir onment t o suppor t
hot -key input . To do t his, it uses t wo cal l s t o t he buil t -in f unct ion system, which simpl y
t akes it s ar gument and execut es it . The command stty cbreak t el l s t he syst em t o pr ocess
input one char act er at a t ime, and t he command stty -echo t el l s t he syst em not t o
displ ay char act er s t yped at t he keyboar d.
NOTE
Some machines might not suppor t hot keys or might use
dif f er ent commands t o est abl ish t he hot -key
envir onment . If you ar e on a machine t hat uses dif f er ent
commands t o est abl ish t he envir onment , you st il l can
r un t his pr ogr am; just change t he stty commands t o
what ever wor ks on your machine
The l oop in l ines 4-9 r eads and wr it es one char act er per l oop it er at ion. Line 5 st ar t s of f
by r eading a char act er f r om t he st andar d input f il e using getc.
Line 6 t est s whet her t he char act er r ead is a backsl ash. If it is, t he l oop t er minat es. If
t he char act er is not a backsl ash, t he pr ogr am cont inues wit h l ine 7. This l ine t r ansl at es
al l al phanumer ic char act er s t o t he next -highest l et t er or number ; f or exampl e, it
t r ansl at es g t o h, E t o F, and 7 t o 8. The char act er s z, Z, and 9 ar e t r ansl at ed t o a, A, and
0, r espect ivel y.
Line 8 pr int s out t he t r ansl at ed char act er . Because t he char act er s you t ype at t he
keyboar d ar e not displ ayed, t he pr ogr am makes it l ook l ike your keyboar d is
mal f unct ioning. (It 's quit e disor ient ing!)
The subr out ine end_hot_keys r est or es t he nor mal wor king envir onment by undoing t he
syst em cal l s t hat ar e per f or med by start_hot_keys.
If you ar e using hot keys, when you cl ean up make sur e
you cal l stty-cbreak before cal l ing stty echo. If you
cal l stty echo f ir st , your t er minal might wind up not
pr int ing newl ine char act er s pr oper l y
Reading a Binary File Using binmode
If your machine dist inguishes bet ween t ext f il es and binar y f il es (f il es t hat cont ain
unpr int abl e char act er s), your Per l pr ogr am can t el l t he syst em t hat a par t icul ar f il e is
a binar y f il e. To do t his, cal l t he buil t -in f unct ion binmode.
The synt ax f or cal l ing t he binmode f unct ion is
binmode (filevar);
filevar is a f il e var iabl e.
binmode expect s a f il e var iabl e (or an expr ession whose val ue is t he name of a f il e
var iabl e). It must be cal l ed af t er t he f il e is opened, but bef or e t he f il e is r ead.
The f ol l owing is an exampl e of a cal l t o binmode:
binmode (MYFILE);
NOTE
Nor mal l y, you won't need t o use t his f unct ion unl ess
you ar e r unning in a DOS-l ike envir onment
Directory-Manipulation Functions
The input and out put f unct ions t hat you have seen ear l ier r ead and wr it e dat a t o f il es.
Per l al so pr ovides a gr oup of f unct ions t hat enabl e you t o manipul at e UNIX dir ect or ies.
Funct ions exist t hat enabl e you t o cr eat e, r ead, open, cl ose, del et e, and skip ar ound in
dir ect or ies. The f ol l owing sect ions descr ibe t hese f unct ions.
The mkdir Function
To cr eat e a new dir ect or y, cal l t he f unct ion mkdir.
The synt ax f or t he mkdir f unct ion is
mkdir (dirname, permissions);
mkdir r equir es t wo ar gument s:
G dirname, which is t he name of t he dir ect or y t o be cr eat ed (which can be a
char act er st r ing or an expr ession whose val ue is a dir ect or y name)
G permissions, which is an oct al (base-8) number specif ying t he access per missions f or
t he new dir ect or y
For exampl e, t o cr eat e a dir ect or y named /u/jqpublic/newdir, you can use t he
f ol l owing st at ement :
mkdir ("/u/jqpublic/newdir", 0777);
To cr eat e a subdir ect or y of t he cur r ent wor king dir ect or y, just specif y t he new
dir ect or y name, as f ol l ows:
mkdir ("newdir", 0777);
If t he cur r ent wor king dir ect or y is /u/janedoe/mydir, t his cr eat es a subdir ect or y named
/u
/janedoe/mydir/newdir.
The per missions val ue of 0777 in bot h t hese exampl es gr ant s r ead, wr it e, and execut e
per missions t o ever ybody. Tabl e 12.1 l ist s each possibl e access per mission and t he oct al
number associat ed wit h it .
Tabl e 12.1. Access per missions f or t he mkdir f unct ion.
Val ue Per mission
4000
Set user ID on execut ion
2000
Set gr oup ID on execut ion
1000
St icky bit (see t he UNIX chmod
manual page)
0400
Read per mission f or f il e owner
0200
Wr it e per mission f or f il e owner
0100
Execut e per mission f or f il e owner
0040
Read per mission f or owner 's gr oup
0020
Wr it e per mission f or owner 's gr oup
0010
Execut e per mission f or owner 's gr oup
0004
Read per mission f or wor l d
0002
Wr it e per mission f or wor l d
0001
Execut e per mission f or wor l d
You can combine access per missions by adding (or doing a l ogical OR oper at ion on) t he
appr opr iat e oct al val ues in t he t abl e. For exampl e, t o gr ant r ead, wr it e, and execut e
per mission t o t he owner but onl y r ead per mission t o ever ybody el se, specif y 0744 as t he
per mission val ue.
NOTE
Al l of t he per mission val ues shown her e ar e in oct al
not at ion, because a l eading zer o is specif ied. If you l ike,
you can use decimal or hexadecimal her e, but it won't be
as easy t o r ead.
Al so not e t hat t he per mission val ue set her e is af f ect ed
by t he cur r ent val ue of umask. See t he descr ipt ion of t he
umask f unct ion l at er t oday f or mor e inf or mat ion
mkdir r et ur ns t r ue (nonzer o) if t he dir ect or y is successf ul l y cr eat ed. It r et ur ns f al se
(0) if t he dir ect or y is not .
The chdir Function
To set a dir ect or y t o be t he cur r ent wor king dir ect or y, use t he f unct ion chdir.
The synt ax f or t he chdir f unct ion is
chdir (dirname);
dirname is t he name of t he new cur r ent wor king dir ect or y.
chdir r et ur ns t r ue if t he cur r ent dir ect or y is set pr oper l y, f al se if an er r or occur s.
For exampl e, t o set t he cur r ent wor king dir ect or y t o /u/jqpublic/newdir, use t he
f ol l owing st at ement :
chdir ("/u/jqpublic/newdir");
NOTE
As wit h mkdir, t he dir ect or y name passed t o chdir can be
eit her a char act er st r ing or an expr ession whose val ue is
a dir ect or y name. For exampl e, t he f ol l owing set s t he
cur r ent dir ect or y t o be /u/jqpublic/newdir:
$dir = "/u/jqpublic/";
chdir ($dir . "newdir")
The opendir Function
You can have your pr ogr am examine a l ist of t he f il es cont ained in a dir ect or y. To do
t his, t he f ir st st ep is t o cal l t he buil t -in f unct ion opendir.
The synt ax f or t he opendir f unct ion is
opendir (dirvar, dirname);
dirvar is t he name t he pr ogr am is t o use t o r epr esent t he dir ect or y, al so known as a
directory variable, and dirname is t he name of t he dir ect or y t o open (which can be a
char act er st r ing or t he val ue of an expr ession).
opendir r et ur ns t r ue if t he open oper at ion is successf ul , and it r et ur ns f al se ot her wise.
For exampl e, t o open t he dir ect or y named /u/janedoe/mydir, you can use t he f ol l owing
st at ement :
opendir (DIR, "/u/janedoe/mydir");
This associat es t he dir ect or y var iabl e DIR wit h t he opened dir ect or y.
NOTE
If you l ike, you can use t he same name as bot h a
dir ect or y var iabl e and a f il e var iabl e.
opendir (MYNAME, "/u/jqpublic/dir");
open (MYNAME, "/u/jqpublic/dir/file");
The Per l int er pr et er al ways can t el l f r om cont ext
whet her a name is being used as a dir ect or y var iabl e or
as a f il e var iabl e. (However , t her e is no r eal r eason t o
do so. Your pr ogr ams wil l be easier t o r ead if you use
dif f er ent names t o r epr esent f il es and dir ect or ies.
The closedir Function
To cl ose an opened dir ect or y, cal l t he closedir f unct ion.
The synt ax f or t he closedir f unct ion is
closedir (mydir);
closedir expect s one ar gument : t he dir ect or y var iabl e associat ed wit h t he dir ect or y t o
be cl osed.
The readdir Function
Af t er opendir has opened a dir ect or y, you can access t he name of each f il e or
subdir ect or y st or ed in t he dir ect or y by cal l ing t he f unct ion readdir.
The synt ax f or t he readdir f unct ion is
readdir (mydir);
Like closedir, readdir is passed t he dir ect or y var iabl e t hat is associat ed wit h t he open
dir ect or y.
If t he val ue r et ur ned f r om readdir is assigned t o a scal ar var iabl e, readdir r et ur ns t he
name of t he f ir st f il e or subdir ect or y st or ed in t he dir ect or y. For exampl e:
$filename = readdir(MYDIR);
The f ir st name is r et ur ned al so if t he r et ur n val ue f r om readdir is assigned t o an
el ement of an ar r ay var iabl e. For exampl e:
$filearray[3] = readdir(MYDIR);
$filearray{"foo"} = readdir(MYDIR);
If readdir is cal l ed again, it r et ur ns t he next name in t he dir ect or y; subsequent cal l s
r et ur n ot her names, cont inuing unt il t he dir ect or y is exhaust ed. List ing 12.9 uses
readdir t o l ist t he f il es and subdir ect or ies in a dir ect or y.

List ing 12.9. A pr ogr am t hat l ist s t he f il es and subdir ect or ies in a
dir ect or y.
1: #!/usr/local/bin/perl
2:
3: opendir(HOMEDIR, "/u/jqpublic") ||
4: die ("Unable to open directory");
5: while ($filename = readdir(HOMEDIR)) {
6: print ("$filename\n");
7: }
8: closedir(HOMEDIR);

$ program12_9
.
..
.cshrc
.Xresources
.xsession
test
bin
letter
file1
$
Line 3 opens t he dir ect or y /u/jqpublic, which is t he home dir ect or y f or user
jqpublic. The opendir f unct ion associat es t he dir ect or y var iabl e HOMEDIR wit h
/u/jqpublic.
Lines 5-7 r ead t he name of each f il e in t he dir ect or y in t ur n. Line 6 pr int s each f il ename
as it is r ead in.
Not e t hat , on a UNIX syst em, t he l ist of names incl udes t wo special f il es:
G The name . (a singl e per iod), which r epr esent s t he cur r ent dir ect or y
G The name .. (t wo per iods), which r epr esent s t he par ent dir ect or y
As you can see, readdir r eads t he names in t he or der in which t hey appear in t he
dir ect or y.
List ing 12.10 shows how you can displ ay t he names in al phabet ical or der .

List ing 12.10. A pr ogr am t hat l ist s t he f il es and subdir ect or ies in a
dir ect or y in al phabet ical or der .
1: #!/usr/local/bin/perl
2:
3: opendir(HOMEDIR, "/u/jqpublic") ||
4: die ("Unable to open directory");
5: @files = readdir(HOMEDIR);
6: closedir(HOMEDIR);
7: foreach $file (sort @files) {
8: print ("$file\n");
9: }

$ program12_10
.
..
.Xresources
.cshrc
.xsession
bin
file1
letter
test
$
The readdir f unct ion behaves dif f er ent l y when it s r et ur n val ue is assigned
t o an ar r ay; in t his case, t he ent ir e l ist of f il es and subdir ect or ies in t he dir ect or y is
assigned t o t he ar r ay var iabl e @files by l ine 5.
Af t er t he ent ir e l ist is st or ed, sort can be cal l ed t o sor t t he l ist int o al phabet ical
or der . The foreach l oop in l ines 7-9 t hen pr int s t he sor t ed l ist one name at a t ime.
The telldir and seekdir Functions
As you've seen, t he l ibr ar y f unct ions tell and seek enabl e you t o skip backwar d and
f or war d in a f il e. Simil ar l y, t he l ibr ar y f unct ions telldir and seekdir enabl e you t o
skip backwar d and f or war d in a l ist of dir ect or ies.
To use telldir, pass it t he dir ect or y var iabl e def ined by opendir. telldir r et ur ns t he
cur r ent dir ect or y l ocat ion (wher e you ar e in t he l ist of f il es).
The synt ax f or t he telldir f unct ion is
location = telldir (mydir);
Her e, mydir is t he dir ect or y var iabl e cor r esponding t o t he dir ect or y whose f il e l ist you
ar e examining, and location is assigned t he cur r ent dir ect or y l ocat ion.
To skip t o t he dir ect or y l ocat ion r et ur ned by telldir, cal l seekdir.
The synt ax f or t he seekdir f unct ion is
seekdir(mydir, location);
This cal l t o seekdir set s t he cur r ent dir ect or y l ocat ion t o t he l ocat ion specif ied by
location.
seekdir wor ks onl y wit h dir ect or y l ocat ions r et ur ned
by telldir
The rewinddir Function
Al t hough being abl e t o skip anywher e you l ike in a dir ect or y l ist is usef ul , t he most
common skipping oper at ion in dir ect or y l ist s is rewinding t he dir ect or y l ist , or st ar t ing
over again. Because of t his, Per l pr ovides a special f unct ion, rewinddir, t hat handl es
t he r ewind oper at ion.
The synt ax f or t he rewinddir f unct ion is
rewinddir (mydir);
rewinddir set s t he cur r ent dir ect or y l ocat ion t o t he beginning of t he l ist of f il es,
which l et s you r ead t he ent ir e l ist of f il es again. As wit h t he ot her dir ect or y f unct ions,
mydir is t he dir ect or y var iabl e def ined by opendir.
The rmdir Function
The f inal dir ect or y f unct ion suppl ied by Per l is rmdir, which del et es an empt y dir ect or y.
The synt ax f or cal l ing t he rmdir f unct ion is
rmdir (dirname);
rmdir r et ur ns t r ue (nonzer o) if t he dir ect or y dirname is del et ed successf ul l y, and f al se
if t he dir ect or y is not empt y or cannot be del et ed.
File-Attribute Functions
Per l pr ovides sever al l ibr ar y f unct ions t hat modif y t he at t r ibut es or behavior of f il es.
These f unct ions can be divided int o t he f ol l owing gr oups:
G Funct ions t hat r el ocat e (r ename or del et e) f il es
G Funct ions t hat est abl ish l inks or symbol ic l inks
G Funct ions t hat modif y f il e per missions
G Ot her f il e-at t r ibut e f unct ions
These gr oups of f unct ions ar e descr ibed in t he f ol l owing sect ions.
File-Relocation Functions
Per l pr ovides t he f ol l owing f il e-r el ocat ion f unct ions:
G rename, which moves or r enames a f il e
G unlink, which del et es a f il e
The rename Function
The buil t -in f unct ion rename changes t he name of a f il e.
The synt ax f or t he rename f unct ion is
rename (oldname, newname);
oldname is t he ol d f il ename, and newname is t he new f il ename.
The rename f unct ion r et ur ns t r ue if t he r ename succeeds, and f al se if an er r or occur s.
For exampl e, t o change a f il e named name1 t o name2, use t he f ol l owing:
rename ("name1", "name2");
You can use t he val ue st or ed in a scal ar var iabl e as an ar gument t o rename, or any
var iabl e or expr ession whose val ue is a char act er st r ing, as f ol l ows:
rename ($oldname, &get_new_name);
You can al so use rename t o move a f il e f r om one dir ect or y t o anot her (pr ovided bot h
dir ect or ies ar e in t he same f il e syst em). For exampl e:
rename ("/u/jqpublic/name1", "/u/janedoe/name2");
NOTE
When rename moves a f il e, as in
rename ("name1", "name2");
it does not check whet her a f il e named name2 al r eady
exist s. Any exist ing name2 is dest r oyed by t he rename
oper at ion.
To get ar ound t his pr obl em, use t he -e f il e-t est oper at or ,
which checks whet her a named f il e exist s, as f ol l ows:
-e "name2" || rename (name1, name2);
Her e, t he || oper at or ensur es t hat rename is cal l ed onl y
when no f il e named name2 al r eady exist s
The unlink Function
To del et e a f il e, use t he unlink f unct ion.
The synt ax f or t he unlink f unct ion is
num = unlink (filelist);
This f unct ion t akes a l ist as it s ar gument and del et es al l t he f il es named in t hat l ist .
unlink r et ur ns t he number of f il es act ual l y del et ed.
The f ol l owing is an exampl e of a cal l t o unlink:
@deletelist = ("file1", "file2");
unlink (@deletelist);
The f unct ion is cal l ed unlink, inst ead of delete, because what it is act ual l y doing is
r emoving a r ef er ence, or link, t o t he par t icul ar f il e. See t he f ol l owing sect ion f or mor e
det ail s on l inks in Per l .
Link and Symbolic Link Functions
In t he UNIX envir onment , f il es can be "cont ained" in mor e t han one dir ect or y at a t ime.
Each dir ect or y cont ains a r ef er ence, or link, t o t he f il e.
The f ol l owing sect ions descr ibe how t o cr eat e and access l inks.
NOTE
If a f il e is r ef er enced by mul t ipl e l inks, unlink r emoves
onl y one of t he l inks, and t he f il e can st il l be
r ef er enced
The link Function
To cr eat e a l ink t o an exist ing f il e, use t he buil t -in f unct ion link.
The synt ax f or t he link f unct ion is
link (newlink, file);
newlink is t he l ink being cr eat ed, and file is t he f il e being l inked t o.
link r et ur ns t r ue if t he l ink is cr eat ed, and f al se if an er r or occur s.
For exampl e:
link ("/u/jqpublic/file", "/u/janedoe/newfile");
Af t er link has been cal l ed, t he f il e /u/jqpublic/file al so can be t hought of as t he f il e
/u/janedoe/newfile. If unlink is cal l ed using /u/jqpublic/file, as in
unlink ("/u/jqpublic/file");
you can st il l r ef er ence t he f il e by specif ying t he name /u/janedoe/newfile.
The symlink Function
The l ink cr eat ed by t he link f unct ion is cal l ed a hard link, which means t hat it act ual l y
r ef er ences t he f il e it sel f . Many oper at ing syst ems al so suppor t symbolic links, which ar e
r ef er ences t o t he f il ename, not t o t he f il e it sel f .
To cr eat e a symbol ic l ink, use t he f unct ion symlink.
The synt ax f or t he symlink f unct ion is
symlink (newlink, file);
newlink is t he l ink being cr eat ed, and file is t he f il e being l inked t o.
symlink, l ike link r et ur ns t r ue if t he l ink is cr eat ed, and f al se if an er r or occur s.
The f ol l owing is an exampl e of symlink:
symlink("/u/jqpublic/file", "/u/janedoe/newfile");
Her e, /u/janedoe/newfile is symbol ical l y l inked t o /u/jqpublic/file. Now, when t he
f ol l owing st at ement is execut ed, t he f il e is act ual l y del et ed:
unlink ("/u/jqpublic/file");
/u/janedoe/newfile now r ef er ences not hing at al l . (In t his case, /u/janedoe/newfile is
an exampl e of an unresolved symbolic link.) When /u/jqpublic/file is cr eat ed again, you
wil l be abl e t o access t he new f il e using /u/janedoe/newfile.
The readlink Function
If a f il ename, such as /u/janedoe/newfile, is act ual l y a symbol ic l ink t o anot her
f il ename, t he f unct ion readlink r et ur ns t he f il ename t o which it is l inked.
The synt ax f or t he readlink f unct ion is
filename = readlink (linkname);
linkname is t he symbol ic l ink, and filename is t he equival ent f il ename.
readlink r et ur ns an empt y st r ing if t he f il ename is not a symbol ic l ink. (In par t icul ar ,
readlink f ail s if t he f il ename is act ual l y a har d l ink.)
For exampl e:
$linkname = readlink("/u/janedoe/newfile");
# $linkname now contains "/u/jqpublic/file"
List ing 12.11 is an exampl e of a pr ogr am t hat pr int s al l t he symbol ic l inks in a par t icul ar
dir ect or y.

List ing 12.11. A pr ogr am t hat pr int s symbol ic l inks.
1: #!/usr/local/bin/perl
2:
3: $dir = "/u/janedoe";
4: opendir(MYDIR, $dir);
5: while ($name = readdir(MYDIR)) {
6: if (-l $dir . "/" . $name) {
7: print ("$name is linked to ");
8: print (readlink($dir . "/". $name) . "\n");
9: }
10: }
11: closedir(MYDIR);

$ program12_11
newfile is linked to /u/jqpublic/file
$
This pr ogr am uses opendir and readdir t o examine each f il e in t he dir ect or y in
t ur n. Line 6 uses t he -l f il e-t est oper at or t o det er mine whet her t he f il ename is
act ual l y a symbol ic l ink. If t he f il ename is a symbol ic l ink, t he f ol l owing expr ession
becomes t r ue, and t he pr ogr am execut es t he cal l s t o print in l ines 7 and 8:
-l $dir . "/" . $name
Line 8 cal l s readlink, passing it t he dir ect or y name and t he f il ename st or ed in $name.
Because readlink is cal l ed onl y if t he expr ession in l ine 6 is t r ue, $name is al ways a
symbol ic l ink.
File-Permission Functions
As you've seen, t he buil t -in f unct ion mkdir r equir es you t o specif y t he access per missions
f or t he dir ect or y you ar e cr eat ing. These per missions indicat e, f or exampl e, whet her
par t icul ar user s ar e al l owed t o r ead f il es f r om t he dir ect or y or wr it e int o t he
dir ect or y.
In t he UNIX envir onment , each individual f il e has it s own set of access per missions. The
set of possibl e per missions is t he same as f or dir ect or ies. (Ref er t o Tabl e 12.1 in t he
sect ion t it l ed "The mkdir Funct ion" ear l ier in t oday's l esson f or a compl et e l ist of t he
possibl e f unct ions.)
In Per l , t hr ee f unct ions ar e def ined t hat deal wit h access per missions.
G chmod, which changes t he access per missions f or a f il e
G chown, which changes t he owner of a f il e
G umask, which set s t he def aul t access per missions f or a f il e
The chmod Function
To change t he access per missions f or a l ist of f il es, cal l t he chmod f unct ion.
The synt ax f or t he chmod f unct ion is
chmod (permissions, filelist);
permissions is t he set of access per missions you want t o give, and is a st andar d UNIX f il e
per missions mask. (For exampl e, set t ing permissions t o 0777 gives r ead, wr it e, and
execut e per mission t o ever ybody. See t he sect ion cal l ed "The mkdir Funct ion" f or a
descr ipt ion of t he set of per missions.) filelist is t he l ist of f il es whose per missions you
want t o change.
The chmod f unct ion r et ur ns t he number of f il es whose per missions wer e successf ul l y set .
The f ol l owing is an exampl e of a cal l t o chmod:
@filelist = ("file1", "file2");
chmod (0777, @filelist);
In t his exampl e, t he f il es file1 and file2 ar e assigned gl obal r ead, wr it e, and execut e
per missions.
NOTE
You cannot change access per missions using chmod unl ess
you have per mission t o do so. You need t o have been
gr ant ed wr it e per mission on a f il e bef or e you can change
it s per missions
The chown Function
Nor mal l y, t he owner of a f il e is t he per son who cr eat ed it . To change t he owner of a
f il e, use t he f unct ion chown.
The synt ax f or t he chown f unct ion is
chown (userid, groupid, filelist);
The chown f unct ion r equir es t hr ee ar gument s:
G userid, which is t he (numer ical ) user ID of t he new owner of t he f il e
G groupid, which is t he new numer ical gr oup ID t o be assigned t o t he f il e (or -1 if t he
exist ing gr oup ID is t o be pr eser ved)
G filelist, which is a l ist of f il es t o change
The chown f unct ion r et ur ns t he number of f il es changed.
The f ol l owing is an exampl e of a cal l t o chown:
@filelist = ("file1", "file2");
chown (17, -1, @filelist);
NOTE
On most UNIX syst ems, you can r et r ieve a user ID or
gr oup ID f r om t he /etc/passwd f il e. You can use t he Per l
f unct ion getpwnam t o r et r ieve inf or mat ion f r om t his f il e.
For mor e inf or mat ion on getpwnam, r ef er t o Day 15,
"Syst em Funct ions."
Al so, t he super user (syst em administ r at or ) is usual l y t he
onl y user al l owed t o change t he owner of a f il e
The umask Function
As you've seen, you can change t he access per missions f or a f il e using chmod. To specif y
access per missions you cannot use when you cr eat e a f il e, use t he umask f unct ion.
The synt ax f or cal l s t o umask is
oldmaskval = umask (maskval);
maskval is t he cur r ent umask val ue, and umask r et ur ns t he pr evious (super seded) umask
val ue in oldmaskval. Each umask val ue is a f il e cr eat ion mask, and is used t o set t he
def aul t per missions f or f il es and dir ect or ies. (See t he umask manual page f or mor e det ail s
on f il e cr eat ion masks.)
For exampl e, t he f ol l owing st at ement disabl es gr oup and wor l d access per missions f or
t he newl y cr eat ed f il e:
$oldperms = umask(0022);
NOTE
You can det er mine t he cur r ent umask val ue by passing no
ar gument s t o umask, as f ol l ows:
$currperms = umask();
This st at ement assigns t he cur r ent umask val ue t o
$currperms.
Permission File-Test Operators
Some f il e-t est oper at or s in Per l ar e designed t o t est f or var ious per missions. Tabl e 12.2
l ist s t hese f il e-t est oper at or s; in each case, filename is t he name of t he f il e being t est ed.
Tabl e 12.2. Fil e-t est oper at or s t hat t est f or per missions.
Oper at or Descr ipt ion
-g
Does filename have it s set gr oup ID bit set ?
-k
Does filename have it s "st icky bit " set ?
-r
Is filename a r eadabl e f il e?
-u
Does filename have it s set user ID bit set ?
-w
Is filename a wr it abl e f il e?
-x
Is filename an execut abl e f il e?
-R
Is filename r eadabl e onl y if t he r eal user ID can
r ead it ?
-W
Is filename wr it abl e onl y if t he r eal user ID can
wr it e?
-X
Is filename execut abl e onl y if t he r eal user ID can
execut e it ?
In t his case, t he r eal user ID is t he user id specif ied at l ogin, as opposed t o t he ef f ect ive
user ID, which is t he user id under which you ar e cur r ent l y r unning. (On some machines,
a command such as /usr/local/etc/suid enabl es you t o change your ef f ect ive user ID.)
(See Day 6 f or mor e inf or mat ion on how t o use f il e-t est oper at or s.)
Miscellaneous Attribute Functions
The f ol l owing sect ions descr ibe ot her Per l f unct ions t hat manipul at e f il es.
The truncate Function
The truncate f unct ion enabl es you t o r educe t he size of a specif ied f il e t o a par t icul ar
l engt h.
The synt ax f or t he truncate f unct ion is
truncate (filename, length);
filename is t he name of t he f il e t o r educe, and length is t he new l engt h of t he f il e.
For exampl e, t he st at ement
truncate ("/u/jqpublic/longfile", 5000);
r educes t he size of /u/jqpublic/longfile t o 5000 byt es in l engt h. (If t he f il e is al r eady
smal l er t han 5000 byt es, truncate does not hing.)
NOTE
You can use a f il e var iabl e in pl ace of t he f il ename.
Truncate (MYFILE, 5000);
The f il e var iabl e must r ef er t o a f il e opened f or wr it ing
by t he open f unct ion
The stat Function
The stat f unct ion r et r ieves inf or mat ion about a par t icul ar f il e when given it s name or
a f il e var iabl e r epr esent ing it s name.
The synt ax f or t he stat f unct ion is
stat (file);
Her e, file is eit her a f il ename or a f il e var iabl e.
stat r et ur ns a l ist cont aining t he f ol l owing el ement s, in t his or der :
G The device on which t he f il e r esides
G The int er nal r ef er ence number (inode number ) f or t his f il e
G The per missions f or t he f il e
G The number of har d l inks t o t he f il e
G The numer ical user ID of t he f il e owner
G The numer ical gr oup ID of t he f il e owner
G The device t ype, if t his "f il e" is act ual l y a device
G The size of t he f il e (in byt es)
G When t he f il e was l ast accessed
G When t he f il e was l ast modif ied
G When t he f il e st at us l ast changed
G The opt imal bl ock size f or input -out put oper at ions on t he f il e syst em cont aining
t he f il e
G The number of bl ocks al l ocat ed f or t his f il e
Some of t he it ems r et ur ned by stat can be obt ained using f il e t est oper at or s. Tabl e 12.3
l ist s t hese it ems.
Tabl e 12.3. Fil e-t est oper at or s t hat check inf or mat ion r et ur ned by stat.
Oper at or Descr ipt ion
-b
Is filename a mount abl e disk (bl ock
device)?
-c
Is filename an I/O device (char act er
device)?
-s
Is filename a non-empt y f il e?
-t
Does filename r epr esent a t er minal ?
-A
How l ong since filename accessed?
-C
How l ong since filename's inode
accessed?
-M
How l ong since filename modif ied?
-S
Is filename a socket ?
For mor e inf or mat ion on stat or t he inf or mat ion it r et ur ns, see t he UNIX manual page
f or t he stat command on your machine.
The lstat Function
The lstat f unct ion r et ur ns t he same inf or mat ion as stat, but it assumes t hat t he name
being passed as an ar gument is a symbol ic l ink.
The synt ax f or lstat is t he same as t hat f or stat.
lstat (file);
file is either a filename or a file variable.
The time Function
The access and modif icat ion t imes r et ur ned by stat and by t he -A and -M f il e-t est
oper at or s ar e int eger s r epr esent ing t he number of el apsed seconds f r om Januar y 1, 1970,
t o t he t ime t he f il e was accessed or modif ied.
To obt ain t he number of el apsed seconds f r om Januar y 1, 1970, t o t he pr esent t ime, cal l
t he buil t -in f unct ion time.
The synt ax f or cal l s t o t he time f unct ion is
currtime = time();
currtime is t he r et ur ned el apsed-seconds val ue.
The gmtime and localtime Functions
The val ue r et ur ned by time can be conver t ed t o eit her Gr eenwich Mean Time or your
comput er 's l ocal t ime.
To conver t t o Gr eenwich Mean Time, cal l t he gmtime f unct ion. To conver t t o l ocal t ime,
cal l t he localtime f unct ion.
The synt ax f or t he gmtime and localtime f unct ions is ident ical :
timelist = gmtime (timeval);
timelist = localtime (timeval);
Bot h f unct ions accept t he t ime val ue r et ur ned by time, stat, or t he -A and -M f il e-t est
oper at or s.
Bot h f unct ions r et ur n a l ist consist ing of t he f ol l owing nine el ement s:
G Seconds
G Minut es
G The hour of t he day, which is a val ue bet ween 0 and 23
G The day of t he mont h
G The mont h, which is a val ue bet ween 0 (Januar y) and 11 (December )
G The year
G The day of t he week, which is a val ue bet ween 0 (Sunday) and 6 (Sat ur day)
G The day of t he year , which is a val ue bet ween 0 and 364
G A f l ag indicat ing whet her dayl ight saving t ime is in ef f ect
For mor e inf or mat ion on t he l ist r et ur ned by gmtime or localtime, r ef er t o t he UNIX
manual pages f or t he syst em f unct ions wit h t he same names.
The utime Function
The t ime val ues r et ur ned by stat, time, and t he -A and -M f il e-t est oper at or s can be used
t o set t he access and modif icat ion t imes of ot her f il es. To do t his, use t he utime f unct ion.
The synt ax f or t he utime f unct ion is
utime (acctime, modtime, filelist);
acctime is t he new access t ime, modtime is t he new modif icat ion t ime, and filelist is t he
l ist of f il es.
utime r et ur ns t he number of f il es whose access and modif icat ion t imes have been
successf ul l y changed.
The f ol l owing is an exampl e of a cal l t o utime:
$acctime = -A "file1";
$modtime = -M "file1";
@filelist = ("file2", "file3");
utime ($acctime, $modtime, @filelist);
Her e, t he f il es file2 and file3 have t heir access and modif icat ion t imes changed t o
t hose of file1.
The fileno Function
The fileno f unct ion r et ur ns t he int er nal UNIX f il e descr ipt or associat ed wit h a
par t icul ar f il e var iabl e.
The synt ax f or t he fileno f unct ion is
filedesc = fileno (filevar);
Her e, filevar is t he f il e var iabl e whose descr ipt or is t o be r et r ieved.
The f il e descr ipt or r et ur ned by fileno is used in var ious UNIX syst em cal l s; t hese cal l s
can be accessed using t he system f unct ion (as descr ibed on Day 15).
The flock and fcntl Functions
The flock and fcntl f unct ions cal l t he UNIX syst em commands of t he same name.
The synt ax f or t he flock and fcntl f unct ions is
fcntl (filevar, fcntlrtn, value);
flock (filevar, flockop);
Her e, filevar is a f il e var iabl e r epr esent ing an open f il e. fcntlrtn is a fcntl f unct ion as
def ined in t he UNIX fcntl manual page, and value is t he val ue passed t o t he f unct ion, if
appr opr iat e. Simil ar l y, flockop is a f il e-l ocking oper at ion, as def ined in t he UNIX flock
manual page.
For mor e inf or mat ion on t hese f unct ions, r ef er t o t he manual pages or t o a book about
UNIX. (You won't r eal l y be abl e t o use t hese f unct ions ef f ect ivel y unl ess you know a
f air bit about how your oper at ing syst em wor ks.)
Using DBM Files
Many syst ems on which Per l is avail abl e suppor t f il es t hat ar e cr eat ed using t he Dat a
Base Management (DBM) l ibr ar y. Per l enabl es you t o use an associat ive ar r ay t o access
a par t icul ar DBM f il e.
The f ol l owing sect ions descr ibe how t o access DBM f il es f r om Per l pr ogr ams using t he
dbmopen and dbmclose f unct ions. If you ar e r unning Per l 5, t hese f unct ions have been
super seded by t he tie and untie f unct ions; see Day 19, "Object -Or ient ed Pr ogr amming in
Per l ," f or mor e det ail s.
For mor e inf or mat ion on DBM, r ef er t o your syst em's appr opr iat e manual pages.
The dbmopen Function
To associat e an associat ive ar r ay wit h a DBM f il e, use t he dbmopen f unct ion.
The synt ax f or t he dbmopen f unct ion is
dbmopen (array, dbmfilename, permissions);
This f unct ion r equir es t hr ee ar gument s:
G array, which is t he associat ive ar r ay t o use
G dbmfilename, which is t he name of t he DBM f il e t o open
G permissions, which ar e t he access per missions t o use (See t he sect ion cal l ed "The
mkdir Funct ion" f or mor e inf or mat ion on access per missions.)
Af t er t he DBM f il e has been opened, t he subscr ipt s f or t he associat ive ar r ay r epr esent
t he DBM f il e keys, and t he val ues of t he ar r ay r epr esent t he val ues associat ed wit h t he
keys.
Cal l ing dbmopen dest r oys any exist ing val ues in t he
associat ive ar r ay
The dbmclose Function
To cl ose a DBM f il e opened by dbmopen, use dbmclose.
The synt ax f or t he dbmclose f unct ion is
dbmclose (array);
Her e, array is t he associat ive ar r ay specif ied in t he cal l t o dbmopen.
Summary
Today, you l ear ned how t o open a pipe t hat dir ect s input t o t he pr ogr am, how t o open a
f il e f or bot h r eading and wr it ing, and how t o associat e mul t ipl e f il e var iabl es wit h a
singl e f il e. You al so l ear ned how t o t est f or t he end of a par t icul ar input f il e or f or
t he end of t he l ast input f il e.
You al so l ear ned how t o skip backwar d and f or war d in f il es and how t o r ead singl e
char act er s f r om a f il e using getc. You can use getc t o buil d hot -key appl icat ions, which
act as soon as t hey r ead a singl e char act er f r om t he keyboar d.
Per l pr ovides sever al f unct ions f or manipul at ing dir ect or ies. They enabl e you t o cr eat e,
open, r ead, cl ose, del et e, and skip ar ound in dir ect or ies. Ot her Per l f unct ions enabl e
you t o move a f il e f r om one dir ect or y t o anot her , cr eat e har d and symbol ic l inks f r om
one l ocat ion t o anot her , and del et e a har d l ink (or a f il e).
You l ear ned about t he Per l f unct ions t hat enabl e you t o change t he f il e owner or f il e
per missions, t r uncat e a f il e, r et r ieve f il e inf or mat ion, set f il e access and modif icat ion
t imes, r et r ieve t he f il e descr ipt or , and cal l t he flock and fcntl syst em commands.
Final l y, Per l pr ovides an int er f ace t o t he DBM l ibr ar y t hat enabl es you t o associat e
DBM f il es wit h associat ive ar r ays.
Q&A
Q: How can I det er mine whet her a par t icul ar Per l f unct ion t hat manipul at es
t he UNIX f il e syst em is def ined on my machine?
A: A Per l f unct ion t hat manipul at es t he UNIX f il e syst em nor mal l y has t he same
name as t he UNIX command or C l ibr ar y f unct ion t hat per f or ms t he same t ask. If
t he UNIX command or C l ibr ar y f unct ion is def ined, t he Per l f unct ion is usual l y
def ined as wel l .
To check whet her a UNIX command or C l ibr ar y f unct ion is def ined, ent er t he
command man name, wher e name is t he name of t he Per l l ibr ar y f unct ion f or which
you ar e checking.
Q: Why does a l ist of f il es in a dir ect or y appear in unsor t ed or der ?
A: The l ist appear s in t he or der in which t he f il es ar e st or ed in t he dir ect or y. This
var ies, depending on t he machine; usual l y, however , newer f il es appear at t he
end of t he l ist .
Q: Which is bet t er t o use: t he f il e-t est oper at or s or t he buil t -in f unct ion
stat?
A: Whenever possibl e, use t he f il e-t est oper at or s. They ar e easier t o use and ar e
of t en mor e ef f icient .
Q: Why ar e bot h read and sysread def ined, when t hey ar e so simil ar ?
A: read, l ike t he UNIX f unct ion fread, uses t he st andar d UNIX input -out put (I/O)
envir onment . sysread and syswrite, on t he ot her hand, bypass t he st andar d I/O
envir onment and per f or m l ow-l evel syst em cal l s.
Q: Why ar e eof and eof() dif f er ent ?
A: The shor t answer is: Just because. The l ong answer is t hat an empt y l ist as an
ar gument (as in eof()) r ef er s t o t he l ist of f il es on t he command l ine, as does t he
<> in
while ($line = <>) ...
eof, on t he ot her hand, r ef er s onl y t o t he f il e cur r ent l y being r ead.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. What do t hese f unct ions do?
a. tell
b. mkdir
c. link
d. unlink
e. truncate
2. What is t he dif f er ence bet ween stat and lstat?
3. What is t he dif f er ence bet ween tell and telldir?
4. How ar e t he f ol l owing f il es being opened?
A. open (MYFILE, "<file1");
b. open (MYFILE, "file2|");
c. open (MYFILE, "+>file3");
d. open (MYFILE, ">&STDOUT");
5. What per missions ar e gr ant ed by t he f ol l owing val ues?
a. 0666
b. 0777
c. 0700
d. 0644
Exercises
1. Wr it e a pr ogr am t hat r eads t he dir ect or y /u/jqpublic and pr int s out al l f il e and
dir ect or y names t hat st ar t wit h a per iod. Ignor e t he special f il es . (one per iod)
and .. (t wo per iods).
2. Wr it e a pr ogr am t hat l ist s al l t he f il es (not t he subdir ect or ies) in t he dir ect or y
/u/jqpublic and t hen l ist s t he cont ent s of any subdir ect or ies, t heir
subdir ect or ies, and so on. (Hint : Use a r ecur sive subr out ine.)
3. Wr it e a pr ogr am t hat uses readdir and rewinddir t o r ead a dir ect or y named
/u/jqpublic and pr int a sor t ed l ist of t he f il es and dir ect or ies in al phabet ical
or der . Ignor e al l names beginning wit h a per iod. (Of cour se, t his is not t he most
ef f icient way t o do t his.)
4. Wr it e a pr ogr am t hat uses hot keys and does t he f ol l owing:
H Reads singl e digit s and pr int s out t heir Engl ish-l anguage equival ent s (f or
exampl e, zero f or 0, one f or 1, and so on)
H Ter minat es if it r eads t he Esc (escape) char act er
H Ignor es al l ot her input
H Pr int s out one Engl ish wor d per l ine
5. Wr it e a pr ogr am t hat r eads t he dir ect or y /u/jqpublic and gr ant s gl obal execut e
per missions f or al l f il es ending in .pl. Take away al l ot her per missions, except user
r ead, f or ever y ot her f il e in t he dir ect or y. Skip over al l subdir ect or ies.
6. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
while ($line = <>) {
print ($line);
if (eof()) {
print ("-- end of current file --\n");
}
}

Chapter 13
Process, String, and Mathematical Functions
CONTENTS
G Pr ocess- and Pr ogr am-Manipul at ion Funct ions
H St ar t ing a Pr ocess
H Ter minat ing a Pr ogr am or Pr ocess
H Execut ion Cont r ol Funct ions
H Miscel l aneous Cont r ol Funct ions
G Mat hemat ical Funct ions
H The sin and cos Funct ions
H The atan2 Funct ion
H The sqrt Funct ion
H The exp Funct ion
H The log Funct ion
H The abs Funct ion
H The rand and srand Funct ions
G St r ing-Manipul at ion Funct ions
H The index Funct ion
H The rindex Funct ion
H The length Funct ion
H Ret r ieving St r ing Lengt h Using tr
H The pos Funct ion
H The substr Funct ion
H The study Funct ion
H Case Conver sion Funct ions
H The quotemeta Funct ion
H The join Funct ion
H The sprintf Funct ion
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson descr ibes t hr ee gr oups of buil t -in Per l f unct ions:
G The f unct ions t hat manipul at e pr ocesses and pr ogr ams t hat ar e cur r ent l y
r unning
G The f unct ions t hat per f or m mat hemat ical oper at ions
G The f unct ions t hat manipul at e char act er st r ings
Many of t he f unct ions descr ibed t oday use f eat ur es of
t he UNIX oper at ing syst em. If you ar e using Per l on a
machine t hat is not r unning UNIX, some of t hese
f unct ions might not be def ined or might behave
dif f er ent l y.
Check t he document at ion suppl ied wit h your ver sion of
Per l f or det ail s on which f unct ions ar e suppor t ed or
emul at ed on your machine
Process- and Program-Manipulation Functions
Per l pr ovides a wide r ange of f unct ions t hat manipul at e bot h t he pr ogr am cur r ent l y
being execut ed and ot her pr ogr ams (al so cal l ed pr ocesses) r unning on your machine.
These f unct ions ar e divided int o f our gr oups:
G Funct ions t hat st ar t addit ional pr ocesses
G Funct ions t hat st op t he cur r ent pr ogr am or anot her pr ocess
G Funct ions t hat cont r ol t he execut ion of a pr ogr am or pr ocess
G Funct ions t hat manipul at e pr ocesses or pr ogr ams but don't f it int o any of t he
pr eceding cat egor ies
The f ol l owing sect ions descr ibe t hese f our gr oups of pr ocess- and pr ogr am-manipul at ion
f unct ions.
Starting a Process
Sever al buil t -in f unct ions pr ovide dif f er ent ways of cr eat ing pr ocesses: eval, system,
fork, pipe, exec, and syscall. These f unct ions ar e descr ibed in t he f ol l owing subsect ions.
The eval Function
The eval f unct ion t r eat s a char act er st r ing as an execut abl e Per l pr ogr am.
The synt ax f or t he eval f unct ion is
eval (string);
Her e, string is t he char act er st r ing t hat is t o become a Per l pr ogr am.
For exampl e, t hese t wo l ines of code:
$print = "print (\"hello, world\\n\");";
eval ($print);
pr int t he f ol l owing message on your scr een:
hello, world
The char act er st r ing passed t o eval can be a char act er -st r ing const ant or any
expr ession t hat has a val ue which is a char act er st r ing. In t his exampl e, t he f ol l owing
st r ing is assigned t o $print, which is t hen passed t o eval:
print ("hello, world\n");
The eval f unct ion uses t he special syst em var iabl e $@ t o indicat e whet her t he Per l
pr ogr am cont ained in t he char act er st r ing has execut ed pr oper l y. If no er r or has
occur r ed, $@ cont ains t he nul l st r ing. If an er r or has been det ect ed, $@ cont ains t he
t ext of t he message.
The subpr ogr am execut ed by eval af f ect s t he pr ogr am t hat cal l ed it ; f or exampl e, any
var iabl es t hat ar e changed by t he subpr ogr am r emain changed in t he main pr ogr am.
List ing 13.1 pr ovides a simpl e exampl e of t his.

List ing 13.1. A pr ogr am t hat il l ust r at es t he behavior of eval.
1: #!/usr/local/bin/perl
2:
3: $myvar = 1;
4: eval ("print (\"hi!\\n\"); \$myvar = 2;");
5: print ("the value of \$myvar is $myvar\n");

$ program13_1
hi!
the value of $myvar is 2
$
The cal l t o eval in l ine 4 f ir st execut es t he st at ement
print ("hi!\n");
Then it execut es t he f ol l owing assignment , which assigns 2 t o $myvar:
$myvar = 2;
The val ue of $myvar r emains 2 in t he main pr ogr am, which means t hat l ine 5 pr int s t he
val ue 2. (The backsl ash pr eceding t he $ in $myvar ensur es t hat t he Per l int er pr et er does
not subst it ut e t he val ue of $myvar f or t he name bef or e passing it t o eval.)
NOTE
If you l ike, you can l eave of f t he f inal semicol on in t he
char act er st r ing passed t o eval, as f ol l ows:
eval ("print (\"hi!\\n\"); \$myvar = 2");
As bef or e, t his pr int s hi! and assigns 2 t o $myvar
The eval f unct ion has one ver y usef ul pr oper t y: If t he subpr ogr am execut ed by eval
encount er s a f at al er r or , t he main pr ogr am does not hal t . Inst ead, t he subpr ogr am
t er minat es, copies t he er r or message int o t he syst em var iabl e $@, and r et ur ns t o t he main
pr ogr am.
This f eat ur e is ver y usef ul if you ar e moving a Per l pr ogr am f r om one machine t o
anot her and you ar e not sur e whet her t he new machine cont ains a buil t -in f unct ion
you need. For exampl e, List ing 13.2 t est s whet her t he tell f unct ion is impl ement ed.

List ing 13.2. A pr ogr am t hat uses eval t o t est whet her a f unct ion is
impl ement ed.
1: #!/usr/local/bin/perl
2:
3: open (MYFILE, "file1") || die ("Can't open file1");
4: eval ("\$start = tell(MYFILE);");
5: if ($@ eq "") {
6: print ("The tell function is defined.\n");
7: } else {
8: print ("The tell function is not defined!\n");
9: }

$ program13_2
The tell function is defined.
$
The cal l t o eval in l ine 4 cr eat es a subpr ogr am t hat cal l s t he f unct ion tell.
If tell is def ined, t he subpr ogr am assigns t he l ocat ion of t he next l ine (which, in t his
case, is t he f ir st l ine) t o r ead t o t he scal ar var iabl e $start. If tell is not def ined, t he
subpr ogr am pl aces t he er r or message in $@.
Line 5 checks whet her $@ is t he nul l st r ing. If $@ is empt y, t he subpr ogr am in l ine 4
execut ed wit hout gener at ing an er r or , which means t hat t he tell f unct ion is
impl ement ed. (Because assignment s per f or med in t he subpr ogr am r emain in ef f ect in t he
main pr ogr am, t he main pr ogr am can cal l seek using t he val ue in $start, if desir ed.) If $@
is not empt y, t he pr ogr am assumes t hat tell is not def ined, and it pr int s a message
pr ocl aiming t hat f act . (This pr ogr am is assuming t hat t he onl y r eason t he subpr ogr am
coul d f ail is because tell is not def ined. This is a r easonabl e assumpt ion, because you
know t hat t he f il e r ef er enced by MYFILE has been successf ul l y opened.)
Al t hough eval is ver y usef ul , it is best t o use it onl y f or
smal l pr ogr ams. If you need t o gener at e a l ar ger
pr ogr am, it might be bet t er t o wr it e t he pr ogr am t o a f il e
and cal l system t o execut e it . (The system f unct ion is
descr ibed in t he f ol l owing sect ion.)
Because st at ement s execut ed by eval af f ect t he pr ogr am
t hat cal l s it , t he behavior of compl icat ed pr ogr ams
might become dif f icul t t o t r ack if eval is used t o excess.
The system Function
You have seen exampl es of t he system f unct ion in ear l ier l essons.
The synt ax f or t he system f unct ion is
system (list);
This f unct ion is passed a l ist as f ol l ows: The f ir st el ement of t he l ist cont ains t he name
of a pr ogr am t o execut e, and t he ot her el ement s ar e ar gument s t o be passed t o t he
pr ogr am.
When system is cal l ed, it st ar t s a pr ocess t hat r uns t he pr ogr am and wait s unt il t he
pr ocess t er minat es. When t he pr ocess t er minat es, t he er r or code is shif t ed l ef t eight bit s,
and t he r esul t ing val ue becomes system's r et ur n val ue. List ing 13.3 is a simpl e exampl e of
a pr ogr am t hat cal l s system.

List ing 13.3. A pr ogr am t hat cal l s system.
1: #!/usr/local/bin/perl
2:
3: @proglist = ("echo", "hello, world!");
4: system(@proglist);

$ program13_3
hello, world!
$
In t his pr ogr am, t he cal l t o system execut es t he UNIX pr ogr am echo, which
displ ays it s ar gument s. The ar gument passed t o echo is hello, world!.
TIP
When you st ar t anot her pr ogr am using system, out put
dat a might be mixed, out of sequence, or dupl icat ed.
To get ar ound t his pr obl em, set t he syst em var iabl e $|,
def ined f or each f il e, t o 1. The f ol l owing is an exampl e:
select (STDOUT);
$| = 1;
select (STDERR);
$| = 1;
When $| is set t o 1, no buf f er is def ined f or t hat f il e, and
out put is wr it t en out r ight away. This ensur es t hat t he
out put behaves pr oper l y when system is cal l ed.
See "Redir ect ing One Fil e t o Anot her " on Day 12,
"Wor king wit h t he Fil e Syst em," f or mor e inf or mat ion on
select and $|
The fork Function
The fork f unct ion cr eat es t wo copies of your pr ogr am: t he par ent pr ocess and t he chil d
pr ocess. These copies execut e simul t aneousl y.
The synt ax f or t he fork f unct ion is
procid = fork();
fork r et ur ns zer o t o t he chil d pr ocess and a nonzer o val ue t o t he par ent pr ocess. This
nonzer o val ue is t he process ID of t he chil d pr ocess. (A pr ocess ID is an int eger t hat
enabl es t he syst em t o dist inguish t his pr ocess f r om t he ot her pr ocesses cur r ent l y
r unning on t he machine.)
The r et ur n val ue f r om fork enabl es you t o det er mine which pr ocess is t he chil d pr ocess
and which is t he par ent . For exampl e:
$retval = fork();
if ($retval == 0) {
# this is the child process
exit; # this terminates the child process
} else {
# this is the parent process
}
If fork is unabl e t o execut e, t he r et ur n val ue is a special undef ined val ue f or which you
can t est by using t he defined f unct ion. (For mor e inf or mat ion on defined, see Day 14,
"Scal ar - Conver sion and List -Manipul at ion Funct ions.")
To t er minat e a chil d pr ocess cr eat ed by fork, use t he buil t -in f unct ion exit, which is
descr ibed l at er in t oday's l esson.
Be car ef ul when you use t he fork f unct ion. The
f ol l owing ar e a f ew exampl es of what can go wr ong:
G If bot h copies of t he pr ogr am execut e cal l s t o
print or any ot her out put -gener at ing f unct ion,
t he out put f r om one copy might be mixed wit h t he
out put f r om t he ot her copy. Ther e is no way t o
guar ant ee t hat out put f r om one copy wil l appear
bef or e out put f r om t he ot her , unl ess you f or ce
one pr ocess t o wait f or t he ot her .
G If you use fork in a l oop, t he pr ogr am might wind
up gener at ing many copies of it sel f . This can af f ect
t he per f or mance of your syst em (or cr ash it
compl et el y).
G Your chil d pr ocess might wind up execut ing code
t hat your par ent pr ocess is supposed t o execut e, or
vice ver sa
The pipe Function
The pipe f unct ion is designed t o be used in conjunct ion wit h t he fork f unct ion. It
pr ovides a way f or t he chil d and par ent pr ocesses t o communicat e.
The synt ax f or t he pipe f unct ion is
pipe (infile, outfile);
pipe r equir es t wo ar gument s, each of which is a f il e var iabl e t hat is not cur r ent l y in
use-in t his case, infile and outfile. Af t er pipe has been cal l ed, inf or mat ion sent via t he
outfile f il e var iabl e can be r ead using t he infile f il e var iabl e. In ef f ect , t he out put
f r om outfile is piped t o infile.
To use pipe wit h fork, do t he f ol l owing:
1. Cal l pipe.
2. Cal l fork t o spl it t he pr ogr am int o par ent and chil d pr ocesses.
3. Have one of t he pr ocesses cl ose infile, and have t he ot her cl ose outfile.
The pr ocess in which outfile is st il l open can now send dat a t o t he pr ocess in which
infile is st il l open. (The chil d can send dat a t o t he par ent , or vice ver sa, depending on
which pr ocess cl oses input and which cl oses out put .)
List ing 13.4 shows how pipe wor ks. It uses fork t o cr eat e a par ent and chil d pr ocess. The
par ent pr ocess r eads a l ine of input , which it passes t o t he chil d pr ocess. The chil d
pr ocess t hen pr int s it .

List ing 13.4. A pr ogr am t hat uses fork and pipe.
1: #!/usr/local/bin/perl
2:
3: pipe (INPUT, OUTPUT);
4: $retval = fork();
5: if ($retval != 0) {
6: # this is the parent process
7: close (INPUT);
8: print ("Enter a line of input:\n");
9: $line = <STDIN>;
10: print OUTPUT ($line);
11: } else {
12: # this is the child process
13: close (OUTPUT);
14: $line = <INPUT>;
15: print ($line);
16: exit (0);
17: }

$ program13_4
Enter a line of input:
Here is a test line
Here is a test line
$
Line 3 def ines t he f il e var iabl es INPUT and OUTPUT. Dat a sent t o OUTPUT can be
now r ead f r om INPUT.
Line 4 spl it s t he pr ogr am int o a par ent pr ocess and a chil d pr ocess. Line 5 t hen
det er mines which pr ocess is which.
The par ent pr ocess execut es l ines 7-10. Because t he par ent pr ocess is sending dat a
t hr ough OUTPUT, it has no need t o access INPUT; t her ef or e, l ine 7 cl oses INPUT.
Lines 8 and 9 obt ain a l ine of dat a f r om t he st andar d input f il e. Line 10 t hen sends t his
l ine of dat a t o t he chil d pr ocess via t he f il e var iabl e OUTPUT.
The chil d pr ocess execut es l ines 13-16. Because t he chil d pr ocess is r eceiving dat a
t hr ough INPUT, it does not need access t o OUTPUT; t her ef or e, l ine 13 cl oses OUTPUT.
Line 14 r eads dat a f r om INPUT. Because dat a f r om OUTPUT is piped t o INPUT, t he pr ogr am
wait s unt il t he dat a is act ual l y sent bef or e cont inuing wit h l ine 15.
Line 16 uses exit t o t er minat e t he chil d pr ocess. This al so aut omat ical l y cl oses INPUT.
Not e t hat t he <INPUT> oper at or behaves l ike any ot her oper at or t hat r eads input (such
as, f or inst ance, <STDIN>). If t her e is no mor e dat a t o r ead, INPUT is assumed t o be at t he
"end of f il e," and <INPUT> r et ur ns t he nul l st r ing.
Tr af f ic t hr ough t he f il e var iabl es specif ied by pipe can
f l ow in onl y one dir ect ion. You cannot have a pr ocess
bot h send and r eceive on t he same pipe.
If you need t o est abl ish t wo-way communicat ion, you can
open t wo pipes, one in each dir ect ion
The exec Function
The exec f unct ion is simil ar t o t he system f unct ion, except t hat it t er minat es t he
cur r ent pr ogr am bef or e st ar t ing t he new one.
The synt ax f or t he exec f unct ion is
exec (list);
This f unct ion is passed a l ist as f ol l ows: The f ir st el ement of t he l ist cont ains t he name
of a pr ogr am t o execut e, and t he ot her el ement s ar e ar gument s t o be passed t o t he
pr ogr am.
For exampl e, t he f ol l owing st at ement t er minat es t he Per l pr ogr am and st ar t s t he
command mail dave:
exec ("mail dave");
Like system, exec accept s addit ional ar gument s t hat ar e assumed t o be passed t o t he
command being invoked. For exampl e, t he f ol l owing st at ement execut es t he command vi
file1:
exec ("vi", "file1");
You can specif y t he name t hat t he syst em is t o use as t he pr ogr am name, as f ol l ows:
exec "maildave" ("mail dave");
Her e, t he command mail dave is invoked, but t he pr ogr am name is set t o maildave. (This
af f ect s t he val ue of t he syst em var iabl e $0, which cont ains t he name of t he r unning
pr ogr am. It al so af f ect s t he val ue of argv[0] if t he pr ogr am t o be invoked was
or iginal l y wr it t en in C.)
exec of t en is used in conjunct ion wit h fork: when fork spl it s int o t wo pr ocesses, t he
chil d pr ocess st ar t s anot her pr ogr am using exec.
exec has t he same out put -buf f er ing pr obl ems as system.
See t he descr ipt ion of system, ear l ier in t oday's l esson,
f or a descr ipt ion of t hese pr obl ems and how t o deal wit h
t hem
The syscall Function
The syscall f unct ion cal l s a syst em f unct ion.
The synt ax f or t he syscall f unct ion is
syscall (list);
syscall expect s a l ist as it s ar gument . The f ir st el ement of t he list is t he name of t he
syst em cal l t o invoke, and t he r emaining el ement s ar e ar gument s t o be passed t o t he
cal l .
If an ar gument in t he l ist passed t o syscall is a numer ic val ue, it is conver t ed t o a C
int eger (t ype int). Ot her wise, a point er t o t he st r ing val ue is passed. See t he syscall
UNIX manual page or t he Per l document at ion f or mor e det ail s.
NOTE
The Per l header f il e syscall.ph must be incl uded in
or der t o use syscall:
require ("syscall.ph")
For mor e inf or mat ion on require, see Day 20,
"Miscel l aneous Feat ur es of Per l ."
Terminating a Program or Process
The f ol l owing sect ions descr ibe t he f unct ions t hat t er minat e eit her t he cur r ent l y
execut ing pr ogr am or a pr ocess r unning el sewher e on t he syst em: die, warn, exit, and
kill.
The die and warn Functions
The die and warn f unct ions pr ovide a way f or pr ogr ams t o pass ur gent messages back t o
t he user who is r unning t hem.
The die f unct ion t er minat es t he pr ogr am and pr int s an er r or message on t he st andar d
er r or f il e.
The synt ax f or t he die f unct ion is
die (message);
message is t he er r or message t o be displ ayed.
For exampl e, t he cal l
die ("Cannot open input file\n");
pr int s t he f ol l owing message and t hen exit s:
Cannot open input file
die can accept a l ist as it s ar gument , in which case al l el ement s of t he l ist ar e pr int ed.
@diemsg = ("I'm about ", "to die\n");
die (@diemsg);
This pr int s out t he f ol l owing message and t hen exit s:
I'm about to die
If t he l ast ar gument passed t o die ends wit h a newl ine char act er , t he er r or message is
pr int ed as is. If t he l ast ar gument t o die does not end wit h a newl ine char act er , t he
pr ogr am f il ename and l ine number ar e pr int ed, al ong wit h t he l ine number of t he input
f il e (if appl icabl e). For exampl e, if l ine 6 of t he f il e myprog is
die ("Cannot open input file");
t he message it pr int s is
Cannot open input file at myprog line 6.
The warn f unct ion, l ike die, pr int s a message on t he st andar d er r or f il e.
The synt ax f or t he warn f unct ion is
warn (message);
As wit h die, message is t he message t o be displ ayed.
warn, unl ike die, does not t er minat e. For exampl e, t he st at ement
warn ("Input file is empty");
sends t he f ol l owing message t o t he st andar d er r or f il e, and t hen cont inues execut ing:
Input file is empty at myprog line 76.
If t he st r ing passed t o warn is t er minat ed by a newl ine char act er , t he war ning message is
pr int ed as is. For exampl e, t he st at ement
warn("Danger! Danger!\n");
sends
Danger! Danger!
t o t he st andar d er r or f il e.
NOTE
If eval is used t o invoke a pr ogr am t hat cal l s die, t he
er r or message pr int ed by die is not pr int ed; inst ead, t he
er r or message is assigned t o t he syst em var iabl e $@
The exit Function
The exit f unct ion t er minat es a pr ogr am.
If you l ike, you can specif y a r et ur n code t o be passed t o t he syst em by passing exit an
ar gument using t he f ol l owing synt ax:
exit (retcode);
retcode is t he r et ur n code you want t o pass.
For exampl e, t he f ol l owing st at ement t er minat es t he pr ogr am wit h a r et ur n code of 2:
exit(2);
The kill Function
The kill f unct ion enabl es you t o send a signal t o a gr oup of pr ocesses.
The synt ax f or invoking t he kill f unct ion is
kill (signal, proclist);
In t his case, signal is t he numer ic signal t o send. (For exampl e, a signal of 9 kil l s t he
l ist ed pr ocesses.) proclist is a l ist of pr ocess IDs (such as t he chil d pr ocess ID r et ur ned
by fork).
signal al so can be a signal name encl osed in quot es, as in "INT".
For mor e det ail s on t he signal s you can send, r ef er t o t he kill UNIX manual page.
Execution Control Functions
The sleep, wait, and waitpid f unct ions del ay t he execut ion of a par t icul ar pr ogr am or
pr ocess.
The sleep Function
The sleep f unct ion suspends t he pr ogr am f or a specif ied number of seconds.
The synt ax f or t he sleep f unct ion is
sleep (time);
time is t he number of seconds t o suspend pr ogr am execut ion.
The f unct ion r et ur ns t he number of seconds t hat t he pr ogr am was act ual l y st opped.
For exampl e, t he f ol l owing st at ement put s t he pr ogr am t o sl eep f or f ive seconds:
sleep (5);
The wait and waitpid Functions
The wait f unct ion suspends execut ion and wait s f or a chil d pr ocess t o t er minat e (such as
a pr ocess cr eat ed by fork).
The wait f unct ion r equir es no ar gument s:
procid = wait();
When a chil d pr ocess t er minat es, wait r et ur ns t he pr ocess ID, procid, of t he pr ocess t hat
has t er minat ed. If no chil d pr ocesses exist , wait r et ur ns -1.
The waitpid f unct ion wait s f or a par t icul ar chil d pr ocess.
The synt ax f or t he waitpid f unct ion is
waitpid (procid, waitflag);
procid is t he pr ocess ID of t he pr ocess t o wait f or , and waitflag is a special wait f l ag (as
def ined by t he waitpid or wait4 manual page). By def aul t , waitflag is 0 (a nor mal wait ).
waitpid r et ur ns 1 if t he pr ocess is f ound and has t er minat ed, and it r et ur ns -1 if t he
chil d pr ocess does not exist .
List ing 13.5 shows how waitpid can be used t o cont r ol pr ocess execut ion.

List ing 13.5. A pr ogr am t hat uses waitpid.
1: #!/usr/local/bin/perl
2:
3: $procid = fork();
4: if ($procid == 0) {
5: # this is the child process
6: print ("this line is printed first\n");
7: exit(0);
8: } else {
9: # this is the parent process
10: waitpid ($procid, 0);
11: print ("this line is printed last\n");
12: }

$ program13_5
this line is printed first
this line is printed last
$
Line 3 spl it s t he pr ogr am int o a par ent pr ocess and a chil d pr ocess. The par ent
pr ocess is r et ur ned t he pr ocess ID of t he chil d pr ocess, which is st or ed in $procid.
Lines 6 and 7 ar e execut ed by t he chil d pr ocess. Line 6 pr int s t he f ol l owing l ine:
this line is printed first
Line 7 t hen cal l s exit, which t er minat es t he chil d pr ocess.
Lines 10 and 11 ar e execut ed by t he par ent pr ocess. Line 10 cal l s waitpid and passes it
t he ID of t he chil d pr ocess; t her ef or e, t he par ent pr ocess wait s unt il t he chil d pr ocess
t er minat es bef or e cont inuing. This means t hat l ine 11, which pr int s t he second l ine, is
guar ant eed t o be execut ed af t er t he f ir st l ine is pr int ed.
As you can see, wait can be used t o f or ce t he or der of execut ion of pr ocesses.
NOTE
For mor e inf or mat ion on t he possibl e val ues t hat can be
passed as waitflag, examine t he f il e wait.ph, which is
avail abl e f r om t he same pl ace you r et r ieved your copy of
Per l . (It might al r eady be on your syst em.) You can f ind
out mor e al so by invest igat ing t he waitpid and wait4
manual pages
Miscellaneous Control Functions
The caller, chroot, local, and times f unct ions per f or m var ious pr ocess and pr ogr am-
r el at ed act ions.
The caller Function
The caller f unct ion r et ur ns t he name and t he l ine number of t he pr ogr am t hat cal l ed
t he cur r ent l y execut ing subr out ine.
The synt ax f or t he caller f unct ion is
subinfo = caller();
caller r et ur ns a t hr ee-el ement l ist , subinfo, consist ing of t he f ol l owing:
G The name of t he package f r om which t he subr out ine was cal l ed
G The name of t he f il e f r om which t he subr out ine was cal l ed
G The l ine number of t he subr out ine cal l
This r out ine is used by t he Per l debugger , which you'l l l ear n about on Day 21, "The Per l
Debugger ." For mor e inf or mat ion on packages, r ef er t o Day 20, "Miscel l aneous Feat ur es
of Per l ."
The chroot Function
The chroot f unct ion dupl icat es t he f unct ional it y of t he chroot f unct ion cal l .
The synt ax f or t he chroot f unct ion is
chroot (dir);
dir is t he new r oot dir ect or y.
In t he f ol l owing exampl e, t he specif ied dir ect or y becomes t he r oot dir ect or y f or t he
pr ogr am:
chroot ("/u/jqpublic");
For mor e inf or mat ion, r ef er t o t he chroot manual page.
The local Function
The local f unct ion was int r oduced on Day 9, "Using Subr out ines." It decl ar es t hat a
copy of a named var iabl e is t o be def ined f or a subr out ine. (Ref er t o t hat day f or
exampl es t hat use local inside a subr out ine.)
local can be used al so t o def ine a copy of a var iabl e f or use inside a statement block (a
col l ect ion of st at ement s encl osed in br ace br acket s), as f ol l ows:
if ($var == 14) {
local ($localvar);
# stuff goes here
}
This def ines a l ocal copy of t he var iabl e $localvar f or use inside t he st at ement bl ock.
Any ot her copies of $localvar t hat exist ar e not af f ect ed by t he changes t o t his l ocal
copy.
DON'T use local inside a l oop, as in t his exampl e:
while ($var <= 14) {
local ($myvar);
# stuff goes here
}
Her e, a new copy of $myvar is def ined each t ime t he l oop
it er at es. This is pr obabl y not what you want .
The times Function
The times f unct ion r et ur ns t he amount of job t ime consumed by t his pr ogr am and any
chil d pr ocesses of t his pr ogr am.
The synt ax f or t he times f unct ion is
timelist = times
As you can see, times accept s no ar gument s. It r et ur ns timelist, a l ist consist ing of t he
f ol l owing f our f l oat ing-point number s:
G The user t ime consumed by t his pr ogr am
G The syst em t ime consumed by t his pr ogr am
G The user t ime consumed by t he chil d pr ocesses, if t hey exist
G The syst em t ime consumed by t he chil d pr ocesses, if t hey exist
Mathematical Functions
Per l pr ovides f unct ions t hat per f or m t he st andar d t r igonomet r ic oper at ions, pl us some
ot her usef ul mat hemat ical oper at ions. The f ol l owing sect ions descr ibe t hese f unct ions:
sin, cos, atan2, sqrt, exp, log, abs, rand, and srand.
The sin and cos Functions
The sin and cos f unct ions ar e passed a scal ar val ue and r et ur n t he sine and cosine,
r espect ivel y, of t he val ue.
The synt ax of t he sin and cos f unct ions is
retval = sin (value);
retval = cos (value);
value is a pl acehol der her e. It can be t he val ue st or ed in a scal ar var iabl e or t he r esul t
of an expr ession; it is assumed t o be in r adians. See t he f ol l owing sect ion, "The atan2
Funct ion," t o f ind out how t o conver t f r om r adians t o degr ees.
The atan2 Function
The atan2 f unct ion cal cul at es and r et ur ns t he ar ct angent of one val ue divided by
anot her , in t he r ange -p t o p.
The synt ax of t he atan2 f unct ion is
retval = atan2 (value1, value2);
If value1 and value2 ar e equal , retval is t he val ue of p divided by 4.
List ing 13.6 shows how you can use t his t o conver t f r om degr ees t o r adians.

List ing 13.6. A pr ogr am t hat cont ains a subr out ine t hat conver t s f r om
degr ees t o r adians.
1: #!/usr/local/bin/perl
2:
3: $rad90 = &degrees_to_radians(90);
4: $sin90 = sin($rad90);
5: $cos90 = cos($rad90);
6: print ("90 degrees:\nsine is $sin90\ncosine is $cos90\n");
7:
8: sub degrees_to_radians {
9: local ($degrees) = @_;
10: local ($radians);
11:
12: $radians = atan2(1,1) * $degrees / 45;
13: }

$ program13_6
90 degrees:
sine is 1
cosine is 6.1230317691118962911e-17
$
The subr out ine degrees_to_radians conver t s f r om degr ees t o r adians by
mul t ipl ying by p divided by 180. Because atan2(1,1) r et ur ns p divided by 4, al l t he
subr out ine needs t o do af t er t hat is divide by 45 t o obt ain t he number of r adians.
In t he main body of t he pr ogr am, l ine 3 conver t s 90 degr ees t o t he equival ent val ue in
r adians (p divided by 2). Line 4 t hen passes t his val ue t o sin, and l ine 5 passes it t o cos.
NOTE
The t r igonomet r ic oper at ions pr ovided her e ar e
suf f icient t o enabl e you t o per f or m t he ot her impor t ant
t r igonomet r ic oper at ions. For exampl e, t o obt ain t he
t angent of a val ue, obt ain t he sine and cosine of t he
val ue by cal l ing sin and cos, and t hen divide t he sine by
t he cosine
The sqrt Function
The sqrt f unct ion r et ur ns t he squar e r oot of t he val ue it is passed.
The synt ax f or t he sqrt f unct ion is
retval = sqrt (value);
value can be any posit ive number .
The exp Function
The exp f unct ion r et ur ns t he number e ** value, wher e e is t he st andar d mat hemat ical
const ant (t he base f or t he nat ur al l ogar it hm) and value is t he ar gument passed t o exp.
The synt ax f or t he exp f unct ion is
retval = exp (value);
To r et r ieve e it sel f , pass exp t he val ue 1.
The log Function
The log f unct ion t akes a val ue and r et ur ns t he nat ur al (base e) l ogar it hm of t he val ue.
The synt ax f or t he log f unct ion is
retval = log (value);
The log f unct ion undoes exp; t he expr ession
$var = log (exp ($var));
al ways l eaves $var wit h t he val ue it st ar t ed wit h (if you f act or in r ound-of f er r or ).
The abs Function
The abs f unct ion r et ur ns t he absol ut e val ue of a number . This is def ined as f ol l ows: if a
val ue is l ess t han zer o, abs negat es it and r et ur ns t he r esul t .
$result = $abs(-3.5); # returns 3.5
Ot her wise, t he r esul t is ident ical t o t he val ue:
$result = $abs(3.5); # returns 3.5
$result = $abs(0); # returns 0
The synt ax f or t he abs f unct ion is
retval = abs (value);
value can be any number .
NOTE
abs is not def ined in Per l 4
The rand and srand Functions
The rand and srand f unct ions enabl e Per l pr ogr ams t o gener at e r andom number s.
The rand f unct ion is passed an int eger val ue and gener at es a r andom f l oat ing-point
number bet ween 0 and t he val ue.
The synt ax f or t he rand f unct ion is
retval = rand (num);
num is t he int eger val ue passed t o rand, and retval is a r andom f l oat ing-point number
bet ween 0 and t he num.
For exampl e, t he f ol l owing st at ement gener at es a number bet ween 0 and 10 and r et ur ns
it in $retval:
$retval = rand (10);
srand init ial izes t he r andom-number gener at or used by rand. This ensur es t hat t he
r andom number s gener at ed ar e, in f act , r andom. (If you do not use srand, you'l l get t he
same set of r andom number s each t ime.)
The synt ax f or t he srand f unct ion is
srand (value);
srand accept s an int eger val ue as an ar gument ; if no ar gument is suppl ied, srand cal l s
t he time f unct ion and uses it s r et ur n val ue as t he r andom-number seed.
For an exampl e t hat uses rand and srand, see t he sect ion t it l ed "Ret ur ning a Val ue f r om
a Subr out ine" on Day 9.
NOTE
The f ol l owing val ues and f unct ions r et ur n number s
t hat can make usef ul r andom-number seeds:
G The syst em var iabl e $$ cont ains t he pr ocess ID of
t he cur r ent pr ogr am. (See Day 17, "Syst em
Var iabl es," f or mor e inf or mat ion on $$.)
G time r et ur ns t he cur r ent t ime val ue.
G Many of t he f unct ions descr ibed on Day 15,
"Syst em Funct ions," r et ur n usef ul val ues. For
exampl e, getppid r et ur ns t he pr ocess ID of t he
pr ogr am's par ent pr ocess.
For best r esul t s, combine t wo or mor e of t hese using t he
| (bit wise OR) oper at or
String-Manipulation Functions
This sect ion descr ibes t he buil t -in Per l f unct ions t hat manipul at e char act er st r ings.
These f unct ions enabl e you t o do t he f ol l owing:
G Sear ch f or a subst r ing in a char act er st r ing
G Cr eat e a st r ing
G Repl ace a subst r ing wit hin a st r ing
The index Function
The index f unct ion pr ovides a way of indicat ing t he l ocat ion of a subst r ing in a st r ing.
The synt ax f or t he index f unct ion is
position = index (string, substring);
string is t he char act er st r ing t o sear ch in, and substring is t he char act er st r ing being
sear ched f or . position r et ur ns t he number of char act er s skipped bef or e substring is
l ocat ed; if substring is not f ound, position is set t o -1.
List ing 13.7 is a pr ogr am t hat uses index t o l ocat e a subst r ing in a st r ing.

List ing 13.7. A pr ogr am t hat uses t he index f unct ion.
1: #!/usr/local/bin/perl
2:
3: $input = <STDIN>;
4: $position = index($input, "the");
5: if ($position >= 0) {
6: print ("pattern found at position $position\n");
7: } else {
8: print ("pattern not found\n");
9: }

$ program13 7
Here is the input line I have typed.
pattern found at position 8
$
This pr ogr am sear ches f or t he f ir st occur r ence of t he wor d the. If it is f ound,
t he pr ogr am pr int s t he l ocat ion of t he pat t er n; if it is not f ound, t he pr ogr am pr int s
pattern not found.
You can use t he index f unct ion t o f ind mor e t han one copy of a subst r ing in a st r ing. To
do t his, pass a t hir d ar gument t o index, which t el l s it how many char act er s t o skip
bef or e st ar t ing t o sear ch. For exampl e:
$position = index($line, "foo", 5);
This cal l t o index skips f ive char act er s bef or e st ar t ing t o sear ch f or foo in t he st r ing
st or ed in $line. As bef or e, if index f inds t he subst r ing, it r et ur ns t he t ot al number of
char act er s skipped (incl uding t he number specif ied by t he t hir d ar gument t o index). If
index does not f ind t he subst r ing in t he por t ion of t he st r ing t hat it sear ches, it r et ur ns
-1.
This f eat ur e of index enabl es you t o f ind al l occur r ences of a subst r ing in a st r ing.
List ing 13.8 is a modif ied ver sion of List ing 13.7 t hat sear ches f or al l occur r ences of the
in an input l ine.

List ing 13.8. A pr ogr am t hat uses index t o sear ch a l ine r epeat edl y.
1: #!/usr/local/bin/perl
2:
3: $input = <STDIN>;
4: $position = $found = 0;
5: while (1) {
6: $position = index($input, "the", $position);
7: last if ($position == -1);
8: if ($found == 0) {
9: $found = 1;
10: print ("pattern found - characters skipped:");
11: }
12: print (" $position");
13: $position++;
14: }
15: if ($found == 0) {
16: print ("pattern not found\n");
17: } else {
18: print ("\n");
19: }

$ program13 8
Here is the test line containing the words.
pattern found - characters skipped: 8 33
$
Line 6 of t his pr ogr am cal l s index. Because t he init ial val ue of $position is 0,
t he f ir st cal l t o index st ar t s sear ching f r om t he beginning of t he st r ing. Eight char act -
er s ar e skipped bef or e t he f ir st occur r ence of the is f ound; t his means t hat $position is
assigned 8.
Line 7 t est s whet her a mat ch has been f ound by compar ing $position wit h -1, which is
t he val ue index r et ur ns when it does not f ind t he st r ing f or which it is l ooking. Because
a mat ch has been f ound, t he l oop cont inues t o execut e.
When t he l oop it er at es again, l ine 6 cal l s index again. This t ime, index skips nine
char act er s bef or e beginning t he sear ch again, which ensur es t hat t he pr eviousl y f ound
occur r ence of the is skipped. A t ot al of 33 byt es ar e skipped bef or e the is f ound again.
Once again, t he l oop cont inues, because t he condit ional expr ession in l ine 7 is f al se.
On t he f inal it er at ion of t he l oop, l ine 6 cal l s index and skips 34 char act er s bef or e
st ar t ing t he sear ch. This t ime, the is not f ound, index r et ur ns -1, and t he condit ional
expr ession in l ine 7 is t r ue. At t his point , t he l oop t er minat es.
NOTE
To ext r act a subst r ing f ound by index, use t he substr
f unct ion, which is descr ibed l at er in t oday's l esson
The rindex Function
The rindex f unct ion is simil ar t o t he index f unct ion. The onl y dif f er ence is t hat rindex
st ar t s sear ching f r om t he r ight end of t he st r ing, not t he l ef t .
The synt ax f or t he rindex f unct ion is
position = rindex (string, substring);
This synt ax is ident ical t o t he synt ax f or index. string is t he char act er st r ing t o sear ch
in, and substring is t he char act er st r ing being sear ched f or . position r et ur ns t he
number of char act er s skipped bef or e substring is l ocat ed; if substring is not f ound,
position is set t o -1.
The f ol l owing is an exampl e:
$string = "Here is the test line containing the words.";
$position = rindex($string, "the");
In t his exampl e, rindex f inds t he second occur r ence of the. As wit h index, rindex r et ur ns
t he number of char act er s bet ween t he l ef t end of t he st r ing and t he l ocat ion of t he
f ound subst r ing. In t his case, 33 char act er s ar e skipped, and $position is assigned 33.
You can specif y a t hir d ar gument t o rindex, indicat ing t he maximum number of
char act er s t hat can be skipped. For exampl e, if you want rindex t o f ind t he f ir st
occur r ence of the in t he pr eceding exampl e, you can cal l it as f ol l ows:
$string = "Here is the test line containing the words.";
$position = rindex($string, "the", 32);
Her e, t he second occur r ence of the cannot be mat ched, because it is t o t he r ight of t he
specif ied l imit of 32 skipped char act er s. rindex, t her ef or e, f inds t he f ir st occur r ence of
the. Because t her e ar e eight char act er s bet ween t he beginning of t he st r ing and t he
occur r ence, $position is assigned 8.
Like index, rindex r et ur ns -1 if it cannot f ind t he st r ing it is l ooking f or .
The length Function
The length f unct ion r et ur ns t he number of char act er s cont ained in a char act er st r ing.
The synt ax f or t he length f unct ion is
num = length (string);
string is t he char act er st r ing f or which you want t o det er mine t he l engt h, and num is
t he r et ur ned l engt h.
Her e is an exampl e using length:
$string = "Here is a string";
$strlen = length($string);
In t his exampl e, length det er mines t hat t he string in $string is 16 char act er s l ong, and
it assigns 16 t o $strlen.
List ing 13.9 is a pr ogr am t hat cal cul at es t he aver age wor d l engt h used in an input f il e.
(This is somet imes used t o det er mine t he "compl exit y" of t he t ext .) Number s ar e skipped.

List ing 13.9. A pr ogr am t hat demonst r at es t he use of length.
1: #!/usr/local/bin/perl
2:
3: $wordcount = $charcount = 0;
4: while ($line = <STDIN>) {
5: @words = split(/\s+/, $line);
6: foreach $word (@words) {
7: next if ($word =~ /^\d+\.?\d+$/);
8: $word =~ s/[,.;:]$//;
9: $wordcount += 1;
10: $charcount += length($word);
11: }
12: }
13: print ("Average word length: ", $charcount / $wordcount, "\n");

$ program13 9
Here is the test input.
Here is the last line.
^D
Average word length: 3.5
$
This pr ogr am r eads a l ine of input at a t ime f r om t he st andar d input f il e,
br eaking t he input l ine int o wor ds. Line 7 t est s whet her t he wor d is a number , and skips
it if it is. Line 8 st r ips any t r ail ing punct uat ion char act er f r om t he wor d, which ensur es
t hat t he punct uat ion is not count ed as par t of t he wor d l engt h.
Line 10 cal l s length t o r et r ieve t he number of char act er s in t he wor d. This number is
added t o $charcount, which cont ains t he t ot al number of char act er s in al l of t he wor ds
t hat have been r ead so f ar . To det er mine t he aver age wor d l engt h of t he f il e, l ine 13
t akes t his val ue and divides it by t he number of wor ds in t he f il e, which is st or ed in
$wordcount.
Retrieving String Length Using tr
The tr f unct ion pr ovides anot her way of det er mining t he l engt h of a char act er st r ing,
in conjunct ion wit h t he buil t -in syst em var iabl e $_.
The synt ax f or t he tr f unct ion is
tr/sourcelist/replacelist/
sourcelist is t he l ist of char act er s t o r epl ace, and replacelist is t he l ist of char act er s
t o r epl ace wit h. (For det ail s, see t he f ol l owing l ist ing and t he expl anat ion pr ovided
wit h it .)
List ing 13.10 shows how tr wor ks.

List ing 13.10. A pr ogr am t hat uses tr t o r et r ieve t he l engt h of a st r ing.
1: #!/usr/local/bin/perl
2:
3: $string = "here is a string";
4: $_ = $string;
5: $length = tr/a-zA-Z /a-zA-Z /;
6: print ("the string is $length characters long\n");

$ program13 10
the string is 16 characters long
$
Line 3 of t his pr ogr am cr eat es a st r ing named here is a string and assigns it
t o t he scal ar var iabl e $string. Line 4 copies t his st r ing int o a buil t -in scal ar var iabl e,
$_.
Line 5 expl oit s t wo f eat ur es of t he tr oper at or t hat have not yet been discussed:
G If t he val ue t o be t r ansl at ed is not expl icit l y specif ied by means of t he =~
oper at or , tr assumes t hat t he val ue is st or ed in $_.
G tr r et ur ns t he number of char act er s t r ansl at ed.
In l ine 5, bot h t he sear ch pat t er n (t he set of char act er s t o l ook f or ) and t he
r epl acement pat t er n (t he char act er s t o r epl ace t hem wit h) ar e t he same. This pat t er n,
/a-zA-Z /, t el l s tr t o sear ch f or al l l ower case l et t er s, upper case l et t er s, and bl ank
spaces, and t hen r epl ace t hem wit h t hemsel ves. This pat t er n mat ches ever y char act er in
t he st r ing, which means t hat ever y char act er is being t r ansl at ed.
Because ever y char act er is being t r ansl at ed, t he number of char act er s t r ansl at ed is
equival ent t o t he l engt h of t he st r ing. This st r ing l engt h is assigned t o t he scal ar
var iabl e $length.
tr can be used al so t o count t he number of occur r ences of a specif ic char act er , as shown
in List ing 13.11.

List ing 13.11. A pr ogr am t hat uses tr t o count t he occur r ences of
specif ic char act er s.
1: #!/usr/local/bin/perl
2:
3: $punctuation = $blanks = $total = 0;
4: while ($input = <STDIN>) {
5: chop ($input);
6: $total += length($input);
7: $_ = $input;
8: $punctuation += tr/,:;.-/,:;.-/;
9: $blanks += tr/ / /;
10: }
11: print ("In this file, there are:\n");
12: print ("\t$punctuation punctuation characters,\n");
13: print ("\t$blanks blank characters,\n");
14: print ("\t", $total - $punctuation - $blanks);
15: print (" other characters.\n");

$ program13 11
Here is a line of input.
This line, another line, contains punctuation.
^D
In this file, there are:
4 punctuation characters,
10 blank characters,
56 other characters.
$
This pr ogr am uses t he scal ar var iabl e $total and t he buil t -in f unct ion length
t o count t he t ot al number of char act er s in t he input f il e (excl uding t he t r ail ing
newl ine char act er s, which ar e r emoved by t he cal l t o chop in l ine 5).
Lines 8 and 9 use tr t o count t he number of occur r ences of par t icul ar char act er s. Line 8
r epl aces al l punct uat ion char act er s wit h t hemsel ves; t he number of r epl acement s
per f or med, and hence t he number of punct uat ion char act er s f ound, is added t o t he t ot al
st or ed in $punctuation. Simil ar l y, l ine 9 r epl aces al l bl anks wit h t hemsel ves and adds
t he number of bl anks f ound t o t he t ot al st or ed in $blanks. In bot h cases, tr oper at es on
t he cont ent s of t he scal ar var iabl e $_, because t he =~ oper at or has not been used t o
specif y anot her val ue t o t r ansl at e.
Line 14 uses $total, $punctuation, and $blanks t o cal cul at e t he t ot al number of
char act er s t hat ar e not bl ank and not punct uat ion.
NOTE
Many ot her f unct ions and oper at or s accept $_ as t he
def aul t var iabl e on which t o wor k. For exampl e, l ines 4-
7 of t his pr ogr am al so can be wr it t en as f ol l ows:
while (<STDIN>) {
chop();
$total += length();
For mor e inf or mat ion on $_, r ef er t o Day 17, "Syst em
Var iabl es.
The pos Function
The pos f unct ion, def ined onl y in Per l 5, r et ur ns t he l ocat ion of t he l ast pat t er n mat ch
in a st r ing. It is ideal f or use when r epeat ed pat t er n mat ches ar e specif ied using t he g
(gl obal ) pat t er n-mat ching oper at or .
The synt ax f or t he pos f unct ion is
offset = pos(string);
string is t he st r ing whose pat t er n is being mat ched. offset is t he number of char act er s
al r eady mat ched or skipped.
List ing 13.12 il l ust r at es t he use of pos.

List ing 13.12. A pr ogr am t hat uses pos t o displ ay pat t er n mat ch
posit ions.
1: #!/usr/local/bin/perl
2:
3: $string = "Mississippi";
4: while ($string =~ /i/g) {
5: $position = pos($string);
6: print("matched at position $position\n");
7: }

$ program13 12
matched at position 2
matched at position 5
matched at position 8
matched at position 11
This pr ogr am l oops ever y t ime an i in Mississippi is mat ched. The number
displ ayed by l ine 6 is t he number of char act er s t o skip t o r each t he point at which
pat t er n mat ching r esumes. For exampl e, t he f ir st i is t he second char act er in t he st r ing,
so t he second pat t er n sear ch st ar t s at posit ion 2.
NOTE
You can al so use pos t o change t he posit ion at which
pat t er n mat ching is t o r esume. To do t his, put t he cal l t o
pos on t he l ef t side of an assignment :
pos($string) = 5;
This t el l s t he Per l int er pr et er t o st ar t t he next pat t er n
sear ch wit h t he sixt h char act er in t he st r ing. (To
r est ar t sear ching f r om t he beginning, use 0.
The substr Function
The substr f unct ion l et s you assign a par t of a char act er st r ing t o a scal ar var iabl e (or
t o a component of an ar r ay var iabl e).
The synt ax f or cal l s t o t he substr f unct ion is
substr (expr, skipchars, length)
expr is t he char act er st r ing f r om which a subst r ing is t o be copied; t his char act er st r ing
can be t he val ue st or ed in a var iabl e or t he val ue r esul t ing f r om t he eval uat ion of an
expr ession. skipchars is t he number of char act er s t o skip bef or e st ar t ing copying. length
is t he number of char act er s t o copy; length can be omit t ed, in which case t he r est of t he
st r ing is copied.
List ing 13.13 pr ovides a simpl e exampl e of substr.

List ing 13.13. A pr ogr am t hat demonst r at es t he use of substr.
1: #!/usr/local/bin/perl
2:
3: $string = "This is a sample character string";
4: $sub1 = substr ($string, 10, 6);
5: $sub2 = substr ($string, 17);
6: print ("\$sub1 is \"$sub1\"\n\$sub2 is \"$sub2\"\n");

$ program13 13
$sub1 is "sample"
$sub2 is "character string"
$
Line 4 cal l s substr, which copies a por t ion of t he st r ing st or ed in $string. This
cal l specif ies t hat t en char act er s ar e t o be skipped bef or e copying st ar t s, and t hat a
t ot al of six char act er s ar e t o be copied. This means t hat t he subst r ing sample is copied
and st or ed in $sub1.
Line 5 is anot her cal l t o substr. Her e, 17 char act er s ar e skipped. Because t he l engt h
f iel d is omit t ed, substr copies t he r emaining char act er s in t he st r ing. This means t hat
t he subst r ing character string is copied and st or ed in $sub2.
Not e t hat l ines 4 and 5 do not change t he cont ent s of $string.
String Insertion Using substr
In List ing 13.13, which you've just seen, cal l s t o substr appear t o t he r ight of t he
assignment oper at or =. This means t hat t he r et ur n val ue f r om substr-t he ext r act ed
subst r ing-is assigned t o t he var iabl e appear ing t o t he l ef t of t he =.
Cal l s t o substr can appear al so on t he l ef t of t he assignment oper at or =. In t his case,
t he por t ion of t he st r ing specif ied by substr is replaced by t he val ue appear ing t o t he
r ight of t he assignment oper at or .
The synt ax f or t hese cal l s t o substr is basical l y t he same as bef or e:
substr (expr, skipchars, length) = newval;
Her e, expr must be somet hing t hat can be assigned t o-f or exampl e, a scal ar var iabl e or
an el ement of an ar r ay var iabl e. skipchars r epr esent s t he number of char act er s t o skip
bef or e beginning t he over wr it ing oper at ion, which cannot be gr eat er t han t he l engt h
of t he st r ing. length is t he number of char act er s t o be r epl aced by t he over wr it ing
oper at ion. If length is not specif ied, t he r emainder of t he st r ing is r epl aced.
newval is t he st r ing t hat r epl aces t he subst r ing specif ied by skipchars and length. If
newval is l ar ger t han length, t he char act er st r ing aut omat ical l y gr ows t o hol d it , and
t he r est of t he st r ing is pushed aside (but not over wr it t en). If newval is smal l er t han
length, t he char act er st r ing aut omat ical l y shr inks. Basical l y, ever yt hing appear s
wher e it is supposed t o wit hout you having t o wor r y about it .
NOTE
By t he way, t hings t hat can be assigned t o ar e somet imes
known as lvalues, because t hey appear t o t he l ef t of
assignment st at ement s (t he l in lvalue st ands f or "l ef t ").
Things t hat appear t o t he r ight of assignment st at ement s
ar e, simil ar l y, cal l ed rvalues.
This book does not use t he t er ms lvalue and rvalue, but you
might f ind t hat knowing t hem wil l pr ove usef ul when
you r ead ot her books on pr ogr amming l anguages
List ing 13.14 is an exampl e of a pr ogr am t hat uses substr t o r epl ace por t ions of a st r ing.

List ing 13.14. A pr ogr am t hat r epl aces par t s of a st r ing using substr.
1: #!/usr/local/bin/perl
2:
3: $string = "Here is a sample character string";
4: substr($string, 0, 4) = "This";
5: substr($string, 8, 1) = "the";
6: substr($string, 19) = "string";
7: substr($string, -1, 1) = "g.";
8: substr($string, 0, 0) = "Behold! ";
9: print ("$string\n");

$ program13 14
Behold! This is the sample string.
$
This pr ogr am il l ust r at es t he many ways you can use substr t o r epl ace
por t ions of a st r ing.
The cal l t o substr in l ine 4 specif ies t hat no char act er s ar e t o be skipped bef or e
over wr it ing, and t hat f our char act er s in t he or iginal st r ing ar e t o be over wr it t en. This
means t hat t he subst r ing Here is r epl aced by This, and t hat t he f ol l owing is t he new
val ue of t he st r ing st or ed in $string:
This is a sample character string
Simil ar l y, t he cal l t o substr in l ine 5 specif ies t hat eight char act er s ar e t o be skipped
and one char act er is t o be r epl aced. This means t hat t he wor d a is r epl aced by the. Now,
$string cont ains t he f ol l owing:
This is the sample character string
Not e t hat t he char act er st r ing is now l ar ger t han t he or iginal , because t he new
subst r ing, the, is l ar ger t han t he subst r ing it r epl aced.
Line 6 is an exampl e of a cal l t o substr t hat shr inks t he st r ing. Her e, 19 char act er s ar e
skipped, and t he r est of t he st r ing is r epl aced by t he subst r ing string (because no length
f iel d has been specif ied). Now, t he f ol l owing is t he val ue st or ed in $string:
This is the sample string
In l ine 7, t he cal l t o substr is passed -1 in t he skipchars f iel d and is passed 1 in t he
length f iel d. This t el l s substr t o r epl ace t he l ast char act er of t he st r ing wit h t he
subst r ing g. (g f ol l owed by a per iod). $string now cont ains
This is the sample string.
NOTE
If substr is passed a skipchars val ue of -n, wher e n is a
posit ive int eger , substr skips t o n char act er s f r om t he
r ight end of t he st r ing. For exampl e, t he f ol l owing cal l
r epl aces t he l ast t wo char act er s in $string wit h t he
st r ing hello:
substr($string, -2, 2) = "hello"
Final l y, l ine 8 specif ies t hat no char act er s ar e t o be skipped and no char act er s ar e t o be
r epl aced. This means t hat t he subst r ing "Behold! " (incl uding a t r ail ing space) is added
t o t he f r ont of t he exist ing st r ing and t hat $string now cont ains t he f ol l owing:
Behold! This is the sample string.
Line 9 pr int s t his f inal val ue of $string.
TIP
If you ar e a C pr ogr ammer and ar e used t o manipul at ing
st r ings using point er s, not e t hat substr wit h a l engt h
f iel d of 1 can be used t o simul at e point er -l ike behavior
in Per l .
For exampl e, you can simul at e t he C st at ement
char = *str++;
as f ol l ows in Per l :
$char = substr($str, $offset++, 1);
You'l l need t o def ine a count er var iabl e (such as
$offset) t o keep t r ack of wher e you ar e in t he st r ing.
However , t his is no mor e of a chor e t han r emember ing t o
init ial ize your C point er var iabl e.
You can simul at e t he f ol l owing C st at ement :
*str++ = char;
by assigning val ues using substr in t he same way:
substr($str, $offset++, 1) = $char;
You shoul dn't use substr in t his way unl ess you r eal l y
have t o. Per l suppl ies mor e power f ul and usef ul t ool s,
such as pat t er n mat ching and subst it ut ion, t o get t he job
done mor e ef f icient l y
The study Function
The study f unct ion is a special f unct ion t hat t el l s t he Per l int er pr et er t hat t he
specif ied scal ar var iabl e is about t o be sear ched many t imes.
The synt ax f or t he study f unct ion is
study (scalar);
scalar is t he scal ar var iabl e t o be "st udied." The Per l int er pr et er t akes t he val ue
st or ed in t he specif ied scal ar var iabl e and r epr esent s it in an int er nal f or mat t hat
al l ows f ast er access.
For exampl e:
study ($myvar);
Her e, t he val ue st or ed in t he scal ar var iabl e $myvar is about t o be r epeat edl y sear ched.
You can cal l study f or onl y one scal ar var iabl e at a t ime. Pr evious cal l s t o study ar e
super seded if study is cal l ed again.
TIP
To check whet her study act ual l y makes your pr ogr am
mor e ef f icient , use t he f unct ion times, which displ ays
t he user and CPU t imes f or a pr ogr am or pr ogr am
f r agment . (times is discussed ear l ier t oday.
Case Conversion Functions
Per l 5 pr ovides f unct ions t hat per f or m case conver sion on st r ings. These ar e
G The lc f unct ion, which conver t s a st r ing t o l ower case
G The uc f unct ion, which conver t s a st r ing t o upper case
G The lcfirst f unct ion, which conver t s t he f ir st char act er of a st r ing t o l ower case
G The ucfirst f unct ion, which conver t s t he f ir st char act er of a st r ing t o upper case
The lc and uc Functions
The synt ax f or t he lc and uc f unct ions is
retval = lc(string);
retval = uc(string);
string is t he st r ing t o be conver t ed. retval is a copy of t he st r ing, conver t ed t o eit her
l ower case or upper case:
$lower = lc("aBcDe"); # $lower is assigned "abcde"
$upper = uc("aBcDe"); # $upper is assigned "ABCDE"
The lcfirst and ucfirst Functions
The synt ax f or t he lcfirst and ucfirst f unct ions is
retval = lcfirst(string);
retval = ucfirst(string);
string is t he st r ing whose f ir st char act er is t o be conver t ed. retval is a copy of t he
st r ing, wit h t he f ir st char act er conver t ed t o eit her l ower case or upper case:
$lower = lcfirst("HELLO"); # $lower is assigned "hELLO"
$upper = ucfirst("hello"); # $upper is assigned "Hello"
The quotemeta Function
The quotemeta f unct ion, def ined onl y in Per l 5, pl aces a backsl ash char act er in f r ont of
any non-wor d char act er in a st r ing. The f ol l owing st at ement s ar e equival ent :
$string = quotemeta($string);
$string =~ s/(\W)/\\$1/g;
The synt ax f or quotemeta is
newstring = quotemeta(oldstring);
oldstring is t he st r ing t o be conver t ed. newstring is t he st r ing wit h backsl ashes added.
quotemeta is usef ul when a st r ing is t o be used in a subsequent pat t er n-mat ching
oper at ion. It ensur es t hat t her e ar e no char act er s in t he st r ing which ar e t o be t r eat ed
as special pat t er n-mat ching char act er s.
The join Function
The join f unct ion has been used many t imes in t his book. It t akes t he el ement s of a l ist
and conver t s t hem int o a singl e char act er st r ing.
The synt ax f or t he join f unct ion is
join (joinstr, list);
joinstr is t he char act er st r ing t hat is t o be used t o gl ue t he el ement s of list t oget her .
For exampl e:
@list = ("Here", "is", "a", "list");
$newstr = join ("::", @list);
Af t er join is cal l ed, t he val ue st or ed in $newstr becomes t he f ol l owing st r ing:
Here::is::a::list
The join st r ing, :: in t his case, appear s bet ween each pair of joined el ement s. The most
common join st r ing is a singl e bl ank space; however , you can use any val ue as t he join
st r ing, incl uding t he val ue r esul t ing f r om an expr ession.
The sprintf Function
The sprintf f unct ion behaves l ike t he printf f unct ion def ined on Day 11, "For mat t ing
Your Out put ," except t hat t he f or mat t ed st r ing is r et ur ned by t he f unct ion inst ead of
being wr it t en t o a f il e. This enabl es you t o assign t he st r ing t o anot her var iabl e.
The synt ax f or t he sprintf f unct ion is
sprintf (string, fields);
string is t he char act er st r ing t o pr int , and fields is a l ist of val ues t o subst it ut e int o
t he st r ing.
List ing 13.15 is an exampl e t hat uses sprintf t o buil d a st r ing.

List ing 13.15. A pr ogr am t hat uses sprintf.
1: #!/usr/local/bin/perl
2:
3: $num = 26;
4: $outstr = sprintf("%d = %x hexadecimal or %o octal\n",
5: $num, $num, $num);
6: print ($outstr);

$ program14_9
26 = 1a hexadecimal or 32 octal
$
Lines 4 and 5 t ake t hr ee copies of t he val ue st or ed in $num and incl ude t hem as
par t of a st r ing. The f iel d specif ier s %d, %x, and %o indicat e how t he val ues ar e t o be
f or mat t ed.
%d Indicat es an int eger displ ayed in t he usual decimal (base-10) f or mat
%x Indicat es an int eger displ ayed in hexadecimal (base-16) f or mat
%o Indicat es an int eger displ ayed in oct al (base-8) f or mat
The cr eat ed st r ing is r et ur ned by sprintf. Once it has been cr eat ed, it behaves just l ike
any ot her Per l char act er st r ing; in par t icul ar , it can be assigned t o a scal ar var iabl e, as
in t his exampl e. Her e, t he st r ing cont aining t he t hr ee copies of $num is assigned t o t he
scal ar var iabl e $outstr. Line 6 t hen pr int s t his st r ing.
NOTE
For mor e inf or mat ion on f iel d specif ier s or on how
printf wor ks, r ef er t o Day 11, which l ist s t he f iel d
specif ier s def ined and pr ovides a descr ipt ion of t he
synt ax of printf
Summary
Today, you l ear ned about t hr ee t ypes of buil t -in Per l f unct ions: f unct ions t hat handl e
pr ocess and pr ogr am cont r ol , f unct ions t hat per f or m mat hemat ical oper at ions, and
f unct ions t hat manipul at e st r ings.
Wit h t he pr ocess- and pr ogr am-cont r ol f unct ions, you can st ar t new pr ocesses, st op t he
cur r ent pr ogr am or ot her pr ocesses, or t empor ar il y hal t t he cur r ent pr ogr am. You al so
can cr eat e a pipe t hat sends dat a f r om one of your cr eat ed pr ocesses t o anot her .
Wit h t he f unct ions t hat per f or m mat hemat ical oper at ions, you can obt ain t he sine,
cosine, and ar ct angent of a val ue. You al so can cal cul at e t he nat ur al l ogar it hm and
squar e r oot of a val ue, or use t he val ue as an exponent of base e.
You al so can gener at e r andom number s and def ine t he seed t o use when gener at ing t he
number s.
Funct ions t hat sear ch char act er st r ings incl ude index, which sear ches f or a subst r ing
st ar t ing f r om t he l ef t of a st r ing, and rindex, which sear ches f or a subst r ing st ar t ing
f r om t he r ight of a st r ing. You can r et r ieve t he l engt h of a char act er st r ing using
length. By using t he t r ansl at e oper at or tr in conjunct ion wit h t he syst em var iabl e $_,
you can count t he number of occur r ences of a par t icul ar char act er or set of char act er s
in a st r ing. The pos f unct ion enabl es you t o det er mine or set t he cur r ent pat t er n-
mat ching l ocat ion in a st r ing.
The f unct ion substr enabl es you t o ext r act a subst r ing f r om a st r ing and use it in an
expr ession or assignment st at ement . substr al so can be used t o r epl ace a por t ion of a
st r ing or append t o t he f r ont or back end of t he st r ing.
The lc and uc f unct ions conver t st r ings t o l ower case or upper case. To conver t t he f ir st
l et t er of a st r ing t o l ower case or upper case, use lcfirst or ucfirst.
quotemeta pl aces a backsl ash in f r ont of ever y non-wor d char act er in a st r ing.
You can cr eat e new char act er st r ings using join and sprintf. join cr eat es a st r ing by
joining el ement s of a l ist , and sprintf buil ds a st r ing using f iel d specif ier s t hat specif y
t he st r ing f or mat .
Q&A
Q: How does Per l gener at e r andom number s?
A: Basical l y, by per f or ming ar it hmet ic oper at ions using ver y l ar ge number s. If t he
number s f or t hese ar it hmet ic oper at ions ar e car ef ul l y chosen, a sequence of
"pseudo-r andom" number s can be gener at ed by r epeat ing t he set of ar it hmet ic
oper at ions and r et ur ning t heir r esul t s.
The r andom-number seed pr ovided by srand suppl ies t he init ial val ue f or one of
t he number s used in t he set of ar it hmet ic oper at ions. This ensur es t hat t he
sequence of pseudo-r andom number s st ar t s wit h a dif f er ent r esul t each t ime.
Q: What pr ogr ams can be cal l ed using system?
A: Any pr ogr am t hat you can r un f r om your t er minal can be r un using system.
Q: How many pr ocesses can a pr ogr am cr eat e using fork?
A: Per l pr ovides no l imit on how many pr ocesses can be cr eat ed at a t ime. However ,
t he per f or mance of your syst em wil l be adver sel y af f ect ed if you gener at e t oo
many pr ocesses at once. In par t icul ar , pr ogr ams t hat cal l fork and wind up in an
inf init e l oop ar e somet imes cal l ed f or k bombs, because t hey gener at e t housands
of pr ocesses and gr ind your machine t o an ef f ect ive hal t . (Your syst em
administ r at or wil l not be pl eased wit h you if you do t his!)
Q: How can I send signal s t o a pr ocess wit hout kil l ing it ?
A: The kill f unct ion act ual l y can send any signal suppor t ed by your machine t o
any r unning pr ocess (t hat you can access).
Ref er t o t he UNIX syst em document at ion f or det ail s on t he signal s you can send
and what t heir names ar e.
Q: What is t he dif f er ence bet ween t he %d and %ld f or mat specif ier s in sprintf?
A: %ld def ines a "l ong int eger ." It r ef er s t o t he l ar gest number of bit s t hat your
l ocal machine can use t o st or e an int eger . (This is of t en 32 bit s.) %d, on t he ot her
hand, is equival ent t o your machine's st andar d int eger f or mat . On some machines,
%ld and %d ar e equival ent . If you ar e not sur e how many bit s your machine uses
t o st or e int eger s, or you know you ar e going t o be deal ing wit h l ar ge number s,
it 's saf er t o use %ld. (The same hol ds t r ue f or al l ot her int eger f or mat s, such as
%lx and %lo.)
Q: What is t he dif f er ence bet ween t he %c and %s f or mat specif ier s in sprintf?
A: %c undoes t he ef f ect of t he ord f unct ion. It conver t s a scal ar val ue int o t he
equival ent ASCII char act er . (It s behavior is simil ar t o t hat of t he chr f unct ion
in Pascal .) %s t r eat s a scal ar val ue as a char act er st r ing and inser t s it int o t he
st r ing at t he pl ace specif ied.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. What do t hese f unct ions do?
a. srand
b. pipe
c. atan2
d. sleep
e. gmtime
2. Expl ain t he dif f er ences bet ween fork, system, and exec.
3. Expl ain t he dif f er ences bet ween wait and waitpid.
4. How can you obt ain t he val ue of p?
5. How can you obt ain t he val ue of t he mat hemat ical const ant e?
6. What sprintf specif ier s pr oduce t he f ol l owing?
a. A hexadecimal number
b. An oct al number
c. A f l oat ing-point number in exponent ial f or mat
d. A f l oat ing-point number in st andar d (f ixed) f or mat
7. If t he scal ar var iabl e $string cont ains abcdefgh, what do t he f ol l owing cal l s
r et ur n?
a substr ($string, 0, 3);
b. substr ($string, 4);
c. substr ($string, -2, 2);
d. substr ($string, 2, 0);
8. Assume $string cont ains t he val ue abcdabcd. What val ue is r et ur ned by each of
t he f ol l owing cal l s?
a. index ($string, "bc");
b. index ($string, "bcde");
c. index ($string, "bc", 1);
d. index ($string, "cd", 3);
e. rindex ($string, "bc");
9. Assume $string cont ains t he val ue abcdabcd\n (t he l ast char act er being a
t r ail ing newl ine char act er ). What is r et ur ned in $retval by t he f ol l owing?
a. $_ = $string; $retval = tr/ab/ab/;
b. $retval = length ($string);
Exercises
1. Wr it e a pr ogr am t hat uses fork and waitpid t o gener at e a t ot al of t hr ee pr ocesses
(incl uding t he pr ogr am). Have each pr ocess pr int a l ine, and have t he l ines appear
in a specif ied or der .
2. Wr it e a pr ogr am t hat r eads input f r om a f il e named temp and wr it es it t o t he
st andar d out put f il e. Wr it e anot her pr ogr am t hat r eads input f r om t he st andar d
out put f il e, wr it es it t o temp, and uses exec t o cal l t he f ir st pr ogr am.
3. Wr it e a pr ogr am t hat pr int s t he nat ur al l ogar it hm of t he int eger s bet ween 1 and
100.
4. Wr it e a pr ogr am t hat comput es t he sum of t he number s f r om 1 t o 10 ** n f or
val ues of n f r om 1 t o 6. For each comput ed val ue, use times t o cal cul at e t he
amount of t ime each comput at ion t akes. Pr int t hese cal cul at ion t imes.
5. Wr it e a pr ogr am t hat r eads an int eger val ue and pr int s t he sine, cosine, and
t angent of t he val ue. Assume t hat t he input val ue is in degr ees.
6. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
print ("Here is a line of output. ");
system ("w");
print ("Here is the rest of the line.\n");
7. Wr it e a pr ogr am t hat uses index t o pr int out t he l ocat ions of t he l et t er s a, e, i, o,
and u in an input l ine.
8. Wr it e a pr ogr am t hat uses rindex t o do t he same t hing as t he one in Exer cise 1.
9. Wr it e a pr ogr am t hat uses substr t o do t he same t hing as t he one in Exer cise 1.
(Hint : This wil l r equir e many cal l s t o substr!)
10. Wr it e a pr ogr am t hat uses tr t o count al l t he occur r ences of a, e, i, o, and u in an
input l ine.
11. Wr it e a pr ogr am t hat r eads a number . If t he number is a f l oat ing-point val ue,
pr int it in exponent ial and f ixed-point f or m. If t he number is an int eger , pr int it in
decimal , oct al , and hexadecimal f or m. (Hint : Recal l t hat printf and sprintf use
t he same f iel d specif ier s.)
12. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
$mystring = <STDIN>;
$lastfound = length ($mystring);
while ($lastfound != -1) {
$lastfound = index($mystring, "xyz", $lastfound);
}

Chapter 14
Scalar-Conversion and List-Manipulation Functions
CONTENTS
G The chop Funct ion
G The chomp Funct ion
G The crypt Funct ion
G The hex Funct ion
G The int Funct ion
G The oct Funct ion
H The oct Funct ion and Hexadecimal Int eger s
G The ord and chr Funct ions
G The scalar Funct ion
G The pack Funct ion
H The pack Funct ion and C Dat a Types
G The unpack Funct ion
H Unpacking St r ings
H Skipping Char act er s When Unpacking
H The unpack Funct ion and uuencode
G The vec Funct ion
G The defined Funct ion
G The undef Funct ion
G Ar r ay and List Funct ions
H The grep Funct ion
H The splice Funct ion
H The shift Funct ion
H The unshift Funct ion
H The push Funct ion
H The pop Funct ion
H Cr eat ing St acks and Queues
H The split Funct ion
H The sort and reverse Funct ions
H The map Funct ion
H The wantarray Funct ion
G Associat ive Ar r ay Funct ions
H The keys Funct ion
H The values Funct ion
H The each Funct ion
H The delete Funct ion
H The exists Funct ion
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today, you l ear n about t he buil t -in Per l f unct ions t hat conver t scal ar val ues f r om one
f or m t o anot her , and t he Per l f unct ions t hat deal wit h var iabl es t hat have not had
val ues def ined f or t hem.
You al so l ear n about t he buil t -in Per l f unct ions t hat manipul at e l ist s and ar r ay
var iabl es. These f unct ions ar e divided int o t wo gr oups:
G The f unct ions t hat manipul at e st andar d ar r ay var iabl es and t heir l ist s
G The f unct ions t hat manipul at e associat ive ar r ays
Many of t he f unct ions descr ibed in t oday's l esson use
f eat ur es of t he UNIX oper at ing syst em. If you ar e using
Per l on a machine t hat is not r unning UNIX, some of
t hese f unct ions might not be def ined or might behave
dif f er ent l y.
Check t he document at ion suppl ied wit h your ver sion of
Per l f or det ail s on which f unct ions ar e suppor t ed or
emul at ed on your machine
The chop Function
The chop f unct ion was f ir st discussed on Day 3, "Under st anding Scal ar Val ues." It
r emoves t he l ast char act er f r om a scal ar val ue.
The synt ax f or t he chop f unct ion is
chop (var);
var can be eit her a scal ar val ue or a l ist , as descr ibed in t he f ol l owing par agr aphs.
For exampl e:
$mystring = "This is a string";
chop ($mystring);
# $mystring now contains "This is a strin";
chop is used most f r equent l y t o r emove t he t r ail ing newl ine char act er f r om an input
l ine, as f ol l ows:
$input = <STDIN>;
chop ($input);
The ar gument passed t o chop can al so be a l ist . In t his case, chop r emoves t he l ast
char act er f r om ever y el ement of t he l ist . For exampl e, t o r ead an ent ir e input f il e int o
an ar r ay var iabl e and r emove al l of t he t r ail ing newl ine char act er s, use t he f ol l owing
st at ement s:
@input = <STDIN>;
chop (@input);
chop r et ur ns t he char act er chopped. For exampl e:
$input = "12345";
$lastchar = chop ($input);
This cal l t o chop assigns 5 t o t he scal ar var iabl e $lastchar.
If chop is passed a l ist , t he l ast char act er f r om t he l ast el ement of t he l ist is r et ur ned:
@array = ("ab", "cd", "ef");
$lastchar = chop(@array);
This assigns f, t he l ast char act er of t he l ast el ement of @array, t o $lastchar.
The chomp Function
The chomp f unct ion, def ined onl y in Per l 5, checks whet her t he l ast char act er s of a
st r ing or l ist of st r ings mat ch t he input l ine separ at or def ined by t he $/ syst em var iabl e.
If t hey do, chomp r emoves t hem.
The synt ax f or t he chomp f unct ion is
result = chomp(var)
As in t he chop f unct ion, var can be eit her a scal ar var iabl e or a l ist . If var is a l ist , each
el ement of t he l ist is checked f or t he input end-of -l ine st r ing. result is t he t ot al
number of char act er s r emoved by chomp.
List ing 14.1 shows how chomp wor ks.

List ing 14.1. A pr ogr am t hat uses t he chomp f unct ion.
1: #!/usr/local/bin/perl
2:
3: $/ = "::"; # set input line separator
4: $scalar = "testing::";
5: $num = chomp($scalar);
6: print ("$scalar $num\n");
7: @list = ("test1::", "test2", "test3::");
8: $num = chomp(@list);
9: print ("@list $num\n");

$ program14_1
testing 2
test1 test2 test3 4
$
This pr ogr am uses chomp t o r emove t he input l ine separ at or f r om bot h a scal ar
var iabl e and an ar r ay var iabl e. The cal l t o chomp in l ine 5 conver t s t he val ue of
$scalar f r om testing:: t o testing. The number of char act er s r emoved, 2, is r et ur ned by
chomp and assigned t o $num.
The cal l t o chomp in l ine 8 checks each el ement of @list. The f ir st el ement is conver t ed
f r om test1:: t o test1, and t he l ast el ement is conver t ed f r om test3:: t o test3. (The
second el ement is ignor ed, because it is not t er minat ed by t he end-of -l ine specif ier .) The
t ot al number of char act er s r emoved, 4 (t wo f r om t he f ir st el ement and t wo f r om t he
l ast ), is r et ur ned by chomp and assigned t o $num.
NOTE
For mor e inf or mat ion on t he $/ syst em var iabl e, r ef er t o
Day 17, "Syst em Var iabl es.
The crypt Function
The crypt f unct ion encr ypt s a st r ing using t he NBS Dat a Encr ypt ion St andar d (DES)
al gor it hm.
The synt ax f or t he crypt f unct ion is
result = crypt (original, salt);
original is t he st r ing t o be encr ypt ed, and salt is a char act er st r ing of t wo char act er s
t hat def ines how t o change t he DES al gor it hm (t o make it mor e dif f icul t t o decode).
These t wo char act er s can be any l et t er or digit , or one of t he . and / char act er s. Af t er
t he al gor it hm is changed, t he st r ing is encr ypt ed using t he r esul t ing key.
result is t he encr ypt ed st r ing. The f ir st t wo char act er s of result ar e t he t wo
char act er s specif ied in salt.
You can use crypt t o set up a passwor d checker simil ar t o t hose used by t he UNIX l ogin.
List ing 14.2 is an exampl e of a pr ogr am t hat pr ompt s t he user f or a passwor d and compar es
it wit h a passwor d st or ed in a special f il e.

List ing 14.2. A pr ogr am t hat asks f or and compar es a passwor d.
1: #!/usr/local/bin/perl
2:
3: open (PASSWD, "/u/jqpublic/passwd") ||
4: die ("Can't open password file");
5: $passwd = <PASSWD>;
6: chop ($passwd);
7: close (PASSWD);
8: print ("Enter the password for this program:\n");
9: system ("stty -echo");
10: $mypasswd = <STDIN>;
11: system ("stty echo");
12: chop ($mypasswd);
13: if (crypt ($mypasswd, substr($passwd, 0, 2)) eq $passwd) {
14: print ("Correct! Carry on!\n");
15: } else {
16: die ("Incorrect password: goodbye!\n");
17: }

$ program14_2
Enter the password for this program:
bluejays
Correct! Carry on!
$
Not e t hat t he passwor d you t ype is not displ ayed on t he scr een.
Lines 3-7 r et r ieve t he cor r ect passwor d f r om t he f il e /u/jqpublic/passwd. This passwor d
can be cr eat ed by anot her cal l t o crypt. For exampl e, if t he cor r ect passwor d is sludge,
t he cal l t hat cr eat es t he st r ing now st or ed in $passwd coul d be t he f ol l owing, wher e
$salt cont ains some t wo-char act er st r ing:
$retval = crypt ("sludge", $salt);
Af t er t he cor r ect passwor d has been r et r ieved, t he next st ep is l ine 8, which asks t he
user t o t ype a passwor d. By def aul t , anyt hing t yped in at t he keyboar d is immediat el y
displ ayed on t he scr een; t his behavior is cal l ed input echoing. Input echoing is not
desir abl e if a passwor d is being t yped in, because someone l ooking over t he user 's
shoul der can r ead t he passwor d and br eak int o t he pr ogr am.
To make t he passwor d-checking pr ocess mor e secur e, l ine 9 cal l s t he UNIX command stty
-echo, which t ur ns of f input echoing; now t he passwor d is not displ ayed on t he scr een
when t he user t ypes it . Af t er t he passwor d has been ent er ed, l ine 11 cal l s t he UNIX
command stty echo, which t ur ns input echoing back on.
Line 13 cal l s crypt t o check t he passwor d t he user has ent er ed. Because t he f ir st t wo
char act er s of t he act ual encr ypt ed passwor d cont ain t he t wo-char act er sal t used in
encr ypt ion, substr is used t o r et r ieve t hese t wo char act er s and use t hem as t he sal t
when encr ypt ing t he user 's passwor d. If t he val ue r et ur ned by crypt is ident ical t o t he
encr ypt ed passwor d, t he user 's passwor d is cor r ect ; ot her wise, t he user has got t en it
wr ong, and die t er minat es t he pr ogr am. (A gent l er passwor d-checking pr ogr am usual l y
gives t he user t wo or t hr ee chances t o t ype a passwor d bef or e t er minat ing t he pr ogr am.)
This passwor d checker is secur e because t he act ual passwor d does not appear in t he
pr ogr am in unencr ypt ed f or m. (In f act , because t he passwor d is in a separ at e f il e, it does
not appear in t he pr ogr am at al l .) This makes it impossibl e t o obt ain t he passwor d by
simpl y examining t he t ext f il e.
NOTE
The behavior of crypt is ident ical t o t hat of t he UNIX
l ibr ar y f unct ion crypt. See t he crypt(3) manual page
f or mor e inf or mat ion on DES encr ypt ion
The hex Function
The hex f unct ion assumes t hat a char act er st r ing is a number wr it t en in hexadecimal
f or mat , and it conver t s it int o a decimal number (a number in st andar d base-10 f or mat ).
The synt ax f or t he hex f unct ion is
decnum = hex (hexnum);
hexnum is t he hexadecimal char act er st r ing, and decnum is t he r esul t ing decimal number .
The f ol l owing is an exampl e:
$myhexstring = "1ff";
$num = hex ($myhexstring);
This cal l t o hex assigns t he decimal equival ent of 1ff t o $num, which means t hat t he
val ue of $num is now 511. The val ue st or ed in $myhexstring is not changed.
The val ue passed t o t he st r ing can cont ain eit her upper case or l ower case l et t er s
(pr ovided t he l et t er s ar e bet ween a and f, incl usive). This val ue can be t he r esul t of an
expr ession, as f ol l ows:
$num = hex ("f" x 2);
Her e, t he expr ession "f" x 2 is equival ent t o ff, which is conver t ed t o 255 by hex.
NOTE
To conver t a st r ing f r om a decimal val ue t o a
hexadecimal val ue, use sprintf and specif y eit her %x
(hexadecimal int eger ) or %lx (l ong hexadecimal int eger )
hex does not handl e hexadecimal st r ings t hat st ar t wit h
t he char act er s 0x or 0X. To handl e t hese st r ings, eit her
get r id of t hese char act er s using a st at ement such as
$myhexstring =~ s/^0[xX]//;
or cal l t he oct f unct ion, which is descr ibed l at er in
t oday's l esson
The int Function
The int f unct ion t ur ns a f l oat ing-point number int o an int eger by get t ing r id of
ever yt hing af t er t he decimal point .
The synt ax f or t he int f unct ion is
intnum = int (floatnum);
floatnum is t he f l oat ing-point number , and intnum is t he r esul t ing int eger .
The f ol l owing is an exampl e:
$floatnum = 45.6;
$intnum = int ($floatnum);
This cal l t o int conver t s 45.6 t o 45 and assigns it t o $intnum. The val ue st or ed in
$floatnum is not changed.
int can be used in expr essions as wel l ; f or exampl e:
$intval = int (68.3 / $divisor) + 1;
int does not r ound up when you conver t f r om f l oat ing
point t o int eger . To r ound up when you use int, add 0.5
f ir st , as f ol l ows:
$intval = int ($mynum + 0.5);
Even t hen, you st il l might need t o wat ch out f or r ound-
of f er r or s. For exampl e, if 4.5 is act ual l y st or ed in t he
machine as, say, 4.499999999, adding 0.5 might st il l
r esul t in a number l ess t han 5, which means t hat int
wil l t r uncat e it t o 4
The oct Function
The oct f unct ion assumes t hat a char act er st r ing is a number wr it t en in oct al f or mat ,
and it conver t s it int o a decimal number (a number in st andar d base-10 f or mat ).
The synt ax f or t he oct f unct ion is
decnum = oct (octnum);
octnum is t he oct al char act er st r ing, and decnum is t he r esul t ing decimal number .
The f ol l owing is an exampl e:
$myoctstring = "177";
$num = oct ($myoctstring);
This cal l t o oct assigns t he decimal equival ent of 177 t o $num, which means t hat t he
val ue of $num is now 127. The val ue st or ed in $myoctstring is not changed.
The val ue passed t o oct can be t he r esul t of an expr ession, as shown in t he f ol l owing
exampl e:
$num = oct ("07" x 2);
Her e, t he expr ession "07" x 2 is equival ent t o 0707, which is conver t ed t o 455 by oct.
NOTE
To conver t a st r ing f r om a decimal val ue t o an oct al
val ue, use sprintf and specif y eit her %o (oct al int eger )
or %lo (l ong oct al int eger )
The oct Function and Hexadecimal Integers
The oct f unct ion al so handl es hexadecimal int eger s whose f ir st t wo char act er s st ar t
wit h 0x or 0X:
$num = oct ("0xff");
This cal l t r eat s 0xff as t he hexadecimal number ff and conver t s it t o 255. This f eat ur e
of oct can be used t o conver t any non-st andar d Per l int eger const ant .
List ing 14.3 is a pr ogr am t hat r eads a l ine of input and checks whet her it is a val id Per l
int eger const ant . If it is, it conver t s it int o a st andar d (base-10) int eger .

List ing 14.3. A pr ogr am t hat r eads any kind of int eger .
1: #!/usr/local/bin/perl
2:
3: $integer = <STDIN>;
4: chop ($integer);
5: if ($integer !~ /^[0-9]+$|^0[xX][0-9a-fa-F]+$/) {
6: die ("$integer is not a legal integer\n");
7: }
8: if ($integer =~ /^0/) {
9: $integer = oct ($integer);
10: }
11: print ("$integer\n");

$ program14_3
077
63
$
The pat t er n in l ine 5 mat ches one of t he f ol l owing:
G One or mor e digit s
G A st r ing consist ing of 0x or 0X f ol l owed by one or mor e digit s or by upper case or
l ower case l et t er s bet ween a and f, incl usive
The f ir st case mat ches any st andar d base-10 int eger or oct al int eger (because oct al
int eger s st ar t wit h 0 and consist of t he number s 0 t o 7). The second case mat ches any
l egal hexadecimal int eger . In bot h cases, t he pat t er n mat ches onl y if t her e ar e no
ext r aneous char act er s (bl ank spaces, or ot her wor ds or number s) on t he l ine. Of cour se,
it is easy t o use t he subst it ut ion oper at or t o get r id of t hese f ir st , if you l ike.
Line 8 t est s whet her t he int eger is eit her an oct al or hexadecimal int eger by sear ching
f or t he pat t er n /^0/. If t his pat t er n is f ound, oct conver t s t he int eger t o decimal ,
pl acing t he conver t ed int eger back in $integer. Not e t hat l ine 8 does not need t o
det er mine which t ype of int eger is cont ained in $integer because oct pr ocesses bot h
oct al and hexadecimal int eger s.
The ord and chr Functions
The ord and chr f unct ions ar e simil ar t o t he Pascal f unct ion of t he same name. ord
conver t s a singl e char act er t o it s numer ic ASCII equival ent , and chr conver t s a number
t o it s ASCII char act er equival ent .
The synt ax f or t he ord f unct ion is
asciival = ord (char);
char is t he st r ing whose f ir st char act er is t o be conver t ed, and asciival is t he r esul t ing
ASCII val ue.
For exampl e, t he f ol l owing st at ement assigns t he ASCII val ue f or t he / char act er , 47,
t o $ASCIIval:
$ASCIIval = ord("/");
If t he val ue passed t o ord is a char act er st r ing t hat is l onger t han one char act er in
l engt h, ord conver t s t he f ir st char act er in t he st r ing:
$mystring = "/ignore the rest of this string";
$charval = ord ($mystring);
Her e, t he f ir st char act er st or ed in $mystring, /, is conver t ed and assigned t o $charval.
The synt ax f or t he chr f unct ion is
charval = chr (asciival);
asciival is t he val ue t o be conver t ed, and charval is t he one-char act er st r ing
r epr esent ing t he char act er equival ent of asciival in t he ASCII char act er set .
For exampl e, t he f ol l owing st at ement assigns / t o $slash, because 47 is t he numer ic
equival ent of / in t he ASCII char act er set :
$slash = chr(47);
NOTE
The ASCII char act er set cont ains 256 char act er s. As a
consequence, if t he val ue passed t o chr is gr eat er t han
256, onl y t he bot t om eight bit s of t he val ue ar e used.
This means, f or exampl e, t hat t he f ol l owing st at ement s
ar e equival ent :
$slash = chr(47);
$slash = chr(303);
$slash = chr(559);
In each case, the value of $slash is /
The chr f unct ion is def ined onl y in Per l 5. If you ar e
using Per l 4, you wil l need t o cal l sprintf t o conver t a
number t o a char act er :
$slash = sprintf("%c", 47);
This assigns / t o $slash
The scalar Function
In Per l , some f unct ions or expr essions behave dif f er ent l y when t heir r esul t s ar e
assigned t o ar r ays t han t hey do when assigned t o scal ar var iabl es. For exampl e, t he
assignment
@var = @array;
copies t he l ist st or ed in @array t o t he ar r ay var iabl e @var, and t he assignment
$var = @array;
det er mines t he number of el ement s in t he l ist st or ed in @array and assigns t hat number
t o t he scal ar var iabl e $var.
As you can see, @array has t wo dif f er ent meanings: an "ar r ay meaning" and a "scal ar
meaning." The Per l int er pr et er det er mines which meaning t o use by examining t he r est of
t he st at ement in which @array occur s. In t he f ir st case, t he ar r ay meaning is int ended,
because t he st at ement is assigning t o an ar r ay var iabl e. St at ement s in which t he ar r ay
meaning is int ended ar e cal l ed array contexts.
In t he second case, t he scal ar meaning of @array is int ended, because t he st at ement is
assigning t o a scal ar var iabl e. St at ement s in which t he scal ar meaning is int ended ar e
cal l ed scalar contexts.
The scal ar f unct ion enabl es you t o specif y t he scal ar meaning in an ar r ay cont ext .
The synt ax f or t he scalar f unct ion is
value = scalar (list);
list is t he l ist t o be used in a scal ar cont ext , and value is t he scal ar meaning of t he l ist .
For exampl e, t o cr eat e a l ist consist ing of t he l engt h of an ar r ay, you can use t he
f ol l owing st at ement :
@array = ("a", "b", "c");
@lengtharray = scalar (@array);
Her e, t he number of el ement s of @array, 3, is conver t ed int o a one-el ement l ist and
assigned t o @lengtharray.
Anot her usef ul pl ace t o use scalar is in conjunct ion wit h t he <> oper at or . Recal l t hat
t he st at ement
$myline = <MYFILE>;
r eads one l ine f r om t he input f il e MYFILE, and
@mylines = <MYFILE>;
r eads al l of MYFILE int o t he ar r ay var iabl e @mylines. To r ead one l ine int o t he ar r ay
var iabl e @mylines (as a one-el ement l ist ), use t he f ol l owing:
@mylines = scalar (<MYFILE>);
Specif ying scalar wit h <MYFILE> ensur es t hat onl y one l ine is r ead f r om MYFILE.
The pack Function
The pack f unct ion enabl es you t o t ake a l ist or t he cont ent s of an ar r ay var iabl e and
conver t (pack) it int o a scal ar val ue in a f or mat t hat can be st or ed in act ual machine
memor y or used in pr ogr amming l anguages such as C.
The synt ax f or t he pack f unct ion is
formatstr = pack(packformat, list);
Her e, list is a l ist of val ues; t his l ist of val ues can, as al ways, be t he cont ent s of an
ar r ay var iabl e. formatstr is t he r esul t ing st r ing, which is in t he f or mat specif ied by
packformat.
packformat consist s of one or mor e pack-format characters; t hese char act er s det er mine how
t he l ist is t o be packed. These pack f or mat s ar e l ist ed in Tabl e 14.1.
Tabl e 14.1. For mat char act er s f or t he pack f unct ion.
Char act er Descr ipt ion
a
ASCII char act er st r ing padded wit h
nul l char act er s
A
ASCII char act er st r ing padded wit h
spaces
b
St r ing of bit s, l owest f ir st
B
St r ing of bit s, highest f ir st
c
A signed char act er (r ange usual l y -128
t o 127)
C
An unsigned char act er (usual l y 8 bit s)
d
A doubl e-pr ecision f l oat ing-point
number
f
A singl e-pr ecision f l oat ing-point
number
h
Hexadecimal st r ing, l owest digit f ir st
H
Hexadecimal st r ing, highest digit f ir st
i
A signed int eger
I
An unsigned int eger
l
A signed l ong int eger
L
An unsigned l ong int eger
n
A shor t int eger in net wor k or der
N
A l ong int eger in net wor k or der
p
A point er t o a st r ing
s
A signed shor t int eger
S
An unsigned shor t int eger
u
Conver t t o uuencode f or mat
v
A shor t int eger in VAX (l it t l e-endian)
or der
V
A l ong int eger in VAX or der
x
A nul l byt e
X
Indicat es "go back one byt e"
@
Fil l wit h nul l s (ASCII 0)
One pack-f or mat char act er must be suppl ied f or each el ement in t he l ist . If you l ike, you
can use spaces or t abs t o separ at e pack-f or mat char act er s, because pack ignor es whit e
space.
The f ol l owing is a simpl e exampl e t hat uses pack:
$integer = pack("i", 171);
This st at ement t akes t he number 171, conver t s it int o t he f or mat used t o st or e int eger s
on your machine, and r et ur ns t he conver t ed int eger in $integer. This conver t ed int eger
can now be wr it t en out t o a f il e or passed t o a pr ogr am using t he system or exec
f unct ions.
To r epeat a pack-f or mat char act er mul t ipl e t imes, specif y a posit ive int eger af t er t he
char act er . The f ol l owing is an exampl e:
$twoints = pack("i2", 103, 241);
Her e, t he pack f or mat i2 is equival ent t o ii.
To use t he same pack-f or mat char act er f or al l of t he r emaining el ement s in t he l ist , use
* in pl ace of an int eger , as f ol l ows:
$manyints = pack("i*", 14, 26, 11, 83);
Specif ying int eger s or * t o r epeat pack-f or mat char act er s wor ks f or al l f or mat s except
a, A, and @. Wit h t he a and A f or mat s, t he int eger is assumed t o be t he l engt h of t he
st r ing t o cr eat e.
$mystring = pack("a6", "test");
This cr eat es a st r ing of six char act er s (t he f our t hat ar e suppl ied, pl us t wo nul l
char act er s).
NOTE
The a and A f or mat s al ways use exact l y one el ement of
t he l ist , r egar dl ess of whet her a posit ive int eger is
incl uded f ol l owing t he char act er . For exampl e:
$mystring = pack("a6", "test1", "test2");
Her e, test1 is packed int o a six-char act er st r ing and
assigned t o $mystring. test2 is ignor ed.
To get ar ound t his pr obl em, use t he x oper at or t o cr eat e
mul t ipl e copies of t he a pack-f or mat char act er , as
f ol l ows:
$strings = pack ("a6" x 2, "test1", "test2");
This packs test1 and test2 int o t wo six-char act er st r ings
(joined t oget her )
The @ f or mat is a special case. It is used onl y when a f ol l owing int eger is specif ied. This
int eger indicat es t he number of byt es t he st r ing must cont ain at t his point ; if t he st r ing
is smal l er , nul l char act er s ar e added. For exampl e:
$output = pack("a @6 a", "test", "test2");
Her e, t he st r ing test is conver t ed t o ASCII f or mat . Because t his st r ing is onl y f our
char act er s l ong, and t he pack f or mat @6 specif ies t hat t he packed scal ar val ue must be
six char act er s l ong at t his point , t wo nul l char act er s ar e added t o t he st r ing bef or e
test2 is packed.
The pack Function and C Data Types
The most f r equent use of pack is t o cr eat e dat a t hat can be used by C pr ogr ams. For
exampl e, t o cr eat e a st r ing t er minat ed by a nul l char act er , use t he f ol l owing cal l t o
pack:
$Cstring = pack ("ax", $mystring);
Her e, t he a pack-f or mat char act er conver t s $mystring int o an ASCII st r ing, and t he x
char act er appends a nul l char act er t o t he end of t he st r ing. This f or mat -a st r ing
f ol l owed by nul l -is how C st or es st r ings.
Tabl e 14.2 shows t he pack-f or mat char act er s t hat have equival ent dat a t ypes in C.
Tabl e 14.2. Pack-f or mat char act er s and t heir C equival ent s.
Char act er C equival ent
C
char
d
double
f
float
I
int
I
unsigned int (or unsigned)
l
long
L
unsigned long
s
short
S
unsigned short
In each case, pack st or es t he val ue in your l ocal machine's int er nal f or mat .
TIP
You usual l y won't need t o use pack unl ess you ar e
pr epar ing dat a f or use in ot her pr ogr ams
The unpack Function
The unpack f unct ion r ever ses t he oper at ion per f or med by pack. It t akes a val ue st or ed in
machine f or mat and conver t s it t o a l ist of val ues under st ood by Per l .
The synt ax f or t he unpack f unct ion is
list = unpack (packformat, formatstr);
Her e, formatstr is t he val ue in machine f or mat , and list is t he cr eat ed l ist of val ues.
As in pack, packformat is a set of one or mor e pack f or mat char act er s. These char act er s
ar e basical l y t he same as t hose under st ood by pack. Tabl e 14.3 l ist s t hese char act er s.
Tabl e 14.3. The pack-f or mat char act er s, as used by unpack.
Char act er Descr ipt ion
a
ASCII char act er st r ing, unst r ipped
A
ASCII char act er st r ing wit h t r ail ing
nul l s and spaces st r ipped
b
St r ing of bit s, l owest f ir st
B
St r ing of bit s, highest f ir st
c
A signed char act er (r ange usual l y -128
t o 127)
C
An unsigned char act er (usual l y 8 bit s)
d
A doubl e-pr ecision f l oat ing-point
number
f
A singl e-pr ecision f l oat ing-point
number
h
Hexadecimal st r ing, l owest digit f ir st
H
Hexadecimal st r ing, highest digit f ir st
I
A signed int eger
I
An unsigned int eger
l
A signed l ong int eger
L
An unsigned l ong int eger
n
A shor t int eger in net wor k or der
N
A l ong int eger in net wor k or der
p
A point er t o a st r ing
s
A signed shor t int eger
S
An unsigned shor t int eger
u
Conver t (uudecode) a uuencoded st r ing
v
A shor t int eger in VAX (l it t l e-endian)
or der
V
A l ong int eger in VAX or der
x
Skip f or war d a byt e
X
Indicat es "go back one byt e"
@
Go t o specif ied posit ion
In al most al l cases, a cal l t o unpack undoes t he ef f ect s of an equival ent cal l t o pack.
For exampl e, consider List ing 14.4, which packs and unpacks a l ist of int eger s.

List ing 14.4. A pr ogr am t hat demonst r at es t he r el at ionship bet ween
pack and unpack.
1: #!/usr/local/bin/perl
2:
3: @list_of_integers = (11, 26, 43);
4: $mystring = pack("i*", @list_of_integers);
5: @list_of_integers = unpack("i*", $mystring);
6: print ("@list_of_integers\n");

$ program14_4
11 26 43
$
Line 4 cal l s pack, which t akes al l of t he el ement s st or ed in
@list_of_integers, conver t s t hem t o t he machine's int eger f or mat , and st or es t hem in
$mystring.
Line 5 cal l s unpack, which assumes t hat t he st r ing st or ed in $mystring is a l ist of val ues
st or ed in t he machine's int eger f or mat ; it t akes t his st r ing, conver t s each int eger in t he
st r ing t o a Per l val ue, and st or es t he r esul t ing l ist of val ues in @list_of_integers.
Unpacking Strings
The onl y unpack oper at ions t hat do not exact l y mir r or pack oper at ions ar e t hose
specif ied by t he a and A f or mat s. The a f or mat conver t s a machine-f or mat st r ing int o a
Per l val ue as is, wher eas t he A f or mat conver t s a machine-f or mat st r ing int o a Per l
val ue and st r ips any t r ail ing bl anks or nul l char act er s.
The A f or mat is usef ul if you want t o conver t a C st r ing int o t he st r ing f or mat
under st ood by Per l . The f ol l owing is an exampl e:
$perlstring = unpack("A", $Cstring);
Her e, $Cstring is assumed t o cont ain a char act er st r ing st or ed in t he f or mat used by t he
C pr ogr amming l anguage (a sequence of byt es t er minat ed by a nul l char act er ). unpack
st r ips t he t r ail ing nul l char act er f r om t he st r ing st or ed in $Cstring, and st or es t he
r esul t ing st r ing in $perlstring.
Skipping Characters When Unpacking
The @ pack-f or mat char act er t el l s unpack t o skip t o t he posit ion specif ied wit h t he @. For
exampl e, t he f ol l owing st at ement skips f our byt es in $packstring, and t hen unpacks a
signed int eger and st or es it in $skipnum.
$skipnum = unpack("@4i", $packstring);
NOTE
If unpack is unpacking a singl e it em, it can be st or ed in
eit her an ar r ay var iabl e or a scal ar var iabl e. If an
ar r ay var iabl e is used t o st or e t he r esul t of t he unpack
oper at ion, t he r esul t ing l ist consist s of a singl e el ement
If an * char act er appear s af t er t he @ pack-f or mat char act er , unpack skips t o t he end of
t he val ue being unpacked. This can be used in conjunct ion wit h t he X pack-f or mat
char act er t o unpack t he r ight end of t he packed val ue. For exampl e, t he f ol l owing
st at ement t r eat s t he l ast f our byt es of a packed val ue as a l ong unsigned int eger and
unpacks t hem:
$longrightint = unpack("@* X4 L", $packstring);
In t his exampl e, t he @* pack f or mat specif ier skips t o t he end of t he val ue st or ed in
$packstring. Then, t he X4 specif ier backs up f our byt es. Final l y, t he L specif ier t r eat s t he
l ast f our byt es as a l ong unsigned int eger , which is unpacked and st or ed in
$longrightint.
The number of byt es unpacked by t he s, S, i, I, l, and L
f or mat s depends on your machine. Many UNIX machines
st or e shor t int eger s in t wo byt es of memor y, and int eger
and l ong int eger val ues in f our byt es. However , ot her
machines might behave dif f er ent l y. In gener al , you
cannot assume t hat pr ogr ams t hat use pack and unpack
wil l behave in t he same way on dif f er ent machines
The unpack Function and uuencode
The unpack f unct ion enabl es you t o decode f il es t hat have been encoded by t he uuencode
encoding pr ogr am. To do t his, use t he u pack-f or mat specif ier .
NOTE
uuencode, a coding mechanism avail abl e on most UNIX
syst ems, conver t s al l char act er s (incl uding unpr int abl e
char act er s) int o pr int abl e ASCII char act er s. This
ensur es t hat you can saf el y t r ansmit f il es acr oss r emot e
net wor ks
List ing 14.5 is an exampl e of a pr ogr am t hat uses unpack t o decode a uuencoded f il e.

List ing 14.5. A pr ogr am t hat decodes a uuencoded f il e.
1: #!/usr/local/bin/perl
2:
3: open (CODEDFILE, "/u/janedoe/codefile") ||
4: die ("Can't open input file");
5: open (OUTFILE, ">outfile") ||
6: die ("Can't open output file");
7: while ($line = <CODEDFILE>) {
8: $decoded = unpack("u", $line);
9: print OUTFILE ($decoded);
10: }
11: close (OUTFILE);
12: close (CODEDFILE);
The f il e var iabl e CODEDFILE r epr esent s t he f il e t hat was pr eviousl y encoded
by uuencode. Lines 3 and 4 open t he f il e (or die t r ying). Lines 5 and 6 open t he out put f il e,
which is r epr esent ed by t he f il e var iabl e OUTFILE.
Lines 7-10 r ead and wr it e one l ine at a t ime. Line 7 st ar t s of f by r eading a l ine of
encoded input int o t he scal ar var iabl e $line. As wit h any ot her input f il e, t he nul l
st r ing is r et ur ned if CODEDFILE is exhaust ed.
Line 8 cal l s unpack t o decode t he l ine. If t he l ine is a special l ine cr eat ed by uuencode
(f or exampl e, t he f ir st l ine, which l ist s t he f il ename and t he size, or t he l ast l ine, which
mar ks t he end of t he f il e), unpack det ect s it and conver t s it int o t he nul l st r ing. This
means t hat t he pr ogr am does not need t o cont ain special code t o handl e t hese l ines.
Line 9 wr it es t he decoded l ine t o t he out put f il e r epr esent ed by OUTFILE.
NOTE
You can use pack t o uuencode l ist s of el ement s, as in t he
f ol l owing:
@encoded = pack ("u", @decoded);
Her e, t he el ement s in @decoded ar e encoded and st or ed in
t he ar r ay var iabl e @encoded. The l ist in @encoded can
t hen be decoded using unpack, as f ol l ows:
@decoded = unpack ("u", @encoded);
Al t hough pack uses t he same uuencode al gor it hm as t he
UNIX uuencode ut il it y, you cannot use t he UNIX
uudecode pr ogr am on dat a encoded using pack because
pack does not suppl y t he header and f oot er (beginning
and ending) l ines expect ed by uudecode.
If you r eal l y need t o use uudecode wit h a f il e cr eat ed by
wr it ing out t he out put f r om pack, you'l l need t o wr it e
out t he header and f oot er f il es as wel l . (See t he UNIX
manual page f or uuencode f or mor e det ail s.
The vec Function
The vec f unct ion enabl es you t o t r eat a scal ar val ue as a col l ect ion of chunks, wit h
each chunk consist ing of a specif ied number of bit s; t his col l ect ion is known as a vector.
Each cal l t o vec accesses a par t icul ar chunk of bit s in t he vect or (known as a bit vector).
The synt ax f or t he vec f unct ion is
retval = vec (vector, index, bits);
vector is t he scal ar val ue t hat is t o be t r eat ed as a vect or . It can be any scal ar val ue,
incl uding t he val ue of an expr ession.
index behaves l ike an ar r ay subscr ipt . It indicat es which chunk of bit s t o r et r ieve. An
index of 0 r et r ieves t he f ir st chunk, 1 r et r ieves t he second, and so on. Not e t hat
r et r ieval is f r om r ight t o l ef t . The f ir st chunk of bit s r et r ieved when t he index 0 is
specif ied is t he chunk of bit s at t he r ight end of t he vect or .
bits specif ies t he number of bit s in each chunk; it can be 1, 2, 4, 8, 16, or 32.
retval is t he val ue of t he chunk of bit s. This val ue is an or dinar y Per l scal ar val ue, and
it can be used anywher e scal ar val ues can be used.
List ing 14.6 shows how you can use vec t o r et r ieve t he val ue of a par t icul ar chunk of
bit s.

List ing 14.6. A pr ogr am t hat il l ust r at es t he use of vec.
1: #!/usr/local/bin/perl
2:
3: $vector = pack ("B*", "11010011");
4: $val1 = vec ($vector, 0, 4);
5: $val2 = vec ($vector, 1, 4);
6: print ("high-to-low order values: $val1 and $val2\n");
7: $vector = pack ("b*", "11010011");
8: $val1 = vec ($vector, 0, 4);
9: $val2 = vec ($vector, 1, 4);
10: print ("low-to-high order values: $val1 and $val2\n");

$ program14_6
high-to-low order values: 3 and 13
low-to-high order values: 11 and 12
$
The cal l t o pack in l ine 3 assumes t hat each char act er in t he st r ing 11010011
is a bit t o be packed. The bit s ar e packed in high-t o-l ow or der (wit h t he highest bit f ir st ),
which means t hat t he vect or st or ed in $vector consist s of t he bit s 11010011 (f r om l ef t t o
r ight ). Gr ouping t hese bit s int o chunks of f our pr oduces 1101 0011, which ar e t he binar y
r epr esent at ions of 13 and 3, r espect ivel y.
Line 4 r et r ieves t he f ir st chunk of f our bit s f r om $vector and assigns it t o $val1. This is
t he chunk 0011, because vec is r et r ieving t he chunk of bit s at t he r ight end of t he bit
vect or . Simil ar l y, l ine 5 r et r ieves 1101, because t he index 1 specif ies t he second chunk of
bit s f r om t he r ight ; t his chunk is assigned t o $val2. (One way t o t hink of t he index is as
"t he number of chunks t o skip." The index 1 indicat es t hat one chunk of bit s is t o be
skipped.)
Line 7 is simil ar t o l ine 3, but t he bit s ar e now st or ed in l ow-t o-high or der , not high-t o-
l ow. This means t hat t he st r ing 11010011 is st or ed as t he f ol l owing (which is 11010011
r ever sed):
11001011
When t his bit vect or is gr ouped int o chunks of 4 bit s, you get t he f ol l owing, which ar e
t he binar y r epr esent at ions of 12 and 11, r espect ivel y:
1100 1011
Lines 8 and 9, l ike l ines 4 and 5, r et r ieve t he f ir st and second chunk of bit s f r om $vector.
This means t hat $val1 is assigned 11 (t he f ir st chunk), and $val2 is assigned 12 (t he
second chunk).
NOTE
You can use vec t o assign t o a chunk of bit s by pl acing
t he cal l t o vec t o t he l ef t of an assignment oper at or .
For exampl e:
vec ($vector, 0, 4) = 11;
This st at ement assigns 11 t o t he f ir st chunk of bit s in
$vector. Because t he binar y r epr esent at ion of 11 is 1011,
t he l ast f our bit s of $vector become 1011
The defined Function
By def aul t , al l scal ar var iabl es and el ement s of ar r ay var iabl es t hat have not been
assigned t o ar e assumed t o cont ain t he nul l st r ing. This ensur es t hat Per l pr ogr ams
don't cr ash when using uninit ial ized scal ar var iabl es.
In some cases, a pr ogr am might need t o know whet her a par t icul ar scal ar var iabl e or
ar r ay el ement has been assigned t o or not . The buil t -in f unct ion defined enabl es you t o
check f or t his.
The synt ax f or t he defined f unct ion is
retval = defined (expr);
Her e, expr is anyt hing t hat can appear on t he l ef t of an assignment st at ement , such as a
scal ar var iabl e, ar r ay el ement , or an ent ir e ar r ay. (An ar r ay is assumed t o be def ined if
at l east one of it s el ement s is def ined.) retval is t r ue (a nonzer o val ue) if expr is
def ined, and f al se (0) if it is not .
List ing 14.7 is a simpl e exampl e of a pr ogr am t hat uses defined.

List ing 14.7. A pr ogr am t hat il l ust r at es t he use of defined.
1: #!/usr/local/bin/perl
2:
3: $array[2] = 14;
4: $array[4] = "hello";
5: for ($i = 0; $i <= 5; $i++) {
6: if (defined ($array[$i])) {
7: print ("element ", $i+1, " is defined\n");
8: }
9: }

$ program14_7
element 3 is defined
element 5 is defined
$
This pr ogr am assigns val ues t o t wo el ement s of t he ar r ay var iabl e @array: t he
el ement wit h subscr ipt 2 (t he t hir d el ement ), and t he el ement wit h subscr ipt 4 (t he f if t h
el ement ).
The l oop in l ines 5-9 checks each el ement of @array t o see whet her it is def ined. Because
t he t hir d and f if t h el ement s-$array[2] and $array[4], r espect ivel y-ar e def ined, defined
r et ur ns t r ue when $i is 2 and when $i is 4.
NOTE
Many f unct ions t hat r et ur n t he nul l st r ing act ual l y
r et ur n a special "undef ined" val ue t hat is t r eat ed as if it
is t he nul l st r ing. If t his undef ined val ue is passed t o
defined, defined r et ur ns f al se.
Funct ions t hat r et ur n undef ined incl ude t he read
f unct ion (discussed on Day 12, "Wor king wit h t he Fil e
Syst em") and fork (int r oduced on Day 13, "Pr ocess,
St r ing, and Mat hemat ical Funct ions"). Many f unct ions
discussed t oday and on Day 15, "Syst em Funct ions," al so
r et ur n t he special undef ined val ue when an er r or
occur s.
The gener al r ul e is: A f unct ion t hat r et ur ns t he nul l
st r ing when an er r or or except ional condit ion occur s is
usual l y r eal l y r et ur ning t he undef ined val ue
The undef Function
The undef f unct ion undef ines a scal ar var iabl e, ar r ay el ement , or an ent ir e ar r ay.
The synt ax of t he undef f unct ion is
retval = undef (expr);
As in cal l s t o defined, expr can be anyt hing t hat can appear t o t he l ef t of a Per l
assignment st at ement . retval is al ways t he special undef ined val ue discussed in t he
pr evious sect ion, "The defined Funct ion"; t his undef ined val ue is equival ent t o t he nul l
st r ing.
The f ol l owing ar e some exampl es of undef:
undef ($myvar);
undef ($array[3]);
undef (@array);
In t he f ir st case, t he scal ar var iabl e $myvar becomes undef ined. The Per l int er pr et er
now t r eat s $myvar as if it has never been assigned t o. Needl ess t o say, any val ue
pr eviousl y st or ed in $myvar is now l ost .
In t he second exampl e, t he f our t h el ement of @array is mar ked as undef ined. It s val ue, if
any, is l ost . Ot her el ement s of @array ar e unaf f ect ed.
In t he t hir d and f inal exampl e, al l t he el ement s of @array ar e mar ked as undef ined. This
l et s t he Per l int er pr et er f r ee up any memor y used t o st or e t he val ues of @array, which
might be usef ul if your pr ogr am is wor king wit h l ar ge ar r ays. For exampl e, if you have
used an ar r ay t o r ead in an ent ir e f il e, as in t he f ol l owing:
@bigarray = <STDIN>;
you can use t he f ol l owing st at ement t o t el l t he Per l int er pr et er t hat you don't need
t he cont ent s of t he input f il e and t hat t he int er pr et er can t hr ow t hem away:
undef (@bigarray);
Cal l s t o undef can omit expr. In t his case, undef does not hing and just r et ur ns t he
undef ined val ue. List ing 14.8 shows how t his can be usef ul .

List ing 14.8. A pr ogr am t hat il l ust r at es t he use of undef t o r epr esent
an unusual condit ion.
1: #!/usr/local/bin/perl
2:
3: print ("Enter the number to divide:\n");
4: $value1 = <STDIN>;
5: chop ($value1);
6: print ("Enter the number to divide by:\n");
7: $value2 = <STDIN>;
8: chop ($value2);
9: $result = &safe_division($value1, $value2);
10: if (defined($result)) {
11: print ("The result is $result.\n");
12: } else {
13: print ("Can't divide by zero.\n");
14: }
15:
16: sub safe_division {
17: local ($dividend, $divisor) = @_;
18: local ($result);
19:
20: $result = ($divisor == 0) ? undef :
21: $dividend / $divisor;
22: }

$ program14_8
Enter the number to divide:
26
Enter the number to divide by:
0
Can't divide by zero.
$
Lines 20 and 21 il l ust r at e how you can use undef. If $divisor is 0, t he pr ogr am
is at t empt ing t o divide by 0. In t his case, t he subr out ine safe_division cal l s undef, which
r et ur ns t he special undef ined val ue. This val ue is assigned t o $result and passed back t o
t he main par t of t he pr ogr am.
Line 10 t est s whet her safe_division has r et ur ned t he undef ined val ue by t he cal l ing
defined f unct ion. If defined r et ur ns f al se, $result cont ains t he undef ined val ue, and
an at t empt ed division by 0 has been det ect ed.
NOTE
You can use undef t o undef ine an ent ir e subr out ine, if
you l ike. The f ol l owing exampl e:
undef (&mysub);
f r ees t he memor y used t o st or e mysub; af t er t his, mysub
can no l onger be cal l ed.
You ar e not l ikel y t o need t o use t his f eat ur e of undef,
but it might pr ove usef ul in pr ogr ams t hat consume a l ot
of memor y
Array and List Functions
The f ol l owing f unct ions manipul at e st andar d ar r ay var iabl es and t he l ist s t hat t hey
st or e:
G grep
G splice
G shift
G unshift
G push
G pop
G split
G sort
G reverse
G map
G wantarray
The grep Function
The grep f unct ion pr ovides a convenient way of ext r act ing t he el ement s of a l ist t hat
mat ch a specif ied pat t er n. (It is named af t er t he UNIX sear ch ut il it y of t he same name.)
The synt ax f or t he grep f unct ion is
foundlist = grep (pattern, searchlist);
pattern is t he pat t er n t o sear ch f or . searchlist is t he l ist of el ement s t o sear ch in.
foundlist is t he l ist of el ement s mat ched.
Her e is an exampl e:
@list = ("This", "is", "a", "test");
@foundlist = grep(/^[tT]/, @list);
Her e, grep examines al l t he el ement s of t he l ist st or ed in @list. If a l ist el ement
cont ains t he l et t er t (in eit her upper case or l ower case), t he el ement is incl uded as par t
of @foundlist. As a r esul t , @foundlist consist s of t wo el ement s: This and test.
List ing 14.9 is an exampl e of a pr ogr am t hat uses grep. It sear ches f or al l int eger s on an
input l ine and adds t hem t oget her .

List ing 14.9. A pr ogr am t hat demonst r at es t he use of grep.
1: #!/usr/local/bin/perl
2:
3: $total = 0;
4: $line = <STDIN>;
5: @words = split(/\s+/, $line);
6: @numbers = grep(/^\d+[.,;:]?$/, @words);
7: foreach $number (@numbers) {
8: $total += $number;
9: }
10: print ("The total is $total.\n");

$ program14_9
This line of input contains 8, 11 and 26.
The total is 45.
$
Line 5 spl it s t he input l ine int o wor ds, using t he st andar d pat t er n /\s+/,
which mat ches one or mor e t abs or bl anks. Some of t hese wor ds ar e act ual l y number s,
and some ar e not .
Line 6 uses grep t o mat ch t he wor ds t hat ar e act ual l y number s. The pat t er n
/^\d+[.,;:]?$/ mat ches if a wor d consist s of one or mor e digit s f ol l owed by an opt ional
punct uat ion char act er . The wor ds t hat mat ch t his pat t er n ar e r et ur ned by grep and
st or ed in @numbers. Af t er l ine 6 has been execut ed, @numbers cont ains t he f ol l owing l ist :
("8,", "11", "26.")
Lines 7-9 use a foreach l oop t o t ot al t he number s. Not e t hat t he t ot al ing oper at ion
wor ks pr oper l y even if a number being added cont ains a cl osing punct uat ion char act er :
when t he Per l int er pr et er conver t s a st r ing t o an int eger , it r eads f r om l ef t t o r ight
unt il it sees a char act er t hat is not a digit . This means t hat t he f inal wor d, 26., is
conver t ed t o 26, which is t he expect ed number .
Because split and grep each r et ur n a l ist and foreach expect s a l ist , you can combine
l ines 5-9 int o a singl e l oop if you want t o get f ancy.
foreach $number (grep (/^\d+[.,;:]?$/, split(/\s+/, $line))) {
$total += $number;
}
As al ways, t her e is a t r ade-of f of speed ver sus r eadabil it y: t his code is mor e concise, but
t he code in List ing 14.9 is mor e r eadabl e.
Using grep with the File-Test Operators
A usef ul f eat ur e of grep is t hat it can be used t o sear ch f or any expr ession, not just
pat t er ns. For exampl e, grep can be used in conjunct ion wit h readdir and t he f il e-t est
oper at or s t o sear ch a dir ect or y.
List ing 14.10 is an exampl e of a pr ogr am t hat sear ches al l t he r eadabl e f il es of t he
cur r ent dir ect or y f or a par t icul ar wor d (which is suppl ied on t he command l ine). Fil es
whose names begin wit h a per iod ar e ignor ed.

List ing 14.10. A pr ogr am t hat uses grep wit h t he f il e-t est oper at or s.
1: #!/usr/local/bin/perl
2:
3: opendir(CURRDIR, ".") ||
4: die("Can't open current directory");
5: @filelist = grep (!/^\./, grep(-r, readdir(CURRDIR)));
6: closedir(CURRDIR);
7: foreach $file (@filelist) {
8: open (CURRFILE, $file) ||
9: die ("Can't open input file $file");
10: while ($line = <CURRFILE>) {
11: if ($line =~ /$ARGV[0]/) {
12: print ("$file:$line");
13: }
14: }
15: close (CURRFILE);
16: }

$ program14_10 pattern
file1:This line of this file contains the word "pattern".
myfile:This file also contains abcpatterndef.
$
Line 3 of t his pr ogr am opens t he cur r ent dir ect or y. If it cannot be opened, l ine
4 cal l s die, which t er minat es t he pr ogr am.
Line 5 is act ual l y t hr ee f unct ion cal l s in one, as f ol l ows:
1. readdir r et r ieves a l ist of al l of t he f il es in t he dir ect or y.
2. This l ist of f il es is passed t o grep, which uses t he -r f il e t est oper at or t o sear ch
f or al l f il es t hat t he user has per mission t o r ead.
3. This l ist of r eadabl e f il es is passed t o anot her cal l t o grep, which uses t he
expr ession !/^\./ t o mat ch al l t he f il es whose names do not begin wit h a per iod.
The r esul t ing l ist -al l t he f il es in t he cur r ent dir ect or y t hat ar e r eadabl e and whose
names do not st ar t wit h a per iod-is assigned t o @filelist.
The r est of t he pr ogr am cont ains not hing new. Line 6 cl oses t he open dir ect or y, and
l ines
7-16 r ead each f il e in t ur n, sear ching f or t he wor d specif ied on t he command l ine.
(Recal l t hat t he buil t -in ar r ay @ARGV l ist s al l t he ar gument s suppl ied on t he command
l ine and t hat t he f ir st wor d specif ied on t he command l ine is st or ed in $ARGV[0].) Line 11
pr int s any l ines cont aining t he wor d t o sear ch f or , using t he f or mat empl oyed by t he
UNIX grep command (t he f il ename, f ol l owed by :, f ol l owed by t he l ine it sel f ).
The splice Function
The splice f unct ion enabl es you t o modif y t he l ist st or ed in an ar r ay var iabl e. By
passing t he appr opr iat e ar gument s t o splice, you can add el ement s t o t he middl e of a
l ist , del et e a por t ion of a l ist , or r epl ace a por t ion of a l ist .
The synt ax f or t he splice f unct ion is
retval = splice (array, skipelements, length, newlist)
array is t he ar r ay var iabl e cont aining t he l ist t o be spl iced. skipelements is t he number
of el ement s t o skip bef or e spl icing. length is t he number of el ement s t o be r epl aced.
newlist is t he l ist t o be spl iced in; t his l ist can be st or ed in an ar r ay var iabl e or specif ied
expl icit l y.
If length is gr eat er t han 0, retval is t he l ist of el ement s r epl aced by splice.
The f ol l owing sect ions pr ovide exampl es of what you can do wit h splice.
Replacing List Elements
You can use splice t o r epl ace a subl ist (a set of el ement s in a l ist ) wit h anot her subl ist .
The f ol l owing is an exampl e:
@array = ("1", "2", "3", "4");
splice (@array, 1, 2, ("two", "three"));
This cal l t o splice t akes t he l ist st or ed in @array, skips over t he f ir st el ement , and
r epl aces t he next t wo el ement s wit h t he l ist ("two", "three"). The new val ue of
@array is t he l ist
("1", "two", "three", "4")
If t he r epl acement l ist is l onger t han t he or iginal l ist , t he el ement s t o t he r ight of t he
r epl aced l ist ar e pushed t o t he r ight . For exampl e:
@array = ("1", "2", "3", "4");
splice (@array, 1, 2, ("two", "2.5", "three"));
Af t er t his cal l , t he new val ue of @array is t he f ol l owing:
("1", "two", "2.5", "three", "4")
Simil ar l y, if t he r epl acement l ist is shor t er t han t he or iginal l ist , t he el ement s t o t he
r ight of t he or iginal l ist ar e moved l ef t t o f il l t he r esul t ing gap. For exampl e:
@array = ("1", "2", "3", "4");
splice (@array, 1, 2, "twothree");
Af t er t his cal l t o splice, @array cont ains t he f ol l owing l ist :
("1", "twothree", "4")
NOTE
You do not need t o put par ent heses ar ound t he l ist you
pass t o splice. For exampl e, t he f ol l owing t wo
st at ement s ar e equival ent :
splice (@array, 1, 2, ("two", "three"));
splice (@array, 1, 2, "two", "three")
When t he Per l int er pr et er sees t he second f or m of
splice, it assumes t hat t he f our t h and subsequent
ar gument s ar e t he r epl acement l ist .
List ing 14.11 is an exampl e of a pr ogr am t hat uses splice t o r epl ace l ist el ement s. It
r eads a f il e cont aining a f or m l et t er , and r epl aces t he st r ing <name> wit h a name r ead
f r om t he st andar d input f il e. It t hen wr it es out t he new l et t er .
The out put shown assumes t hat t he f il e form cont ains
Hello <name>!
This is your lucky day, <name>!

List ing 14.11. A pr ogr am t hat uses splice t o r epl ace l ist el ement s.
1: #!/usr/local/bin/perl
2:
3: open (FORM, "form") || die ("Can't open form letter");
4: @form = <FORM>;
5: close (FORM);
6: $name = <STDIN>;
7: @nameparts = split(/\s+/, $name);
8: foreach $line (@form) {
9: @words = split(/\s+/, $line);
10: $i = 0;
11: while (1) {
12: last if (!defined($words[$i]));
13: if ($words[$i] eq "<name>") {
14: splice (@words, $i, 1, @nameparts);
15: $i += @nameparts;
16: } elsif ($words[$i] =~ /^<name>/) {
17: $punc = $words[$i];
18: $punc =~ s/<name>//;
19: @temp = @nameparts;
20: $temp[@temp-1] .= $punc;
21: splice (@words, $i, 1, @temp);
22: $i += @temp;
23: } else {
24: $i++;
25: }
26: }
27: $line = join (" ", @words);
28: }
29: $i = 0;
30: while (1) {
31: if (!defined ($form[$i])) {
32: $~ = "FLUSH";
33: write;
34: last;
35: }
36: if ($form[$i] =~ /^\s*$/) {
37: $~ = "FLUSH";
38: write;
39: $~ = "BLANK";
40: write;
41: $i++;
42: next;
43: }
44: if ($writeline ne "" &&
45: $writeline !~ / $/) {
46: $writeline .= " ";
47: }
48: $writeline .= $form[$i];
49: if (length ($writeline) < 60) {
50: $i++;
51: next;
52: }
53: $~ = "WRITELINE";
54: write;
55: $i++;
56: }
57: format WRITELINE =
58: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~
59: $writeline
60: .
61: format FLUSH =
62: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~
63: $writeline
64: .
65: format BLANK =
66:
67: .

$ program14_11
Fred
Hello Fred! This is your lucky day, Fred!
$
This pr ogr am st ar t s of f by r eading t he ent ir e f or m l et t er f r om t he f il e named
form int o t he ar r ay var iabl e @form. This makes it possibl e t o f or mat t he f or m l et t er
out put l at er on.
Lines 6 and 7 r ead t he name f r om t he st andar d input f il e and br eak int o individual
wor ds. This l ist of wor ds is st or ed in t he ar r ay var iabl e @nameparts.
The l oop in l ines 8-28 r eads each l ine in t he f or m l et t er and l ooks f or occur r ences of
t he st r ing <name>. Fir st , l ine 9 br eaks t he l ine int o individual wor ds. This l ist of wor ds is
st or ed in t he ar r ay var iabl e @words.
The while l oop st ar t ing in l ine 11 t hen examines each wor d of @words in t ur n. Line 12
checks whet her t he l oop has r eached t he end of t he l ist by cal l ing defined; if t he l oop
is past t he end of t he l ist , defined wil l r et ur n f al se, indicat ing t hat t he ar r ay el ement
is not def ined.
Lines 13-15 check whet her a wor d consist s ent ir el y of t he st r ing <name>. If it does, l ine
14 cal l s splice; t his cal l r epl aces t he wor d <name> wit h t he wor ds in t he name l ist
@nameparts.
If a wor d is not equal t o t he st r ing <name>, it might st il l cont ain <name> f ol l owed by a
punct uat ion char act er . To t est f or t his, l ine 16 t r ies t o mat ch t he pat t er n /^<name>/. If
it mat ches, l ines 17 and 18 isol at e t he punct uat ion in a singl e wor d. This punct uat ion is
st or ed in t he scal ar var iabl e $punc.
Lines 19 and 20 cr eat e a copy of t he name ar r ay @nameparts and append t he punct uat ion
t o t he l ast el ement of t he ar r ay. This ensur es t hat t he punct uat ion wil l appear in t he
f or m l et t er wher e it is supposed t o-r ight af t er t he l ast char act er of t he subst it ut ed
name. Line 21 t hen cal l s splice as in l ine 14.
Af t er t he wor ds in @words have been sear ched and t he name subst it ut ed f or <name>, l ine
27 joins t he wor ds back int o a singl e l ine. As an addit ional benef it , t he mul t ipl e spaces
and t abs in t he or iginal l ine have now been r epl aced by a singl e space, which wil l make
t he event ual f or mat t ed out put l ook nicer .
Lines 30-56 wr it e out t he out put . The st r ing t o be wr it t en is st or ed in t he scal ar
var iabl e $writeline. The pr ogr am ensur es t hat t he f or m-l et t er out put is f or mat t ed by
doing t he f ol l owing:
1. Fir st , t he pr int f or mat WRITELINE is def ined t o use t he ^<<<< val ue-f iel d f or mat .
This f or mat f it s as much of t he cont ent s of $writeline int o t he l ine as possibl e
and t hen del et es t he par t of $writeline t hat has been wr it t en out .
2. Lines 36-43 enabl e you t o add par agr aphs t o your f or m l et t er . Line 36 t est s
whet her an input l ine is bl ank. If it is, t he FLUSH pr int f or mat is used t o wr it e out
any out put f r om pr evious l ines t hat has not yet been pr int ed. (Because t he out put
l ine specif ied by FLUSH st ar t s wit h ~~, t he l ine is pr int ed onl y if it is not bl ank-in
ot her wor ds, if $writeline act ual l y cont ains some l ef t over t ext .) Then, t he BLANK
pr int f or mat wr it es a bl ank l ine.
3. Lines 44-47 check whet her a space needs t o be pl aced bet ween t he end of one input
l ine and t he beginning of t he next when f or mat t ing.
4. Lines 49-52 ensur e t hat $writeline is al ways l ong enough t o f il l t he val ue f iel d
specif ied by WRITELINE. This guar ant ees t hat t her e wil l be no unnecessar y space in
any of t he out put l ines.
5. When @form has been compl et el y r ead, l ines 32-34 ensur e t hat al l of t he out put
f r om pr evious l ines has been wr it t en by using t he FLUSH pr int f or mat .
(For mor e inf or mat ion on t he pr int f or mat s used in t his exampl e, r ef er t o Day 11,
"For mat t ing Your Out put .")
NOTE
You can use splice t o spl ice t he cont ent s of a scal ar
var iabl e int o an ar r ay. For exampl e:
splice (@array, 8, 1, $name);
This cr eat es a one-el ement l ist consist ing of t he
cont ent s of $name and adds it t o t he l ist st or ed in @array
(as t he eight h el ement )
Appending List Elements
You can use splice t o add a subl ist anywher e in a l ist . To do t his, specif y a l engt h f iel d
of 0. For exampl e:
splice (@array, 5, 0, "Hello", "there");
This cal l t o splice adds t he l ist ("Hello", "there") t o t he l ist st or ed in @array. Hello
becomes t he new sixt h el ement of $list, and there becomes t he new sevent h el ement ;
t he exist ing sixt h and sevent h el ement s, if t hey exist , become t he new eight h and nint h
el ement s, and ever y ot her el ement is al so pushed t o t he r ight .
To add a new el ement t o t he end of an exist ing ar r ay, specif y a skipelements val ue of -
1, as shown in t he f ol l owing:
splice (@array, -1, 0, "Hello");
This adds Hello as t he l ast el ement of t he l ist st or ed in @array.
List ing 14.12 is an exampl e of a pr ogr am t hat uses splice t o inser t an el ement int o a l ist .
This pr ogr am inser t s a wor d count af t er ever y t ent h wor d in a f il e.

List ing 14.12. A pr ogr am t hat uses splice t o inser t ar r ay el ement s.
1: #!/usr/local/bin/perl
2:
3: $count = 0;
4: while ($line = <STDIN>) {
5: chop ($line);
6: @words = split(/\s+/, $line);
7: $added = 0;
8: for ($i = 0; $i+$added < @words; $i++) {
9: if ($count > 0 && ($count + $i) % 10 == 0) {
10: splice (@words, $i+$added, 0,
11: $count + $i);
12: $added += 1;
13: }
14: }
15: $count += @words - $added;
16: $line = join (" ", @words);
17: print ("$line\n");
18: }

$ program14_12
Here is a line with some words on it.
Here are some more test words to count.
A B C D E F G H I J K L M N O P
^D
Here is a line with some words on it.
Here 10 are some more test words to count.
A B C 20 D E F G H I J K L M 30 N O P
$
This pr ogr am, l ike many of t he ot her s you have seen, r eads one l ine at a t ime
and br eaks t he l ine int o wor ds; t he ar r ay var iabl e @words cont ains t he l ist of wor ds f or
a par t icul ar l ine.
The scal ar var iabl e $count cont ains t he number of wor ds in t he l ines pr eviousl y r ead.
Lines 8 t hr ough 14 r ead each wor d in t he cur r ent input l ine in t ur n; at any given point ,
t he count ing var iabl e $i l ist s t he number of wor ds r ead in t he l ine, and t he sum of
$count and $i l ist s t he t ot al number of wor ds r ead in al l input l ines.
Line 9 adds t he val ue st or ed in $count t o t he val ue st or ed in $i; if t his val ue, t he
cur r ent wor d number , is a mul t ipl e of t en, l ines 10 and 11 cal l splice and inser t t he
cur r ent wor d number int o t he l ist . As a r esul t , ever y t ent h wor d is f ol l owed by it s
wor d number .
The scal ar var iabl e $added count s t he number of el ement s added t o t he l ist ; t his ensur es
t hat t he wor d number s added by l ines 10 and 11 ar e not incl uded as par t of t he wor d
count .
Af t er t he wor d number s have been inser t ed int o t he l ist , l ine 16 r ebuil ds t he input l ine
by joining t he el ement s of @words; t his new input l ine incl udes t he wor d number s. Line 17
t hen pr int s t he r ebuil t l ine.
Deleting List Elements
You can use splice t o del et e l ist el ement s wit hout r epl acing t hem. To do t his, cal l
splice and omit t he newlist ar gument . For exampl e:
@deleted = splice (@array, 8, 2);
This cal l t o splice del et es t he nint h and t ent h el ement s of t he l ist st or ed in @array. If
@array cont ains subsequent el ement s, t hese el ement s ar e shif t ed l ef t t o f il l t he gap.
The l ist of del et ed el ement s is r et ur ned and st or ed in @deleted.
List ing 14.13 r eads an input f il e, uses splice t o del et e al l wor ds gr eat er t han f ive
char act er s l ong, and wr it es out t he r esul t .

List ing 14.13. A pr ogr am t hat uses splice t o del et e wor ds.
1: #!/usr/local/bin/perl
2:
3: while ($line = <STDIN>) {
4: @words = split(/\s+/, $line);
5: $i = 0;
6: while (defined($words[$i])) {
7: if (length($words[$i]) > 5) {
8: splice(@words, $i, 1);
9: } else {
10: $i++;
11: }
12: }
13: $line = join (" ", @words);
14: print ("$line\n");
15: }

$ program14_13
this is a test of the program which removes long words
^D
this is a test of the which long words
$
This pr ogr am r eads one l ine of input at a t ime and br eaks each input l ine int o
wor ds. Line 7 cal l s length t o det er mine t he l engt h of a par t icul ar wor d. If t he wor d is
gr eat er t han f ive char act er s in l engt h, l ine 8 cal l s splice t o r emove t he wor d f r om t he
l ist .
NOTE
You al so can omit t he length ar gument when you cal l
splice. If you do, splice del et es ever yt hing af t er t he
el ement specif ied by skipelements:
splice (@array, 7);
This del et es t he sevent h and al l subsequent el ement s of
t he l ist st or ed in @array.
To del et e t he l ast el ement of a l ist , specif y -1 as t he
skipelements ar gument .
splice (@array, -1);
In al l cases, splice r et ur ns t he l ist of del et ed el ement s
The shift Function
One l ist oper at ion t hat is f r equent l y needed in a pr ogr am is t o r emove an el ement f r om
t he f r ont of a l ist . Because t his oper at ion is of t en per f or med, Per l pr ovides a special
f unct ion, shift, t hat handl es it .
shift r emoves t he f ir st el ement of t he l ist and moves (or "shif t s") ever y r emaining
el ement of t he l ist t o t he l ef t t o cover t he gap. shift t hen r et ur ns t he r emoved
el ement .
The synt ax f or t he shift f unct ion is
element = shift (arrayvar);
shift is passed one ar gument : an ar r ay var iabl e t hat cont ains a l ist . element is t he
r et ur ned el ement .
NOTE
shift r et ur ns t he undef ined val ue (equival ent t o t he
nul l st r ing) if t he l ist is empt y
Her e is a simpl e exampl e using shift:
@mylist = ("1", "2", "3");
$firstval = shift(@mylist);
This cal l t o shift r emoves t he f ir st el ement , 1, f r om t he l ist st or ed in @mylist. This
el ement is assigned t o $firstval. @mylist now cont ains t he l ist ("2", "3").
If you do not specif y an ar r ay var iabl e when you cal l shift, t he Per l int er pr et er
assumes t hat shift is t o r emove t he f ir st el ement f r om t he syst em ar r ay var iabl e @ARGV.
This var iabl e l ist s t he ar gument s suppl ied on t he command l ine when t he pr ogr am is
st ar t ed up. For exampl e, if you cal l a Per l pr ogr am named foo wit h t he f ol l owing
command:
foo arg1 arg2 arg3
@ARGV cont ains t he l ist ("arg1", "arg2", "arg3").
This def aul t f eat ur e of shift makes it handy f or pr ocessing command-l ine ar gument s.
List ing 14.14 is a simpl e pr ogr am t hat pr int s out it s ar gument s.

List ing 14.14. A pr ogr am t hat uses shift t o pr ocess t he command-l ine
ar gument s.
1: #!/usr/local/bin/perl
2:
3: while (1) {
4: $currarg = shift;
5: last if (!defined($currarg));
6: print ("$currarg\n");
7: }

$ program14_14 arg1 arg2 arg3
arg1
arg2
arg3
$
When t his pr ogr am is cal l ed, t he ar r ay var iabl e @ARGV cont ains a l ist of t he
val ues suppl ied as ar gument s t o t he pr ogr am. Line 4 cal l s shift t o r emove t he f ir st
ar gument f r om t he l ist and assign it t o $currarg.
If t her e ar e no el ement s (or none r emaining), shift r et ur ns t he undef ined val ue, and
t he cal l t o defined in l ine 5 r et ur ns f al se. This ensur es t hat t he l oop t er minat es when
t her e ar e no mor e ar gument s t o r ead.
NOTE
The shift f unct ion is equival ent t o t he f ol l owing cal l
t o splice:
splice (@array, 0, 1)
The unshift Function
To undo t he ef f ect of a shift f unct ion, cal l unshift.
The synt ax f or t he unshift f unct ion is
count = unshift (arrayvar, elements);
arrayvar is t he l ist (usual l y st or ed in an ar r ay var iabl e) t o add t o, and elements is t he
el ement or l ist of el ement s t o add. count is t he number of el ement s in t he r esul t ing l ist .
The f ol l owing is an exampl e of a cal l t o unshift:
unshift (@array, "newitem");
This adds t he el ement newitem t o t he f r ont of t he l ist st or ed in @array. The ot her
el ement s of t he l ist ar e moved t o t he r ight t o accommodat e t he new it em.
You can use unshift t o add mor e t han one el ement t o t he f r ont of an ar r ay. For
exampl e:
unshift (@array, @sublist1, "newitem", @sublist2);
This adds a l ist consist ing of t he l ist st or ed in @sublist1, t he el ement newitem, and t he
l ist st or ed in @sublist2 t o t he f r ont of t he l ist st or ed in @array.
unshift r et ur ns t he number of el ement s in t he new l ist , as shown in t he f ol l owing:
@array = (1, 2, 3);
$num = unshift (@array, "newitem");
This assigns 4 t o $num.
NOTE
The unshift f unct ion is equival ent t o cal l ing splice
wit h a skipelements val ue of 0 and a length val ue of 0.
For exampl e, t he f ol l owing st at ement s ar e equival ent :
unshift (@array, "item1", "item2");
splice (@array, 0, 0, "item1", "item2")
The push Function
As you have seen, t he unshift f unct ion adds an el ement t o t he f r ont of a l ist . To add an
el ement t o t he end of a l ist , cal l t he push f unct ion.
The synt ax f or t he push f unct ion is
push (arrayvar, elements);
arrayvar is t he l ist (usual l y st or ed in an ar r ay var iabl e) t o add t o, and elements is t he
el ement or l ist of el ement s t o add.
The f ol l owing is an exampl e t hat uses push:
push (@array, "newitem");
This adds t he el ement newitem t o t he end of t he l ist .
The end of t he l ist is al ways assumed t o be t he l ast def ined el ement . For exampl e,
consider t he f ol l owing st at ement s:
@array = ("one", "two");
$array[3] = "four";
push (@array, "five");
Her e, t he f ir st st at ement cr eat es a t wo-el ement l ist and assigns it t o @array. The second
st at ement assigns four t o t he f our t h el ement of @array. Because t he f our t h el ement is
now t he l ast el ement of @array, t he cal l t o push cr eat es a f if t h el ement , even t hough
t he t hir d el ement is undef ined. @array now cont ains t he l ist
("one", "two", "", "four", "five");
The undef ined t hir d el ement is, as al ways, equival ent t o t he nul l st r ing.
As wit h unshift, you can use push t o add mul t ipl e el ement s t o t he end of a l ist , as in t his
exampl e:
push (@array, @sublist1, "newitem", @sublist2);
Her e, t he l ist consist ing of t he cont ent s of @sublist1, t he el ement newitem, and t he
cont ent s of @sublist2 is added t o t he end of t he l ist st or ed in @array.
NOTE
push is equival ent t o a cal l t o splice wit h t he
skiparguments ar gument set t o t he l engt h of t he ar r ay.
This means t hat t he f ol l owing st at ement s ar e
equival ent :
push (@array, "newitem");
splice (@array, @array, 0, "newitem")
The pop Function
The pop f unct ion undoes t he ef f ect of push. It r emoves t he l ast el ement f r om t he end of
a l ist . The r emoved el ement is r et ur ned.
The synt ax f or t he pop f unct ion is
element = pop (arrayvar);
arrayvar is t he ar r ay el ement f r om which an el ement is t o be r emoved. element is t he
r et ur ned el ement .
For exampl e, t he f ol l owing st at ement r emoves t he l ast el ement f r om t he l ist st or ed in
@array and assigns it t o t he scal ar var iabl e $popped:
$popped = pop (@array);
If t he l ist passed t o pop is empt y, pop r et ur ns t he undef ined val ue.
NOTE
pop is equival ent t o a cal l t o splice wit h a
skipelements val ue of -1 (indicat ing t he l ast el ement of
t he ar r ay). This means t hat t he f ol l owing st at ement s
behave in t he same way:
$popped = pop (@array);
$popped = splice (@array, -1)
Creating Stacks and Queues
The f unct ions you have just seen ar e handy f or const r uct ing t wo commonl y used dat a
st r uct ur es: st acks and queues. The f ol l owing sect ions pr ovide exampl es t hat use a st ack
and a queue.
Creating a Stack
A stack is a dat a st r uct ur e t hat behaves l ike a st ack of pl at es in a cupboar d: t he l ast
it em added t o t he st ack is al ways t he f ir st it em r emoved. Dat a it ems t hat ar e added t o
t he st ack ar e said t o be pushed ont o t he st ack; it ems which ar e r emoved f r om t he st ack
ar e popped of f t he st ack.
As you might have guessed, t he f unct ions push and pop enabl e you t o cr eat e a st ack in a
Per l pr ogr am. List ing 14.15 is an exampl e of a pr ogr am t hat uses a st ack t o per f or m
ar it hmet ic oper at ions. It wor ks as f ol l ows:
1. Two number s ar e pushed ont o t he st ack.
2. The pr ogr am r eads an ar it hmet ic oper at or , such as + or -. The t wo number s ar e
popped of f t he st ack, and t he oper at ion is per f or med.
3. The r esul t of t he oper at ion is pushed ont o t he st ack, enabl ing it t o be used in
f ur t her ar it hmet ic oper at ions.
Af t er al l t he ar it hmet ic oper at ions have been per f or med, t he st ack shoul d consist of a
singl e el ement , which is t he f inal r esul t .
The number s and oper at or s ar e r ead f r om t he st andar d input f il e.
Not e t hat List ing 14.15 is t he "inver se" of List ing 9.12. In t he l at t er pr ogr am, t he
ar it hmet ic oper at or s appear f ir st , f ol l owed by t he val ues.

List ing 14.15. A pr ogr am t hat uses a st ack t o per f or m ar it hmet ic.
1: #!/usr/local/bin/perl
2:
3: while (defined ($value = &read_value)) {
4: if ($value =~ /^\d+$/) {
5: push (@stack, $value);
6: } else {
7: $firstpop = pop (@stack);
8: $secondpop = pop (@stack);
9: push (@stack,
10: &do_math ($firstpop, $secondpop, $value));
11: }
12: }
13: $result = pop (@stack);
14: if (defined ($result)) {
15: print ("The result is $result.\n");
16: } else {
17: die ("Stack empty when printing result.\n");
18: }
19:
20: sub read_value {
21: local ($retval);
22: $input =~ s/^\s+//;
23: while ($input eq "") {
24: $input = <STDIN>;
25: return if ($input eq "");
26: $input =~ s/^\s+//;
27: }
28: $input =~ s/^\S+//;
29: $retval = $&;
30: }
31:
32: sub do_math {
33: local ($val2, $val1, $operator) = @_;
34: local ($result);
35:
36: if (!defined($val1) || !defined($val2)) {
37: die ("Missing operand");
38: }
39: if ($operator =~ m.^[+-/*]$. ) {
40: eval ("\$result = \$val2 $operator \$val1");
41: } else {
42: die ("$operator is not an operator");
43: }
44: $result; # ensure the proper return value
45: }

$ program14_15
11 4 + 26 -
^D
The result is 11.
$
Bef or e going int o det ail s, l et 's f ir st t ake a l ook at how t he pr ogr am pr oduces
t he f inal r esul t , which is 11:
1. The pr ogr am st ar t s of f by r eading t he number s 11 and 4 and pushing t hem ont o t he
st ack. If t he st ack is l ist ed f r om t he t op down, it now l ooks l ike t his:
4
11
Anot her way t o l ook at t he st ack is t his: At pr esent , t he l ist st or ed in @stack is
(11, 4).
2. The pr ogr am t hen r eads t he + oper at or , pops t he 4 and 11 of f t he st ack, and
per f or ms t he addit ion, pushing t he r esul t ont o t he st ack. The st ack now cont ains
a singl e val ue:
15
3. The next val ue, 26, is pushed ont o t he st ack, which now l ooks l ike t his:
26
15
4. The pr ogr am t hen r eads t he - oper at or , pops 15 and 26 of f t he st ack, and subt r act s
15 f r om 26. The r esul t , 11, is pushed ont o t he st ack.
5. Because t her e ar e no mor e oper at ions t o per f or m, 11 becomes t he f inal r esul t .
This pr ogr am del egat es t o t he subr out ine read_value t he t ask of r eading val ues and
oper at or s. This subr out ine r eads a l ine of t he st andar d input f il e and ext r act s t he non-
bl ank it ems on t he l ine. Each cal l t o read_value ext r act s one it em f r om an input l ine;
when an input l ine is exhaust ed, read_value r eads t he next one. When t he input f il e is
exhaust ed and t her e ar e no mor e it ems t o r et ur n, $input becomes t he undef ined val ue,
which is equival ent t o t he nul l st r ing; t he cal l t o defined in l ine 3 t est s f or t his
condit ion.
If an it em r et ur ned by read_value is a number , l ine 5 cal l s push, which pushes t he number
ont o t he st ack. If an it em is not a number , t he pr ogr am assumes it is an oper at or . At t his
point , pop is cal l ed t wice t o r emove t he l ast t wo number s f r om t he st ack, and do_math is
cal l ed t o per f or m t he ar it hmet ic oper at ion.
The do_math subr out ine uses a coupl e of t r icks. Fir st , defined is cal l ed t o see whet her
t her e ar e, in f act , t wo number s t o add. If one or bot h of t he number s does not exist , t he
pr ogr am t er minat es.
Next , t he subr out ine uses t he pat t er n m.^[+-*/]$. t o check whet her t he char act er
st r ing st or ed in $operator is, in f act , a l egal ar it hmet ic oper at or . (Recal l t hat you can
use a pat t er n del imit er ot her t han / by specif ying m f ol l owed by t he char act er you
want t o use as t he del imit er . In t his case, t he per iod char act er is t he pat t er n del imit er .)
Final l y, t he subr out ine cal l s eval t o per f or m t he ar it hmet ic oper at ion. eval r epl aces
t he name $operator wit h it s cur r ent val ue, and t hen t r eat s t he r esul t ing char act er
st r ing as an execut abl e st at ement ; t his per f or ms t he ar it hmet ic oper at ion specif ied by
$operator. Using eval her e saves space; t he onl y al t er nat ive is t o use a compl icat ed if-
elseif st r uct ur e.
The r esul t of t he oper at ion is r et ur ned in $result. Lines 9 and 10 t hen pass t his val ue t o
push, which pushes t he r esul t ont o t he st ack. This enabl es you t o use t he r esul t in
subsequent oper at ions.
When t he l ast ar it hmet ic oper at ion has been per f or med, t he f inal r esul t is st or ed as t he
t op el ement of t he st ack. Line 13 pops t his el ement , and l ine 15 pr int s it .
Not e t hat t his pr ogr am al ways assumes t hat t he l ast el ement pushed ont o t he st ack is
t o be on t he l ef t of t he ar it hmet ic oper at ion. To r ever se t his, al l you need t o do is
change t he or der of $val1 and $val2 in l ine 33. (Some pr ogr ams t hat manipul at e st acks
al so pr ovide an oper at ion which r ever ses t he or der of t he t op t wo el ement s of a st ack.)
The pop f unct ion r et ur ns t he undef ined val ue if t he
st ack is empt y. Because t he undef ined val ue is
equival ent t o t he nul l st r ing, and t he nul l st r ing is
t r eat ed as 0 in ar it hmet ic oper at ions, your pr ogr am wil l
not compl ain if you t r y t o pop a number f r om an empt y
st ack.
To ensur e t hat you get t he r esul t you want , al ways
cal l defined af t er you cal l pop t o ensur e t hat a val ue
has act ual l y been popped f r om t he st ack
Creating a Queue
A queue is a dat a st r uct ur e t hat pr ocesses dat a in t he or der in which it is ent er ed; such
dat a st r uct ur es ar e known as f ir st -in, f ir st -out (or FIFO) st r uct ur es. (A st ack, on t he
ot her hand, is an exampl e of a l ast -in, f ir st -out , or LIFO, st r uct ur e.)
To cr eat e a queue, use t he f unct ion push t o add it ems t o t he queue, and cal l shift t o
r emove el ement s f r om it . Because push adds t o t he r ight of t he l ist and shift r emoves
f r om t he l ef t , el ement s ar e pr ocessed in t he or der in which t hey appear .
List ing 14.16 is an exampl e of a pr ogr am t hat uses a queue t o add a set of number s
r et r ieved via a pipe. Each input l ine can consist of mor e t han one number , and t he
number s ar e added in t he or der l ist ed.
The input /out put exampl e shown f or t his l ist ing assumes t hat t he number s r et r ieved via
t he pipe ar e 11, 12, and 13.

List ing 14.16. A pr ogr am t hat il l ust r at es t he use of a queue.
1: #!/usr/local/bin/perl
2:
3: open (PIPE, "numbers|") ||
4: die ("Can't open pipe");
5: $result = 0;
6: while (defined ($value = &readnum)) {
7: $result += $value;
8: }
9: print ("The result is $result.\n");
10:
11: sub readnum {
12: local ($line, @numbers, $retval);
13: while ($queue[0] eq "") {
14: $line = <PIPE>;
15: last if ($line eq "");
16: $line =~ s/^\s+//;
17: @numbers = split (/\s+/, $line);
18: push (@queue, @numbers);
19: }
20: $retval = shift(@queue);
21: }

$ program14_16
The result is 36.
$
This pr ogr am assumes t hat a pr ogr am named numbers exist s, and t hat it s out -
put is a st r eam of number s. Mul t ipl e number s can appear on a singl e l ine of t his out put .
Lines 3 and 4 associat e t he f il e var iabl e PIPE wit h t he out put f r om t he numbers command.
Lines 6-8 cal l t he subr out ine readnum t o obt ain a number and t hen add it t o t he r esul t
st or ed in $result. This subr out ine r eads input f r om t he pipe, br eaks it int o individual
number s, and t hen cal l s push t o add t he number s t o t he queue st or ed in @queue. Line 20
t hen cal l s shift t o r et r ieve t he f ir st el ement in t he queue, which is r et ur ned t o t he
main pr ogr am.
If an input l ine is bl ank, t he cal l t o split in l ine 17 pr oduces t he empt y l ist , which
means t hat not hing is added t o @queue. This ensur es t hat input is r ead f r om t he pipe unt il
a non-bl ank l ine is r ead or unt il t he input is exhaust ed.
The split Function
The split f unct ion was f ir st discussed on Day 5, "List s and Ar r ay Var iabl es." It spl it s a
char act er st r ing int o a l ist of el ement s.
The usual synt ax f or t he split f unct ion is
list = split (pattern, value);
Her e, value is t he char act er st r ing t o be spl it . pattern is a pat t er n t o be sear ched f or . A
new el ement is st ar t ed ever y t ime pattern is mat ched. (pattern is not incl uded as par t of
any el ement .) The r esul t ing l ist of el ement s is r et ur ned in list.
For exampl e, t he f ol l owing st at ement br eaks t he char act er st r ing st or ed in $line int o
el ement s, which ar e st or ed in @list:
@list = split (/:/, $line);
A new el ement is st ar t ed ever y t ime t he pat t er n /:/ is mat ched. If $line cont ains
This:is:a:string, t he r esul t ing l ist is ("This", "is", "a", "string").
If you l ike, you can specif y t he maximum number of el ement s of t he l ist pr oduced by
split by specif ying t he maximum as t he t hir d ar gument . For exampl e:
$line = "This:is:a:string";
@list = split (/:/, $line, 3);
As bef or e, t his br eaks t he st r ing st or ed in $line int o el ement s. Af t er t hr ee el ement s
have been cr eat ed, no mor e new el ement s ar e cr eat ed. Any subsequent mat ches of t he
pat t er n ar e ignor ed. In t his case, t he l ist assigned t o @list is ("This", "is",
"a:string").
TIP
If you use split wit h a l imit , you can assign t o sever al
scal ar var iabl es at once:
$line = "11 12 13 14 15";
($var1, $var2, $line) = split (/\s+/, $line, 3);
This spl it s $line int o t he l ist ("11", "12", "13 14 15").
$var1 is assigned 11, $var2 is assigned 12, and $line is
assigned "13 14 15". This enabl es you t o assign t he
"l ef t over s" t o a singl e var iabl e, which can t hen be spl it
again at a l at er t ime
The sort and reverse Functions
The sort f unct ion sor t s a l ist in al phabet ical or der , as f ol l ows:
@sorted = sort (@list);
The sor t ed l ist is r et ur ned.
The reverse f unct ion r ever ses t he or der of a l ist :
@reversed = reverse (@list);
For mor e inf or mat ion on t he sort and reverse f unct ions, see Day 5. For inf or mat ion on
how you can specif y t he sor t or der t hat sort is t o use, see Day 9, "Using Subr out ines."
The map Function
The map f unct ion, def ined onl y in Per l 5, enabl es you t o use each of t he el ement s of a
l ist , in t ur n, as an oper and in an expr ession.
The synt ax f or t he map f unct ion is
resultlist = map(expr, list);
list is t he l ist of el ement s t o be used as oper ands or ar gument s; t his l ist is copied by map,
but is not it sel f changed. expr is t he expr ession t o be r epeat ed. The r esul t s of t he
r epeat ed eval uat ion of t he expr ession ar e st or ed in a l ist , which is r et ur ned in
resultlist.
expr assumes t hat t he syst em var iabl e $_ cont ains t he el ement of t he l ist cur r ent l y
being used as an oper and. For exampl e:
@list = (100, 200, 300);
@results = map($_+1, @list);
This eval uat es t he expr ession $_+1 f or each of 100, 200, and 300 in t ur n. The r esul t s, 101,
201, and 301, r espect ivel y, ar e f or med int o t he l ist (101, 201, 301). This l ist is t hen
assigned t o @results.
To use map wit h a subr out ine, just pass $_ t o t he subr out ine, as in t he f ol l owing:
@results = map(&mysub($_), @list);
This cal l s t he subr out ine mysub once f or each el ement of t he l ist st or ed in @list. The
val ues r et ur ned by mysub ar e st or ed in a l ist , which is assigned t o @results.
This al so wor ks wit h buil t -in f unct ions:
@results = map(chr($_), @list);
@results = map(chr, @list); # same as above,
since $_ is the default argument for chr
This conver t s each el ement of t he l ist in @list t o it s ASCII char act er equival ent . The
r esul t ing l ist of char act er s is st or ed in @results.
NOTE
For mor e inf or mat ion on t he $_ syst em var iabl e, r ef er t o
Day 17
The wantarray Function
In Per l , t he behavior of some buil t -in f unct ions depends on whet her t hey ar e deal ing
wit h scal ar val ues or l ist s. For exampl e, t he chop f unct ion eit her chops t he l ast
char act er of a singl e st r ing or chops t he l ast char act er of ever y el ement of a l ist :
chop($scalar); # chop a single string
chop(@array); # chop every element of an array
Per l 5 enabl es you t o def ine simil ar t wo-way behavior f or your subr out ines using t he
wantarray f unct ion. (This f unct ion is not def ined in Per l 4.)
The synt ax f or t he wantarray f unct ion is
result = wantarray();
result is a non-zer o val ue if t he subr out ine is expect ed t o r et ur n a l ist , and is zer o if
t he subr out ine is expect ed t o r et ur n a scal ar val ue.
List ing 14.17 il l ust r at es how wantarray wor ks.

List ing 14.17. A pr ogr am t hat uses t he wantarray f unct ion.
1: #!/usr/local/bin/perl
2:
3: @array = &mysub();
4: $scalar = &mysub();
5:
6: sub mysub {
7: if (wantarray()) {
8: print ("true\n");
9: } else {
10: print ("false\n");
11: }
12: }

$ program14_17
true
false
$
When mysub is f ir st cal l ed in l ine 3, t he r et ur n val ue is expect ed t o be a l ist ,
which means t hat wantarray r et ur ns a non-zer o (t r ue) val ue in l ine 7. The second cal l
t o mysub in l ine 4 expect s a scal ar r et ur n val ue, which means t hat wantarray r et ur ns
zer o (f al se).
Associative Array Functions
Per l pr ovides a var iet y of f unct ions t hat oper at e on associat ive ar r ays. Most of t hese
f unct ions ar e descr ibed in det ail on Day 10, "Associat ive Ar r ays"; a br ief descr ipt ion of
each f unct ion is pr esent ed her e.
The keys Function
The keys f unct ion r et ur ns a l ist of t he subscr ipt s of t he el ement s of an associat ive
ar r ay.
The synt ax f or keys is st r aight f or war d:
list = keys (assoc_array);
assoc_array is t he associat ive ar r ay f r om which subscr ipt s ar e t o be ext r act ed, and list
is t he r et ur ned l ist of subscr ipt s.
For exampl e:
%array = ("foo", 26, "bar", 17);
@list = keys(%array);
This cal l t o keys assigns ("foo", "bar") t o @list. (The el ement s of t he l ist might be in a
dif f er ent or der . To specif y a par t icul ar or der , sor t t he l ist using t he sort f unct ion.)
keys of t en is used wit h foreach, as in t he f ol l owing exampl e:
foreach $subscript (keys (%array)) {
# stuff goes here
}
This l oops once f or each subscr ipt of t he ar r ay.
The values Function
The values f unct ion r et ur ns a l ist consist ing of al l t he val ues in an associat ive ar r ay.
The synt ax f or t he values f unct ion is
list = values (assoc_array);
assoc_array is t he associat ive ar r ay f r om which val ues ar e t o be ext r act ed, and list is
t he r et ur ned l ist of val ues.
The f ol l owing is an exampl e t hat uses values:
%array = ("foo", 26, "bar", 17);
@list = values(%array);
This assigns t he l ist (26, 17) t o @list (not necessar il y in t his or der ).
The each Function
The each f unct ion r et ur ns an associat ive ar r ay el ement as a t wo-el ement l ist . The l ist
consist s of t he associat ive ar r ay subscr ipt and it s associat ed val ue. Successive cal l s t o
each r et ur n anot her associat ive ar r ay el ement .
The synt ax f or t he each f unct ion is
pair = each (assoc_array);
assoc_array is t he associat ive ar r ay f r om which pair s ar e t o be r et ur ned, and pair is t he
subscr ipt -el ement pair r et ur ned.
The f ol l owing is an exampl e:
%array = ("foo", 26, "bar", 17);
@list = each(%array);
The f ir st cal l t o each assigns eit her ("foo", 26) or ("bar", 17) t o @list. A subsequent
cal l r et ur ns t he ot her el ement , and a t hir d cal l r et ur ns an empt y l ist . (The or der in
which t he el ement s ar e r et ur ned depends on how t he l ist is st or ed; no par t icul ar or der
is guar ant eed.)
The delete Function
The delete f unct ion del et es an associat ive ar r ay el ement .
The synt ax f or t he delete f unct ion is
element = delete (assoc_array_item);
assoc_array_item is t he associat ive ar r ay el ement t o be del et ed, and element is t he
val ue of t he del et ed el ement .
The f ol l owing is an exampl e:
%array = ("foo", 26, "bar", 17);
$retval = delete ($array{"foo"});
Af t er delete is cal l ed, t he associat ive ar r ay %array cont ains onl y one el ement : t he
el ement wit h t he subscr ipt bar. $retval is assigned t he val ue of t he del et ed el ement foo,
which in t his case is 26.
The exists Function
The exists f unct ion, def ined onl y in Per l 5, enabl es you t o det er mine whet her a
par t icul ar el ement of an associat ive ar r ay exist s.
The synt ax f or t he exists f unct ion is
result = exists(element);
element is t he el ement of t he associat ive ar r ay t hat is being t est ed f or exist ence. result
is non-zer o if t he el ement exist s, and zer o if it does not .
The f ol l owing is an exampl e:
$result = exists($myarray{$mykey});
$result is nonzer o if $myarray{$mykey} exist s.
Summary
Today, you l ear ned about f unct ions t hat manipul at e scal ar val ues and conver t t hem
f r om one f or m t o anot her , and about f unct ions t hat manipul at e l ist s.
The chop f unct ion r emoves t he l ast char act er f r om a scal ar val ue or f r om each el ement
of a l ist .
The crypt f unct ion encr ypt s a scal ar val ue, using t he same met hod t hat t he UNIX
passwor d encr ypt or uses.
The int f unct ion t akes a f l oat ing-point number and get s r id of ever yt hing af t er t he
decimal point .
The defined f unct ion checks whet her a scal ar var iabl e, ar r ay el ement , or ar r ay has
been assigned t o. The undef f unct ion enabl es you t o t r eat a pr eviousl y def ined scal ar
var iabl e, ar r ay el ement , or ar r ay as if it is undef ined. scalar enabl es you t o t r eat an
ar r ay or l ist as if it is a scal ar val ue.
The ot her f unct ions descr ibed in t oday's l esson conver t val ues f r om one f or m int o
anot her . The hex and oct f unct ions r ead hexadecimal and oct al const ant s and conver t
t hem int o decimal f or m. The ord f unct ion conver t s a char act er int o it s ASCII decimal
equival ent . pack and unpack conver t a scal ar val ue int o a f or mat t hat can be st or ed in
machine memor y, and vice ver sa. vec enabl es you t o t r eat a val ue as an ar r ay of numer ic
val ues, each of which is a cer t ain number of bit s l ong.
The grep f unct ion enabl es you t o ext r act t he el ement s of a l ist t hat mat ch a par t icul ar
pat t er n. This f unct ion can be used in conjunct ion wit h t he f il e-t est oper at or s.
The splice f unct ion enabl es you t o ext r act a por t ion of a l ist or inser t a subl ist int o a
l ist . The shift and pop f unct ions r emove an el ement f r om t he l ef t and r ight ends of a
l ist , and t he unshift and push f unct ions add one or mor e el ement s t o t he l ef t and r ight
ends of a l ist . You can use push, pop, and shift t o cr eat e st acks and queues.
The split f unct ion enabl es you t o br eak a char act er st r ing int o l ist el ement s. You can
impose an upper l imit on t he number of l ist el ement s t o be cr eat ed.
The sort f unct ion sor t s a l ist in a specif ied or der . The reverse f unct ion r ever ses t he
or der of t he el ement s in a l ist .
The map f unct ion copies a l ist and t hen per f or ms an oper at ion on ever y el ement of t he
l ist .
The wantarray f unct ion enabl es you t o det er mine whet her t he st at ement t hat cal l ed a
subr out ine is expect ing a scal ar r et ur n val ue or a l ist .
Five f unct ions ar e def ined t hat manipul at e associat ive ar r ays:
G keys, which r et ur ns a l ist of t he ar r ay subscr ipt s
G values, which r et ur ns a l ist of t he ar r ay val ues
G each, which r et ur ns a t wo-el ement l ist consist ing of an ar r ay subscr ipt and it s
val ue
G delete, which del et es an el ement
G exists, which checks whet her a par t icul ar el ement exist s
Q&A
Q: Why is t he undef ined val ue equival ent t o t he nul l st r ing?
A: Basical l y, t o keep Per l pr ogr ams f r om bl owing up if t hey t r y t o access a var iabl e
t hat has not yet been assigned t o.
Q: Why does oct handl e hexadecimal const ant s t hat st ar t wit h 0x or 0X?
A: Ther e is no par t icul ar r eason, except t hat it 's a l it t l e mor e convenient . If you
f ind t hat it bot her s you t o use oct t o conver t a hexadecimal const ant , get r id of
t he l eading 0x or 0X (using t he subst it ut e oper at or ) and cal l hex inst ead.
Q: I want t o put a passwor d check in my pr ogr am. How can I ensur e t hat it is
secur e?
A: Do t wo t hings:
G Don't incl ude t he unencr ypt ed t ext of your passwor d in your pr ogr am
sour ce. Peopl e can t hen f ind out t he passwor d just by r eading t he f il e.
G Use a passwor d t hat is not a r eal Engl ish-l anguage wor d or pr oper name.
Incl ude at l east one digit . This makes your passwor d har der t o "cr ack."
Q: Why does int t r uncat e inst ead of r ounding?
A: Some pr ogr ams might f ind it usef ul t o just r et r ieve t he int eger par t of a f l oat ing-
point number . (For exampl e, in ear l ier chapt er s, you have seen int used in
conjunct ion wit h rand t o r et ur n a r andom int eger .)
You can al ways add 0.5 t o your number bef or e cal l ing int, which wil l
ef f ect ivel y r ound it up when necessar y.
Q: When I pack int eger s using t he s or i pack-f or mat char act er s, t he bit s don' t
appear in t he or der I was expect ing. What is happening?
A: Most machines enabl e you t o st or e int eger s t hat ar e mor e t han one byt e l ong
(t wo- and f our -byt e int eger s usual l y ar e suppor t ed). However , each machine does
not st or e a mul t ibyt e int eger in t he same way. Some machines st or e t he most
signif icant byt e of a wor d at a l ower addr ess; t hese machines ar e cal l ed big-
endian machines because t he big end of a wor d is f ir st . Ot her machines, cal l ed little-
endian machines, st or e t he l east signif icant byt e of a wor d at a l ower byt e
addr ess.
If you ar e not get t ing t he r esul t you expect , you might be expect ing big-endian
and get t ing l it t l e-endian, or vice ver sa.
Q: The splice f unct ion wor ks by shif t ing el ement s t o t he r ight or l ef t t o make
r oom or f il l gaps. Is t his inef f icient ?
A: No. The Per l int er pr et er act ual l y st or es a l ist as a sequence of point er s (memor y
addr esses). Al l splice has t o do is r ear r ange t he point er s. This hol ds t r ue al so
f or sort and reverse.
Q: Can I use each t o wor k t hr ough an associat ive ar r ay in a specif ied or der ?
A: No. If you need t o access t he el ement s of an associat ive ar r ay in a specif ied or der ,
use keys and sort t o sor t t he subscr ipt s, and t hen r et r ieve t he val ue associat ed
wit h each el ement .
Q: If I am using values wit h foreach, can I r et r ieve t he subscr ipt associat ed
wit h a par t icul ar val ue if I need it ?
A: No. If you ar e l ikel y t o need t he subscr ipt s as wel l as t heir val ues, use each or
keys.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. What f or mat does each of t he f ol l owing pack-f or mat char act er s specif y?
a. A
b. A
c. d
d. p
e. @
2. What do t hese unpack-f or mat specif ier s do?
a. "a"
b. "@4A10i*"
c. "@*X4C*"
d. "ix4iX8i"
e. "b*X*B*"
3. What val ue is st or ed in $value by t he f ol l owing?
a. The st at ement s
$vector = pack ("b*", "10110110");
$value = vec ($vector, 3, 1);
b. The st at ement s
$vector = pack ("b*", "10110110");
$value = vec ($vector, 1, 2);
4. What 's t he dif f er ence bet ween defined and undef?
5. Assume @list cont ains ("1", "2", "3", "4", "5"). What ar e t he cont ent s of
@list af t er t he f ol l owing st at ement ?
a. splice (@list, 0, 1, "new");
b. splice (@list, 2, 0, "test1", "test2");
c. splice (@list, -1, 1, "test1", "test2");
d. splice (@list, 2, 1);
e. splice (@list, 3);
6. What do t he f ol l owing st at ement s r et ur n?
a. grep (!/^!/, @array);
b. grep (/\b\d+\b/, @array);
c. grep (/./, @array);
d. grep (//, @array);
7. What is t he dif f er ence bet ween shift and unshift?
8. What ar gument s t o splice ar e equival ent t o t he f ol l owing f unct ion cal l s?
a. shift (@array);
b. pop (@array);
c. push (@array, @sublist);
d. unshift (@array, @sublist);>
9. How can you cr eat e a st ack using shift, pop, push, or unshift?
10. How can you cr eat e a queue using shift, pop, push, or unshift?
Exercises
1. Wr it e a pr ogr am t hat r eads t wo binar y st r ings of any l engt h, adds t hem t oget her ,
and wr it es out t he binar y out put . (Hint : This is a r eal l y nast y pr obl em. To get t his
t o wor k, you wil l need t o ensur e t hat your bit st r ings ar e a mul t ipl e of eight bit s
by adding zer os at t he f r ont .)
2. Wr it e a pr ogr am t hat r eads t wo hexadecimal st r ings of any l engt h, adds t hem
t oget her , and wr it es out t he hexadecimal out put . (Hint : This is a st r aight f or war d
modif icat ion of Exer cise 1.)
3. Wr it e a pr ogr am t hat uses int t o r ound a val ue t o t wo decimal pl aces. (Hint : This
is t r ickier t han it seems.)
4. Wr it e a pr ogr am t hat encr ypt s a passwor d and t hen asks t he user t o guess it . Give
t he user t hr ee chances t o get it r ight .
5. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
$bitstring = "00000011";
$packed = pack("b*", $bitstring);
$highbit = vec($packed, 0, 1);
print ("The high-order bit is $highbit\n");
6. Wr it e a pr ogr am t hat uses splice t o sor t a l ist in numer ic or der .
7. Wr it e a pr ogr am t hat "f l ips" an associat ive ar r ay; t hat is, t he subscr ipt s of t he ol d
ar r ay become t he val ues of t he new, and vice ver sa. Pr int an er r or message if t he
ol d ar r ay has t wo subscr ipt s wit h ident ical val ues.
8. Wr it e a pr ogr am t hat r eads a f il e f r om st andar d input , br eaks each l ine int o
wor ds, uses grep t o get r id of al l wor ds l onger t han f ive char act er s, and pr int s
t he f il e.
9. Wr it e a pr ogr am t hat r eads an input l ine and uses split t o r ead and pr int one
wor d of t he l ine at a t ime.
10. BUG BUSTER: What is wr ong wit h t he f ol l owing subr out ine?
sub retrieve_first_element {
local ($retval);
$retval = unshift(@array);
}

Week
2
Week 2 in Review
By now, you know enough about pr ogr amming in Per l t o wr it e some quit e power f ul
pr ogr ams. The pr ogr am in List ing R2.1 il l ust r at es some of t he concept s you've l ear ned
t his week. It pr ompt s you f or a dir ect or y name, l ist s t he subdir ect or ies f or t hat
dir ect or y, and st or es t hem in an associat ive ar r ay f or l at er access. It al so enabl es you
t o move about in t he dir ect or y hier ar chy and pr int t he names of t he f il es in any
dir ect or y.

List ing R2.1. Br owsing dir ect or ies and pr int ing t heir cont ent s.
1: #!/usr/local/bin/perl
2:
3: $dircount = 0;
4: $curdir = "";
5: while (1) {
6: # if we don't have a current directory, get one
7: if ($curdir eq "") {
8: print ("Enter directory to list:\n");
9: $curdir = <STDIN>;
10: $curdir =~ s/^\s+|\s+$//g;
11: $curdir = &followlink($curdir);
12: &readsubdirs($curdir);
13: }
14: $curdir = &menudir($curdir);
15: }
16:
17:
18: # Find all subdirectories of the given directory,
19: # and store them in an associative array.
20: #
21: # The associative array subscripts and values are:
22: # <directory name>: 1
23: # (indicates that directory has been read)
24: # <directory name>.<num> the <num>th subdirectory
25:
26: sub readsubdirs {
27: local ($dirname) = @_;
28: local ($dirvar, $subdircount, $name, $index);
29:
30: # open the current directory;
31: # $dircount ensures that each file variable is unique
32: $dirvar = "DIR" . ++$dircount;
33: if (!opendir ($dirvar, $dirname)) {
34: warn ("Can't open $dirname\n");
35: return;
36: }
37:
38: # read all the subdirectories; store in a standard array
39: chdir ($dirname);
40: $subdircount = 0;
41: while ($name = readdir ($dirvar)) {
42: next if ($name eq ".");
43: if ($dirname eq "/") {
44: $name = $dirname . $name;
45: } else {
46: $name = $dirname . "/" . $name;
47: }
48: if (-d $name) {
49: $dirarray[$subdircount++] = $name;
50: }
51: }
52: closedir ($dirvar);
53:
54: # sort the standard array; assign the sorted array to the
55: # associative array
56: @dirarray = sort (@dirarray);
57: for ($index = 0; $index < $subdircount; $index++) {
58: $dirarray {$dirname . $index} =
$dirarray[$index];
59: }
60: undef (@dirarray);
61: $dirarray{$dirname} = 1;
62: }
63:
64:
65: # Display the subdirectories of the current directory and the
66: # available menu options.
67:
68: sub menudir {
69: local ($curdir) = @_;
70: local ($base) = 0;
71: local ($command, $count, $subdir);
72:
73: while (1) {
74: print ("\nCurrent directory is: $curdir\n");
75: print ("\nSubdirectories:\n");
76: if ($base > 0) {
77: print ("<more up>\n");
78: }
79: for ($count=0; $count<10; $count++) {
80: $subdir = $count+$base;
81: $subdir = $dirarray{$curdir.$subdir};
82: last if ($subdir eq "");
83: print ("$count: $subdir\n");
84: }
85: if ($dirarray{$curdir.($base+10)} ne "") {
86: print ("<more down>\n");
87: }
88: print ("\nEnter a number to move to the ");
89: print ("specified directory,\n");
90: if ($base > 0) {
91: print ("enter < to move up in the
list,\n");
92: }
93: if ($dirarray{$curdir.($base+10)} ne "") {
94: print ("enter > to move down in the
list,\n");
95: }
96: print ("enter d to display the files,\n");
97: print ("enter e to specify a new directory,\n");
98: print ("or enter q to quit entirely.\n");
99: print ("> ");
100: $command = <STDIN>;
101: $command =~ s/^\s+|\s+$//g;
102: if ($command eq "q") {
103: exit (0);
104: } elsif ($command eq ">") {
105: if ($dirarray{$curdir.($base+10)} ne "")
{
106: $base += 10;
107: }
108: } elsif ($command eq "<") {
109: $base -= 10 if $base > 0;
110: } elsif ($command eq "d") {
111: &display ($curdir);
112: } elsif ($command eq "e") {
113: # set the current directory to "" to
force
114: # the main program to prompt for a name
115: return ("");
116: } elsif ($command =~ /^\d+$/) {
117: $subdir =
$dirarray{$curdir.($command+$base)};
118: # if subdirectory is the parent
directory,
119: # remove .. and the last directory name
120: # from the path
121: if ($subdir =~ /\.\.$/) {
122: $subdir =~ s#(.*)/.*/..#$1#;
123: }
124: # if subdirectory is defined, it becomes
125: # the new current directory
126: if ($subdir ne "") {
127: if ($dirarray{$subdir} != 1) {
128: $subdir =
&followlink($subdir);
129: &readsubdirs ($subdir);
130: }
131: return ($subdir);
132: }
133: } else {
134: warn ("Invalid command $command\n");
135: }
136: }
137: }
138:
139:
140: # Display the files in a directory, three per line.
141:
142: sub display {
143: local ($dirname) = @_;
144: local ($file, $filecount, $printfile);
145: local (@filelist);
146:
147: if (!opendir(LOCALDIR, "$dirname")) {
148: warn ("Can't open $dirname\n");
149: return;
150: }
151: chdir ($dirname);
152: print ("\n\nFiles in directory $dirname:\n");
153: $filecount = 0;
154: while ($file = readdir (LOCALDIR)) {
155: next if (-d $file);
156: $filelist[$filecount++] = $file;
157: }
158: closedir ($dirname);
159: if ($filecount == 0) {
160: print ("\tDirectory contains no files.\n");
161: return;
162: }
163: @filelist = sort(@filelist);
164: $filecount = 0;
165: foreach $printfile (@filelist) {
166: if ($filecount == 30) {
167: print ("<Press return to continue>");
168: <STDIN>;
169: $filecount = 0;
170: }
171: if ($filecount % 3 == 0) {
172: print ("\t");
173: }
174: printf ("%-20s", $printfile);
175: $filecount += 1;
176: if ($filecount % 3 == 0) {
177: print ("\n");
178: }
179: }
180: }
181:
182:
183: # Check whether the directory name is really a symbolic link.
184: # If it is, find the real name and use it.
185:
186: sub followlink {
187: local ($dirname) = @_;
188:
189: if (-l $dirname) {
190: $dirname = readlink ($dirname);
191: }
192: $dirname; # return value
193: }

$ programR2_1
Enter directory to list:
/ag1/dave
Current directory is: /ag1/dave
Subdirectories:
0: /ag1/dave/..
1: /ag1/dave/.elm
2: /ag1/dave/.mosaic
3: /ag1/dave/.nn
4: /ag1/dave/Mail
5: /ag1/dave/News
6: /ag1/dave/bin
7: /ag1/dave/dave
8: /ag1/dave/ems
<more down>
Enter a number to move to the specified directory,
enter > to move down in the list,
enter d to display the files,
enter e to specify a new directory,
or enter q to quit entirely.
> d
Files in directory /ag1/dave:
.Xauthority .Xnormal .Xresources
.cshrc .login .newsrc
.xsession README calendar
doclist foo ideas
letter letter2 sched
Current directory is: /ag1/dave
Subdirectories:
0: /ag1/dave/..
1: /ag1/dave/.elm
2: /ag1/dave/.mosaic
3: /ag1/dave/.nn
4: /ag1/dave/Mail
5: /ag1/dave/News
6: /ag1/dave/bin
7: /ag1/dave/dave
8: /ag1/dave/ems
<more down>
Enter a number to move to the specified directory,
enter > to move down in the list,
enter d to display the files,
enter e to specify a new directory,
or enter q to quit entirely.
> 6
Current directory is: /ag1/dave/bin
Subdirectories:
0: /ag1/dave/bin/..
Enter a number to move to the specified directory,
enter d to display the files,
enter e to specify a new directory,
or enter q to quit entirely.
> q
$
The pr ogr am in List ing R2.1 consist s of f ive par t s:
G A ver y simpl e main pr ogr am
G The subr out ine &readsubdirs, which r eads and st or es t he subdir ect or ies of a
dir ect or y
G The subr out ine &menudir, which displ ays t he subdir ect or ies of t he cur r ent
dir ect or y, l ist s t he menu opt ions, and pr ocesses t he menu choices
G The subr out ine &display, which l ist s t he f il es in t he cur r ent dir ect or y
G The subr out ine &followlink, which checks whet her a dir ect or y name is r eal l y a
symbol ic l ink
The main pr ogr am is quit e simpl e: al l it does is pr ompt f or a dir ect or y name and cal l t he
subr out ines &readsubdirs and &menudir. (Many compl icat ed pr ogr ams ar e l ike t his: t he
main por t ion of t he pr ogr am just cal l s a f ew subr out ines.)
The subr out ine &readsubdirs is passed t he name of a dir ect or y t o examine. Line 33 opens
t he dir ect or y using opendir, and l ines 38-51 st or e t he subdir ect or ies in a (st andar d)
ar r ay named @dirarray. Af t er t his, l ine 56 sor t s t he ar r ay, and l ines 57-59 l oad t he
sor t ed el ement s int o an associat ive ar r ay named %dirarray. (Recal l t hat Per l pr ogr ams
can use t he same name f or an associat ive ar r ay and f or a st andar d ar r ay because t he
pr ogr am al ways can t el l t hem apar t .)
The subscr ipt s f or t he associat ive ar r ay use a simpl e scheme:
G When a dir ect or y is r ead, l ine 61 def ines an associat ive ar r ay el ement whose
subscr ipt is t he dir ect or y name, and set s it s val ue t o 1. (For exampl e, if t he
dir ect or y /ag1/dave is being r ead, t he ar r ay el ement $dirarray{"/ag1/dave"} is
set t o 1.) This is t he way t he pr ogr am indicat es t hat a par t icul ar dir ect or y has
been r ead.
G Line 49 st or es t he subdir ect or y names in associat ive ar r ay el ement s whose
subscr ipt s consist of t he name of t he dir ect or y joined wit h a unique int eger . For
exampl e, if t he f ir st subdir ect or y of /ag1/dave is named /ag1/dave/foo, t he
associat ive ar r ay el ement $dirarray{"/ag1/dave0"} is assigned t he val ue
ag1/dave/foo. Simil ar l y, t he second subdir ect or y of /ag1/dave has it s name st or ed
in $dirarray{"/ag1/dave1"}, and so on.
Line 60 int r oduces a f unct ion you have not yet seen: undef. This f unct ion basical l y just
t hr ows away t he cont ent s of @dirarray because t he pr ogr am no l onger needs t hem. (For
mor e det ail s on undef, see Day 14, "Scal ar -Conver sion and List -Manipul at ion
Funct ions.")
The subr out ine &menudir uses t his associat ive ar r ay t o displ ay t he subdir ect or ies of t he
cur r ent dir ect or y. Line 74 pr int s t he name of t he cur r ent dir ect or y, and l ines 79-84
pr int t he names of t he subdir ect or ies of t he dir ect or y. If t her e ar e mor e t han t en
subdir ect or ies, &menudir displ ays onl y a "window" of t en subdir ect or ies, and it pr int s
<more down> or <more up> t o show t hat t her e ar e mor e subdir ect or ies avail abl e. Each
subdir ect or y is pr int ed wit h a cor r esponding number t hat you can use t o sel ect t he
subdir ect or y and set it t o be t he cur r ent dir ect or y.
Af t er &menudir pr int s t he subdir ect or y names, l ines 88-99 pr int a l ist of t he avail abl e
menu commands. These commands ar e
G d, which displ ays t he f il es st or ed in t he cur r ent dir ect or y
G e, which enabl es you t o ent er t he name of a dir ect or y t o displ ay
G q, which enabl es you t o quit t he pr ogr am
G a number bet ween 0 and 9, which changes t he cur r ent dir ect or y t o t he specif ied
subdir ect or y
G <, which moves up in t he l ist of subdir ect or ies (if possibl e)
G >, which moves down in t he l ist of subdir ect or ies (again, if possibl e)
Line 100 r eads a command f r om t he st andar d input f il e, and l ine 101 get s r id of any
l eading or t r ail ing whit e space. Lines 102-135 det er mine which command has been
ent er ed.
If q has been ent er ed, l ine 103 cal l s exit, which t er minat es t he pr ogr am.
If eit her > or < has been ent er ed, l ines 104-109 move up or down in t he dir ect or y l ist .
They do t his by modif ying t he val ue of a var iabl e named $base, which det er mines how
many subdir ect or y names t o skip bef or e l ines 79-84 st ar t pr int ing.
If d has been ent er ed, l ine 111 cal l s &display, which pr int s t he l ist of f il es.
If e has been ent er ed, l ine 115 exit s t he subr out ine wit h a r et ur n val ue of t he nul l
st r ing. This f or ces t he main pr ogr am t o execut e l ines 7-13 again, which pr ompt you f or a
dir ect or y name.
If a number has been ent er ed, l ine 117 t akes t he number , joins it t o t he cur r ent
dir ect or y name, and uses t he r esul t ing st r ing as t he subscr ipt int o t he associat ive ar r ay
%dirarray. (For exampl e, if t he cur r ent dir ect or y is /ag1/dave and t he number 6 has been
ent er ed, l ine 117 accesses t he associat ive ar r ay el ement %dirarray{"/ag1/dave6"}). This
is one of t he ar r ay el ement s t hat l ine 49 of &readsubdirs cr eat ed; it s val ue is t he name
of a subdir ect or y.
Line 127 t akes t he name of t his subdir ect or y and uses it , in t ur n, as an associat ive ar r ay
subscr ipt . (For exampl e, if t he val ue of %dirarray{"/ag1/dave6"} is "/ag1/dave/bin", l ine
127 checks t he associat ive ar r ay el ement %dirarray{"/ag1/dave/bin"}.) If t he val ue of
t his el ement is 1, &readsubdirs has al r eady r ead t his dir ect or y and st or ed it s
subdir ect or y names in t he associat ive ar r ay, so t he pr ogr am does not need t o do it again.
If t his el ement is not def ined, t he pr ogr am cal l s &readsubdirs, which r eads and st or es
t he names of t he subdir ect or ies of t his dir ect or y.
The subr out ine &display pr int s t he names of t he f il es st or ed in a par t icul ar dir ect or y.
To save space, it pr int s t he f il enames t hr ee per l ine. &display pr int s onl y t en l ines at a
t ime. If t her e ar e mor e t han t en l ines (in ot her wor ds, 30 f il enames), l ine 168 pauses and
wait s f or you t o pr ess Ent er bef or e cont inuing t o pr int . This gives you t ime t o r ead al l
of t he cur r ent l y displ ayed names.
The f inal subr out ine is &followlink, which al ways is cal l ed immediat el y bef or e t he
subr out ine &readsubdirs is cal l ed. It s job is t o check whet her a dir ect or y name is r eal l y
a symbol ic l ink. If it is, l ine 190 cal l s readlink, which r et r ieves t he r eal dir ect or y name.
This dir ect or y name is r et ur ned t o t he cal l ing subr out ine or main pr ogr am and t hen is
passed t o &readsubdirs.
As you can see, you now know enough about Per l t o wr it e pr ogr ams t hat manipul at e t he
f il e syst em and use compl ex dat a st r uct ur es. In Week 3, you'l l l ear n about t he
r emainder of Per l 's buil t -in f unct ions and t he r est of t he f eat ur es of Per l .

Week
3
Week 3 at a Glance
CONTENTS
G Wher e You'r e Going
You've f inished your second week of l ear ning how t o pr ogr am wit h Per l . By now, you
know enough about Per l t o consider your sel f an accompl ished Per l pr ogr ammer .
Where You're Going
The t hir d week cover s t he r est of t he Per l l ibr ar y f unct ions, descr ibes some of t he mor e
esot er ic concept s of t he l anguage, and int r oduces some f eat ur es unique t o ver sion 5 of
Per l . Her e's a summar y of what you'l l l ear n.
Day 15, "Syst em Funct ions," descr ibes t he f unct ions t hat wor k wit h l ist s and ar r ay
var iabl es.
Day 16, "Command-Line Opt ions," descr ibes t he opt ions you can suppl y wit h Per l t o
cont r ol how your pr ogr am r uns.
Day 17, "Syst em Var iabl es," descr ibes t he buil t -in var iabl es t hat ar e incl uded
aut omat ical l y as par t of ever y Per l pr ogr am.
Day 18, "Ref er ences in Per l 5," descr ibes t he use of Per l r ef er ences and t he concept of
point er s.
Day 19, "Object -Or ient ed Pr ogr amming in Per l ," cover s how t o const r uct object s in Per l
and how t o use OOP f eat ur es of f er ed by Per l .
Day 20, "Miscel l aneous Feat ur es of Per l ," cover s some of t he mor e exot ic or obscur e
f eat ur es of t he l anguage.
Final l y, Day 21, "The Per l Debugger ," shows you how t o use t he Per l debugger t o
quickl y discover er r or s.
By t he end of t he t hir d week, you'l l know al l t he f eat ur es and capabil it ies of Per l .

Chapter 15
System Functions
CONTENTS
G Syst em Libr ar y Emul at ion Funct ions
H The getgrent Funct ion
H The setgrent and endgrent Funct ions
H The getgrnam Funct ion
H The getgrid Funct ion
H The getnetent Funct ion
H The getnetbyaddr Funct ion
H The getnetbyname Funct ion
H The setnetent and endnetent Funct ions
H The gethostbyaddr Funct ion
H The gethostbyname Funct ion
H The gethostent, sethostent, and endhostent Funct ions
H The getlogin Funct ion
H The getpgrp and setpgrp Funct ions
H The getppid Funct ion
H The getpwnam Funct ion
H The getpwuid Funct ion
H The getpwent Funct ion
H The setpwent and endpwent Funct ions
H The getpriority and setpriority Funct ions
H The getprotoent Funct ion
H The getprotobyname and getprotobynumber Funct ions
H The setprotoent and endprotoent Funct ions
H The getservent Funct ion
H The getservbyname and getservbyport Funct ions
H The setservent and endservent Funct ions
H The chroot Funct ion
H The ioctl Funct ion
H The alarm Funct ion
H Cal l ing t he Syst em select Funct ion
H The dump Funct ion
G Socket -Manipul at ion Funct ions
H The socket Funct ion
H The bind Funct ion
H The listen Funct ion
H The accept Funct ion
H The connect Funct ion
H The shutdown Funct ion
H The socketpair Funct ion
H The getsockopt and setsockopt Funct ions
H The getsockname and getpeername Funct ions
G The UNIX Syst em V IPC Funct ions
H IPC Funct ions and t he require St at ement
H The msgget Funct ion
H The msgsnd Funct ion
H The msgrcv Funct ion
H The msgctl Funct ion
H The shmget Funct ion
H The shmwrite Funct ion
H The shmread Funct ion
H The shmctl Funct ion
H The semget Funct ion
H The semop Funct ion
H The semctl Funct ion
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson descr ibes t he buil t -in Per l f unct ions t hat per f or m var ious syst em-l evel
oper at ions. These f unct ions ar e divided int o t hr ee gr oups:
G The f unct ions t hat emul at e syst em l ibr ar y f unct ions
G The f unct ions t hat wor k wit h Ber kel ey UNIX socket s
G The f unct ions t hat per f or m UNIX Syst em V IPC oper at ions
Many of t he f unct ions descr ibed in t oday's l esson use
f eat ur es of t he UNIX oper at ing syst em. If you ar e using
Per l on a machine t hat is not r unning UNIX, some of
t hese f unct ions might not be def ined or might behave
dif f er ent l y.
Check t he document at ion suppl ied wit h your ver sion of
Per l f or det ail s on which f unct ions ar e suppor t ed or
emul at ed on your machine
System Library Emulation Functions
Sever al buil t -in Per l f unct ions enabl e you t o execut e var ious syst em l ibr ar y cal l s f r om
wit hin your Per l pr ogr am. Each one cor r esponds t o a UNIX syst em l ibr ar y f unct ion.
The f ol l owing sect ions br ief l y descr ibe t hese syst em l ibr ar y f unct ions. For mor e
inf or mat ion on a par t icul ar syst em l ibr ar y f unct ion, r ef er t o t he on-l ine manual page
f or t hat f unct ion. For exampl e, t o f ind out mor e about t he getnetent f unct ion, r ef er t o
your UNIX syst em's getnetent manual page.
The getgrent Function
In t he UNIX envir onment , each user bel ongs t o a user gr oup. Being in a user gr oup
enabl es you t o def ine f il es t hat onl y cer t ain user s-t he peopl e in your user gr oup-can
r ead f r om or wr it e t o.
On UNIX syst ems, t he f il e /etc/group l ist s t he user gr oups def ined f or your machine.
Each ent r y in t he user gr oup f il e consist s of f our component s:
G The user gr oup name
G The user gr oup passwor d, if one exist s
G The gr oup ID, which is a unique int eger t hat t he syst em uses t o ident if y t his
par t icul ar user gr oup
G A l ist of t he user IDs t hat bel ong t o t his gr oup
The Per l f unct ion getgrent enabl es you t o r et r ieve an it em f r om t he user gr oup f il e.
The synt ax f or t he getgrent f unct ion is
(gname, gpasswd, gid, gmembers) = getgrent;
This f unct ion r et ur ns a f our -el ement l ist consist ing of t he f our component s of a gr oup
l ine ent r y, as just descr ibed. gname cont ains t he user gr oup name, gpasswd cont ains t he
user gr oup passwor d, gid is t he gr oup ID, and gmembers is a char act er st r ing consist ing of
a l ist of t he user IDs bel onging t o t his gr oup. The user IDs l ist ed in gmembers ar e
separ at ed by spaces.
Each cal l t o getgrent r et ur ns anot her l ine f r om t he /etc/group f il e. Ther ef or e, you
can put getgrent inside a while l oop.
while (($gname, $gpasswd, $gid, $gmembers) = getgrent) {
# do stuff here
}
When t he /etc/group f il e is exhaust ed, getgrent r et ur ns t he empt y l ist .
List ing 15.1 is an exampl e of a pr ogr am t hat uses getgrent t o l ist al l t he user IDs
associat ed wit h each gr oup on your syst em.

List ing 15.1. A pr ogr am t hat uses getgrent.
1: #!/usr/local/bin/perl
2:
3: while (($gname, $gpasswd, $gid, $gmembers) = getgrent) {
4: $garray{$gname} = $gmembers;
5: }
6: foreach $gname (sort keys (%garray)) {
7: print ("Userids belonging to group $gname:\n");
8: $gmembers = $garray{$gname};
9: $userids = 0;
10: while (1) {
11: last if ($gmembers eq "");
12: ($userid, $gmembers) =
13: split (/\s+/, $gmembers, 2);
14: printf (" %-20s", $userid);
15: $userids++;
16: if ($userids % 3 == 0) {
17: print ("\n");
18: }
19: }
20: if ($userids % 3 != 0) {
21: print ("\n");
22: }
23: }

$ program15_1
Userids belonging to group adm:
adm daemon
Userids belonging to group develop:
dave jqpublic kilroy
mpython ralomar xyzzy
Userids belonging to group root:
root
$
Line 3 of t his pr ogr am cal l s getgrent. This f unct ion r et ur ns a f our -el ement
l ist whose el ement s ar e t he component s of a gr oup ent r y st or ed in t he /etc/group f il e. If
/etc/group is exhaust ed, getgrent r et ur ns t he empt y l ist .
Line 4 t akes t he l ist of gr oup member s in $gmembers and st or es it in an associat ive ar r ay
named %garray. The subscr ipt f or t his ar r ay el ement is t he name of t he gr oup, which is
cont ained in $gname.
Lines 6-23 pr int t he l ist of user IDs f or each gr oup. The l oop it er at es once f or each gr oup
name, and t he cal l t o sort in l ine 6 ensur es t hat t he gr oup names appear in al phabet ical
or der . Fir st , l ine 7 pr int s t he name of t he gr oup. Then, l ine 8 r et r ieves t he l ist of user
IDs in t he gr oup by accessing t he associat ive ar r ay %garray. This l ist is st or ed, once
again, in $gmembers.
Lines 12 and 13 cal l split t o ext r act t he next user ID f r om t he l ist . split br eaks t he
st r ing int o t wo par t s when it sees t he f ir st whit e space. The f ir st par t , t he subst r ing
bef or e t he f ir st space, cont ains one user ID and is assigned t o $userid; t he r est of t he
st r ing is r eassigned t o $gmembers.
The r est of t he l oop pr int s t he ext r act ed user ID. User IDs ar e pr int ed t hr ee per l ine t o
save space.
The setgrent and endgrent Functions
The setgrent f unct ion af f ect s t he behavior of getgrent: it t el l s t he Per l int er pr et er t o
r ewind t he /etc/group f il e. Af t er setgrent is cal l ed, t he next cal l t o getgrent
r et r ieves t he f ir st el ement of t he /etc/group f il e.
The endgrent f unct ion t el l s t he Per l int er pr et er t hat you no l onger need t o access t he
/etc/group f il e. It f r ees t he memor y used t o st or e gr oup inf or mat ion.
Neit her setgrent nor endgrent accept s any ar gument s or r et ur ns any val ues.
The synt ax f or t hese f unct ions is
setgrent();
endgrent();
The getgrnam Function
The getgrnam f unct ion enabl es you t o r et r ieve t he gr oup f il e ent r y cor r esponding t o a
par t icul ar gr oup name.
The synt ax f or t he getgrnam f unct ion is
(gname, gpasswd, gid, gmembers) = getgrnam (name);
Her e, name is t he gr oup name t o sear ch f or . getgrnam r et ur ns t he same f our -el ement l ist
t hat getgrent r et ur ns: gname is t he gr oup name (which is t he same as name), gpasswd is t he
gr oup passwor d, gid is t he gr oup ID, and gmembers is t he l ist of user IDs in t he gr oup. If
getgrnam does not f ind a gr oup ent r y mat ching name, it r et ur ns t he empt y l ist .
List ing 15.2 is a modif icat ion of List ing 15.1. It asks you f or a gr oup name and t hen pr int s
t he user IDs in t hat gr oup.

List ing 15.2. A pr ogr am t hat uses getgrnam.
1: #!/usr/local/bin/perl
2:
3: print ("Enter the group name to list:\n");
4: $name = <STDIN>;
5: chop ($name);
6: if (!(($gname, $gpasswd, $gid, $gmembers) = getgrnam ($name))) {
7: die ("Group $name does not exist.\n");
8: }
9: $userids = 0;
10: while (1) {
11: last if ($gmembers eq "");
12: ($userid, $gmembers) = split (/\s+/, $gmembers, 2);
13: printf (" %-20s", $userid);
14: $userids++;
15: if ($userids % 3 == 0) {
16: print ("\n");
17: }
18: }
19: if ($userids % 3 != 0) {
20: print ("\n");
21: }

$ program15_2
Enter the group name to list:
develop
dave jqpublic kilroy
mpython ralomar xyzzy
$
Line 6 t akes t he gr oup name st or ed in $name and passes it t o getgrnam. If a
gr oup cor r esponding t o t hat name exist s, getgrnam r et ur ns t he name, passwor d, gr oup ID,
and member s. If no such gr oup exist s, getgrnam r et ur ns t he empt y l ist , t he condit ional
expr ession in l ine 6 f ail s, and l ine 7 cal l s die t o t er minat e t he pr ogr am.
The r est of t he pr ogr am is t aken ver bat im f r om List ing 15.1: t he while l oop in l ines 10-18
ext r act s a user ID f r om t he l ist of user IDs in $gmembers and pr int s it , cont inuing unt il
t he l ist is exhaust ed.
The getgrid Function
The getgrid f unct ion is simil ar t o getgrnam, except t hat it r et r ieves t he gr oup f il e ent r y
cor r esponding t o a given gr oup ID.
The synt ax f or t he getgrid f unct ion is
(gname, gpasswd, gid, gmembers) = getgrid (id);
Like getgrname, getgrid r et ur ns a f our -el ement l ist consist ing of t he gr oup name,
passwor d, ID, and member l ist . If t he gr oup specif ied by id does not exist , getgrid r et ur ns
t he empt y l ist .
This f unct ion of t en is used t o r et r ieve t he associat ed gr oup name:
($gname) = getgrid (11);
This l ine r et r ieves t he gr oup name associat ed wit h gr oup ID 11. (The ot her el ement s of
t he l ist ar e t hr own away.)
You must pl ace par ent heses ar ound $gname t o denot e
t hat getgrid is assigning t o a l ist . The st at ement
$gname = getgrid (11);
assigns t he l ist r et ur ned by getgrid t o t he scal ar
var iabl e $gname. In Per l , assigning a l ist t o a scal ar
var iabl e act ual l y assigns t he l engt h of t he l ist t o t he
var iabl e, so t his st at ement assigns 4 t o $gname because
t her e ar e f our el ement s in t he l ist r et ur ned by getgrid
The getnetent Function
The getnetent f unct ion enabl es you t o st ep t hr ough t he f il e /etc/networks, which l ist s
t he names and addr esses of t he net wor ks your machine is on.
The synt ax f or t he getnetent f unct ion is
(name, altnames, addrtype, net) = getnetent();
name is t he name of a net wor k. altnames is a l ist of al t er nat ive names f or t he net wor k;
t his l ist of names is r et ur ned as a char act er st r ing, wit h spaces separ at ing t he individual
names. addrtype is t he addr ess t ype; at pr esent , t his is al ways what ever val ue is def ined
f or t he syst em const ant AF_INET, which indicat es t hat t he addr ess is an Int er net addr ess.
NOTE
To get t he val ue of AF_INET on your machine, r ef er t o
t he header f il e
/usr/include/netdb.h or /usr/include/bsd/netdb.h, and
l ook f or a st at ement simil ar t o t he f ol l owing:
#define AF_INET 2
The number t hat appear s af t er AF_INET is t he one you
want
net is t he Int er net addr ess of t his net wor k. This addr ess is r epr esent ed as a st r ing of
f our byt es, which can be unpacked int o Per l scal ar val ues using t he unpack f unct ion.
List ing 15.3 shows how you can use getnetent t o l ist t he machine names and addr esses at
your sit e.

List ing 15.3. A pr ogr am t hat uses getnetent.
1: #!/usr/local/bin/perl
2:
3: print ("Networks this machine is connected to:\n");
4: while (($name, $altnames, $addrtype, $rawaddr) = getnetent()) {
5: @addrbytes = unpack ("C4", $rawaddr);
6: $address = join (".", @addrbytes);
7: print ("$name, at address $address\n");
8: }

$ program15_3
Networks this machine is connected to:
silver, at address 192.75.236.168
$
Line 4 cal l s getnetent, which r eads f r om t he f il e /etc/networks. If t he f il e
has been exhaust ed, getnetent r et ur ns t he empt y l ist , and t he while l oop t er minat es. If
/etc/networks st il l cont ains an unr ead ent r y, getnetent r et r ieves it and assigns it s
component s t o $name, $altnames, $addrtype, and $rawaddr.
$rawaddr cont ains t he Int er net addr ess f or a par t icul ar net wor k. This addr ess is st or ed
as a f our -byt e int eger ; each byt e cont ains one component of t he addr ess. (This met hod
wor ks because each number in an Int er net addr ess has a maximum val ue of 255, which is
t he l ar gest val ue t hat can f it in a byt e.) Line 5 conver t s t his f our -byt e int eger int o a
l ist of int eger s by cal l ing unpack, and it st or es t he l ist in @addrbytes.
Line 6 cal l s join t o conver t t he l ist of int eger s int o a char act er st r ing t hat cont ains
t he r eadabl e addr ess. Line 7 t hen pr int s t he net wor k name and t he r eadabl e addr ess of
t he net wor k.
The getnetbyaddr Function
The getnetbyaddr f unct ion enabl esyou t o r et r ieve t he l ine of input f r om /etc/networks
t hat mat ches a par t icul ar net wor k number .
The synt ax f or t he getnetbyaddr f unct ion is
(name, altnames, addrtype, addr) = getnetbyaddr (inaddr, inaddrtype);
Her e, inaddr is t he net wor k number or addr ess f or which you want t o sear ch. This
addr ess must be a packed f our -byt e int eger whose f our byt es ar e t he f our component s of
t he addr ess. (An exampl e of a net wor k addr ess is 192.75.236.168, which is t he machine
on which I wor k.) To buil d a packed addr ess, use t he pack command:
@addrbytes = (192, 75, 236, 168);
$packedaddr = pack ("C4", @addrbytes);
The packed addr ess in $packedaddr can now be passed t o getnetbyaddr.
inaddrtype is t he addr ess t ype, which is al ways AF_INET (whose val ue is l ocat ed in t he
f il e
/usr/include/netdb.h or /usr/include/bsd/netdb.h).
The getnetbyaddr f unct ion r et ur ns t he same f our -el ement l ist as getnetent: t he name of
t he net wor k, t he l ist of al t er nat ive names, t he addr ess t ype, and t he packed addr ess.
The getnetbyname Function
The getnetbyname f unct ion is simil ar t o getnetbyaddr, except t hat it enabl es you t o
sear ch in t he /etc/networks f il e f or a net wor k of a par t icul ar name.
The synt ax f or t he getnetbyname f unct ion is
(name, altnames, addrtype, net) = getnetbyname (inname);
Her e, inname is t he machine name t o sear ch f or . Like getnetbyaddr and getnetent,
getnetbyname r et ur ns a f our -el ement l ist consist ing of t he net wor k name, al t er nat ive
name l ist , addr ess t ype, and packed addr ess.
NOTE
You can pass getnetbyname eit her t he pr incipal net wor k
name or one of it s al iases
The setnetent and endnetent Functions
The setnetent f unct ion r ewinds t he /etc/networks f il e; af t er setnetent has been
cal l ed, a cal l t o getnetent r et ur ns t he f ir st ent r y in t he /etc/networks f il e.
The synt ax f or t he setnetent f unct ion is
setnetent (keepopen);
keepopen is a scal ar val ue. If keepopen is not zer o, t he /etc/networks f il e is not cl osed
af t er getnetbyname or getnetbyaddr is cal l ed; t her ef or e, you can ef f icient l y cal l t hese
f unct ions r epeat edl y. If keepopen is zer o, t he f il e is cl osed.
The endnetent f unct ion t el l s t he Per l int er pr et er t hat your pr ogr am is f inished wit h
t he /etc/networks f il e. It cl oses t he f il e and f r ees any memor y used by your pr ogr am t o
st or e r el at ed inf or mat ion.
The synt ax f or t he endnetent f unct ion is
endnetent;
It accept s no ar gument s and r et ur ns no val ues.
The gethostbyaddr Function
The gethostbyaddr f unct ion sear ches t he f il e /etc/hosts (or t he equival ent name
ser ver ) f or t he host name cor r esponding t o a par t icul ar Int er net addr ess.
The synt ax f or t he gethostbyaddr f unct ion is
(name, altnames, addrtype, len, addrs) = gethostbyaddr (inaddr,
inaddrtype);
This f unct ion r equir es t wo ar gument s. The f ir st , inaddr, is t he Int er net addr ess t o
sear ch f or , st or ed in packed f our -byt e f or mat (ident ical t o t hat used by getnetbyaddr).
The second ar gument , inaddrtype, is t he addr ess t ype; at pr esent , onl y Int er net addr ess
t ypes ar e under st ood, and inaddrtype is al ways AF_INET. (The val ue of AF_INET can be
f ound in /usr/include/netdb.h or /usr/include/sys/netdb.h.)
gethostbyaddr r et ur ns a f ive-el ement l ist . The f ir st el ement , name, is t he host name
cor r esponding t o t he Int er net addr ess specif ied by inaddr. altnames is t he l ist of al iases
or al t er nat ive names by which t he host can be r ef er r ed. addrtype, l ike inaddrtype, is
al ways AF_INET.
addrs is a l ist of addr esses (main addr ess and al t er nat ives) cor r esponding t o t he host
node named name. Each addr ess is st or ed as a f our -byt e int eger . len is t he l engt h of t he
addrs f iel d; t his l engt h is al ways f our mul t ipl ied by t he number of addr esses r et ur ned in
addrs.
List ing 15.4 shows how you can use gethostbyaddr t o r et r ieve t he Int er net addr ess
cor r esponding t o a par t icul ar machine name.

List ing 15.4. A pr ogr am t hat uses gethostbyaddr.
1: #!/usr/local/bin/perl
2:
3: print ("Enter an Internet address:\n");
4: $machine = <STDIN>;
5: $machine =~ s/^\s+|\s+$//g;
6: @bytes = split (/\./, $machine);
7: $packaddr = pack ("C4", @bytes);
8: if (!(($name, $altnames, $addrtype, $len, @addrlist) =
9: gethostbyaddr ($packaddr, 2))) {
10: die ("Address $machine not found.\n");
11: }
12: print ("Principal name: $name\n");
13: if ($altnames ne "") {
14: print ("Alternative names:\n");
15: @altlist = split (/\s+/, $altnames);
16: for ($i = 0; $i < @altlist; $i++) {
17: print ("\t$altlist[$i]\n");
18: }
19: }

$ program15_4
Enter an Internet address:
128.174.5.59
Principal name: ux1.cso.uiuc.edu
$
The pr ogr am st ar t s by pr ompt ing you f or an Int er net addr ess. (In t his exampl e,
t he Int er net addr ess specif ied is 128.174.5.59, which is t he l ocat ion of a popul ar publ ic
access Gopher sit e.) Lines 5-7 t hen conver t t he addr ess int o a f our -byt e packed int eger ,
which is st or ed in $packaddr.
Lines 8 and 9 cal l gethostbyaddr. This f unct ion sear ches t he /etc/hosts f il e f or an
ent r y mat ching t he specif ied machine name. If t he ent r y is not f ound, t he condit ional
expr ession becomes f al se, and l ine 10 cal l s die t o t er minat e t he pr ogr am.
NOTE
Line 9 uses t he val ue 2 as t he addr ess t ype t o pass t o
gethostbyaddr. If your machine def ines a dif f er ent val ue
of AF_INET, as def ined in t he f il es /usr/include/netdb.h
or /usr/include/bsd/netdb.h, r epl ace 2 wit h t hat val ue
If t he ent r y is f ound, l ine 12 pr int s t he pr incipal machine name, which was r et ur ned by
gethostbyaddr and is now st or ed in t he scal ar var iabl e $name. Line 13 t hen checks
whet her t he r et ur ned ent r y l ist s any al t er nat ive machine names cor r esponding t o t his
Int er net addr ess.
If al t er nat ive machine names exist , l ines 14-18 spl it t he al t er nat ive name l ist int o
individual names and pr int each name on a separ at e l ine.
NOTE
gethostbyaddr and t he ot her f unct ions t hat access
/etc/hosts expect t he f ol l owing f or mat f or a host
ent r y:
address mainname altname1 altname2 ...
Her e, address is an Int er net addr ess; mainname is t he
name associat ed wit h t he addr ess; and altname1,
altname2, and so on ar e t he (opt ional ) al t er nat ive names
f or t he host .
If your /etc/hosts f il e is in a dif f er ent f or mat ,
gethostbyaddr might not wor k pr oper l y
The gethostbyname Function
The gethostbyname f unct ion is simil ar t o gethostbyaddr, except t hat it sear ches f or an
/etc/hosts ent r y t hat mat ches a specif ied machine name or Int er net sit e name.
The synt ax f or t he gethostbyname f unct ion is
(name, altnames, addrtype, len, addrs) = gethostbyname (inname);
Her e, inname is t he machine name or Int er net sit e name t o sear ch f or . gethostbyname, l ike
gethostbyaddr, r et ur ns a f ive-el ement l ist consist ing of t he machine name, a char act er
st r ing cont aining a l ist of al t er nat ive names, t he addr ess t ype, t he l engt h of t he
addr ess l ist , and t he addr ess l ist .
List ing 15.5 is a simpl e pr ogr am t hat sear ches f or an Int er net addr ess when given t he
name of a sit e.

List ing 15.5. A pr ogr am t hat uses gethostbyname.
1: #!/usr/local/bin/perl
2:
3: print ("Enter a machine name or Internet site name:\n");
4: $machine = <STDIN>;
5: $machine =~ s/^\s+|\s+$//g;
6: if (!(($name, $altnames, $addrtype, $len, @addrlist) =
7: gethostbyname ($machine))) {
8: die ("Machine name $machine not found.\n");
9: }
10: print ("Equivalent addresses:\n");
11: for ($i = 0; $i < @addrlist; $i++) {
12: @addrbytes = unpack("C4", $addrlist[$i]);
13: $realaddr = join (".", @addrbytes);
14: print ("\t$realaddr\n");
15: }

$ program15_5
Enter a machine name or Internet site name:
ux1.cso.uiuc.edu
Equivalent addresses:
128.174.5.59
$
This pr ogr am pr ompt s f or a machine name and t hen r emoves t he l eading and
t r ail ing whit e space f r om it . Af t er t he machine name has been pr epar ed, l ines 6 and 7
cal l gethostbyname, which sear ches f or t he /etc/hosts ent r y mat ching t he specif ied
machine name. If gethostbyname does not f ind t he ent r y, it r et ur ns t he nul l st r ing, t he
condit ional expr ession becomes f al se, and l ine 8 cal l s die t o t er minat e t he pr ogr am.
If gethostbyname f inds t he ent r y, t he l oop in l ines 11-15 examines t he l ist of addr esses in
@addrlist, assembl ing and pr int ing one addr ess at a t ime. Line 12 assembl es an addr ess by
unpacking one el ement of @addrlist and st or ing t he individual byt es in @addrbytes. Line
13 joins t he byt es int o a char act er st r ing, pl acing a per iod bet ween each pair of byt es.
The r esul t ing st r ing is a r eadabl e Int er net addr ess, which l ine 14 pr int s.
NOTE
The machine name passed t o gethostbyname can be eit her
t he pr incipal machine name (as specif ied in t he f ir st
el ement of t he r et ur ned l ist ) or one of t he al t er nat ive
names (al iases)
The gethostent, sethostent, and endhostent Functions
The gethostent f unct ion enabl es you t o r ead each it em of t he /etc/hosts f il e in t ur n.
The synt ax f or t he gethostent f unct ion is
(name, altnames, addrtype, len, addrs) = gethostent();
The f ir st cal l t o gethostent r et ur ns t he f ir st el ement in t he /etc/hosts f il e;
subsequent cal l s t o gethostent r et ur n successive el ement s. Each cal l t o gethostent
r et ur ns a f ive-el ement l ist ident ical t o t he l ist r et ur ned by gethostbyaddr or
gethostbyname. This l ist consist s of a machine name, a char act er st r ing l ist ing t he
al t er nat ive machine names, t he addr ess t ype (al ways AF_INET), t he l engt h of t he addr ess
f iel d, and t he addr ess f iel d it sel f .
Many machines simul at e an /etc/hosts f il e using a name
ser ver . When a pr ogr am t hat is r unning on a machine
using a name ser ver at t empt s t o access /etc/hosts, t he
ser ver quer ies var ious Int er net sit es f or machine names,
addr esses, and ot her inf or mat ion.
If a Per l pr ogr am r unning on such a machine cal l s
gethostent r epeat edl y, t he pr ogr am might t r y t o access
many Int er net sit es t o obt ain machine inf or mat ion. This
t akes a l ot of t ime and is a st r ain on Int er net r esour ces;
do not do it unl ess you absol ut el y must , and do it dur ing
of f -peak hour s if possibl e
The sethostent f unct ion r ewinds t he /etc/hosts f il e, which means t hat t he next cal l t o
gethostent wil l r et ur n t he f ir st ent r y in t he f il e.
The synt ax f or t he sethostent f unct ion is
sethostent (keepopen);
keepopen is a scal ar val ue. If keepopen is nonzer o, t he Per l pr ogr am keeps /etc/hosts
inf or mat ion in memor y, which ensur es t hat subsequent cal l s t o gethostent ar e
per f or med as ef f icient l y as possibl e. If keepopen is zer o, no inf or mat ion is r et ained af t er
sethostent f inishes execut ing.
The endhostent f unct ion cl oses t he /etc/hosts f il e and indicat es t hat t he pr ogr am is t o
f r ee any int er nal memor y r et aining host -r el at ed inf or mat ion.
The endhostent f unct ion expect s no ar gument s and r et ur ns no val ues:
endhostent();
The getlogin Function
The getlogin f unct ion r et ur ns t he user ID under which you ar e l ogged in. The user ID is
r et r ieved f r om t he f il e /etc/utmp.
The synt ax f or t he getlogin f unct ion is
logname = getlogin();
logname is t he r et ur ned user ID.
The f ol l owing is a simpl e exampl e using getlogin:
$logname = getlogin();
if ($logname == "dave") {
print ("Hello, dave! How are you?\n");
}
The getpgrp and setpgrp Functions
In t he UNIX envir onment , pr ocesses ar e or ganized int o col l ect ions of pr ocesses known as
pr ocess gr oups. Each pr ocess gr oup is ident if ied by a unique int eger known as a pr ocess
gr oup ID.
The getpgrp f unct ion r et r ieves t he pr ocess gr oup ID f or a par t icul ar pr ocess.
The synt ax of t he getpgrp f unct ion is
pgroup = getpgrp (pid);
pid is t he pr ocess ID whose gr oup you want t o r et r ieve, and pgroup is t he r et ur ned
pr ocess gr oup ID, which is a scal ar val ue.
If pid is not specif ied or is zer o, getpgrp assumes t hat you want t he pr ocess gr oup ID f or
t he cur r ent pr ocess (t he pr ogr am you ar e r unning).
List ing 15.6 is an exampl e of a pr ogr am t hat r et r ieves it s own pr ocess gr oup ID.

List ing 15.6. A pr ogr am t hat uses getpgrp.
1: #!/usr/local/bin/perl
2:
3: $pgroup = getpgrp (0);
4: print ("The process group for this program is $pgroup.\n");

$ program15_6
The process group for this program is 3313.
$
Line 3 cal l s getpgrp wit h t he ar gument 0, which indicat es t he cur r ent pr ocess
(t he cur r ent pr ogr am). The pr ocess gr oup ID f or t his pr ocess is r et ur ned in $pgroup and
t hen pr int ed.
The setpgrp f unct ion enabl es you t o set t he pr ocess gr oup ID f or a pr ocess.
The synt ax of t he setpgrp f unct ion is
setpgrp (pid, groupid);
pid is t he ID of t he pr ocess whose gr oup you want t o change, and groupid is t he pr ocess
gr oup ID you want your pr ocess t o be par t of . (This gr oup ID is usual l y r et ur ned by a
cal l t o getpgrp.)
Not al l machines suppor t setpgrp, and some machines
impose l imit at ions on how you can use it . If your pr ogr am
uses setpgrp, you shoul d cal l getpgrp immediat el y
af t er war d t o ensur e t hat t he pr ocess gr oup ID has been
set pr oper l y
The getppid Function
On UNIX machines, as you have seen, ever y r unning pr ogr am or ot her execut ing pr ocess
has it s own unique pr ocess ID. Each pr ogr am and pr ocess al so is associat ed wit h a par ent
pr ocess, which is t he pr ocess t hat st ar t ed it . For exampl e, when you execut e a command
t hat st ar t s a Per l pr ogr am, t he par ent pr ocess of t he Per l pr ogr am is t he shel l pr ogr am
f r om which you ent er ed t he command.
To r et r ieve t he pr ocess ID f or t he par ent pr ocess f or your pr ogr am, cal l t he f unct ion
getppid.
The synt ax of t he getppid f unct ion is
parentid = getppid();
Her e, parentid is t he pr ocess ID of your pr ogr am.
You can use getppid wit h fork t o ensur e t hat each of t he t wo pr ocesses pr oduced by
fork knows t he pr ocess ID of t he ot her .
List ing 15.7 shows how t o do t his.

List ing 15.7. A pr ogr am t hat cal l s fork and getppid.
1: #!/usr/local/bin/perl
2:
3: $otherid = fork();
4: if ($otherid == 0) {
5: # this is the child; retrieve parent ID
6: $otherid = getppid();
7: } else {
8: # this is the parent
9: }

This pr ogr am r equir es no input and gener at es no out put .
When l ine 3 cal l s fork, t he pr ogr am spl it s int o t wo separ at e pr ocesses (or
r unning pr ogr ams, if you want t o t hink of t hem t hat way). fork r et ur ns 0 t o t he chil d
pr ocess and r et ur ns t he pr ocess ID of t he chil d pr ocess t o t he par ent pr ocess. At t his
point , t he par ent pr ocess knows t he pr ocess ID of t he chil d, but t he chil d does not know
t he pr ocess ID of t he par ent .
Line 6, which is execut ed onl y by t he chil d pr ocess, f ixes t his imbal ance by cal l ing
getppid and r et ur ning t he pr ocess ID of t he par ent (t he ot her pr ocess cr eat ed by fork).
Af t er t he chil d pr ocess execut es l ine 6, bot h t he par ent and t he chil d pr ocess have
st or ed t he pr ocess ID of t he ot her pr ocess in t he scal ar var iabl e $otherid.
Af t er each pr ocess has t he ID of t he ot her , t he pr ocesses can send signal s t o one anot her
using t he kill f unct ion (which is discussed on Day 13, "Pr ocess, St r ing, and
Mat hemat ical Funct ions").
The getpwnam Function
On UNIX machines, t he /etc/passwd f il e (al so known as t he passwor d f il e) cont ains
inf or mat ion on each of t he user s who ar e aut hor ized t o use t he machine. The getpwnam
f unct ion enabl es you t o r et r ieve t he passwor d f il e ent r y f or a par t icul ar user .
The synt ax of t he getpwnam f unct ion is
(username, password, userid, groupid, quota, comment, infofield,
_homedir, shell) = getpwnam (name);
name is t he l ogin user ID of t he user whose inf or mat ion you want t o r et r ieve. If an ent r y
in t he /etc/passwd f il e cor r esponds t o t his name, getpwnam r et ur ns a nine-el ement l ist
cont aining t he cont ent s of t he ent r y. These cont ent s ar e
G username, which is ident ical t o name
G password, which is t he user 's encr ypt ed passwor d
G userid, which is t he unique numer ical ID t hat r epr esent s t his user
G groupid, which is t he ID of t he gr oup t o which t his user bel ongs
G quota and comment, which mean dif f er ent t hings on dif f er ent machines (check your
l ocal getpwnam manual page f or det ail s)
G infofield, which is a char act er st r ing cont aining per sonal inf or mat ion about t he
user (such as t he r oom number of t he user 's of f ice, or t he user 's phone number )
G homedir, which is t he user 's home dir ect or y (t he dir ect or y t hat becomes t he
cur r ent dir ect or y when t he user l ogs in)
G shell, which is t he command shel l t hat is st ar t ed when t he user l ogs in
getpwnam r et ur ns t he empt y l ist if no passwor d f il e ent r y f or name exist s.
You can use getpwnam in var ious ways. The most common way is t o r et r ieve t he user ID or
gr oup ID cor r esponding t o a par t icul ar user name. List ing 15.8 is a pr ogr am t hat
r et r ieves and pr int s t he user ID f or a par t icul ar user .

List ing 15.8. A pr ogr am t hat r et r ieves t he user ID
f or a user .
1: #!/usr/local/bin/perl
2:
3: print ("Enter a username:\n");
4: $username = <STDIN>;
5: $username =~ s/^\s+|\s+$//g;
6: if (($username, $passwd, $userid) = getpwnam ($username)) {
7: print ("Username $username has user id $userid.\n");
8: } else {
9: print ("Username not found.\n");
10: }

$ program15_8
Enter a username:
dave
Username dave has userid 127.
$
Af t er l ines 4 and 5 have r et r ieved t he user name and r emoved any ext r aneous
whit e space, l ine 6 passes t he user name t o getpwnam. If a passwor d f il e ent r y exist s f or
t his user name, t he nine-el ement ent r y is r et ur ned, and t he f ir st t hr ee el ement s ar e
assigned t o $username, $password, and $userid. (The r emaining el ement s ar e t hr own
away.) The t hir d el ement , t he user ID, is st or ed in $userid and is pr int ed by l ine 7.
The getpwuid Function
The getpwuid f unct ion is simil ar t o t he getpwnam f unct ion because it al so accesses t he
/etc/passwd f il e. getpwuid, however , sear ches f or t he passwor d f il e ent r y t hat mat ches
a par t icul ar user ID.
The synt ax of t he f unct ion is
(username, password, userid, groupid, quota, comment, infofield,
_homedir, shell) = getpwuid (inputuid);
inputuid is t he user ID t hat is t o be sear ched f or ; it must be a nonzer o int eger . The nine-
el ement l ist r et ur ned by getpwuid is ident ical t o t hat r et ur ned by getpwnam.
NOTE
The userid f iel d in t he nine-el ement l ist r et ur ned by
getpwuid is al ways ident ical t o t he inputuid f iel d t hat is
passed as an ar gument
The getpwent Function
The getpwnam and getpwuid f unct ions enabl e you t o r et r ieve a singl e ent r y f r om t he
passwor d f il e. To access each ent r y of t he passwor d f il e in t ur n, cal l getpwent.
The synt ax f or t he getpwent f unct ion is
(username, password, userid, groupid, quota, comment, infofield,
_homedir, shell) = getpwent();
When a pr ogr am cal l s getpwent f or t he f ir st t ime, it r et r ieves t he f ir st ent r y in t he
/etc/passwd f il e. Subsequent cal l s r et r ieve f ur t her ent r ies; if no mor e ent r ies r emain,
t he empt y l ist is r et ur ned.
The component s of t he nine-el ement l ist r et ur ned by getpwent ar e t he same as t hose in
t he l ist s r et ur ned by getpwnam and getpwuid.
List ing 15.9 is an exampl e of a pr ogr am t hat uses getpwent. It l ist s t he user names known
by t he machine as wel l as t heir user IDs.

List ing 15.9. A pr ogr am t hat uses getpwent.
1: #!/usr/local/bin/perl
2:
3: while (1) {
4: last unless (($username, $password, $userid)
5: = getpwent());
6: $userlist{$username} = $userid;
7: }
8: print ("Users known to this machine:\n");
9: foreach $user (sort keys (%userlist)) {
10: printf ("%-20s %d\n", $user, $userlist{$user});
11: }

$ program15_9
Users known to this machine:
adm 4
daemon 1
dave 127
ftp 8
jimmy 711
root 0
$
The while l oop in l ines 3-7 uses getpwent t o r ead ever y ent r y in t he passwor d
f il e. Onl y t he f ir st t hr ee el ement s of t he r et ur ned l ist ar e saved-in t he scal ar var iabl es
$username, $password, and $userid-t he r est ar e t hr own away. Af t er t he /etc/passwd f il e
has been compl et el y r ead, l ine 4 t er minat es t he while l oop.
Line 6 cr eat es an associat ive ar r ay el ement f or each user . The subscr ipt f or t he ar r ay
el ement is t he user name, and t he val ue of t he el ement is t he user ID.
Lines 9-11 pr int t he l ist of user s, sor t ing t hem in or der by user name and pr int ing t he
name and user ID f or each.
The setpwent and endpwent Functions
Like getpwent, setpwent and endpwent manipul at e t he /etc/passwd f il e.
The setpwent f unct ion r ewinds t he /etc/passwd f il e.
The synt ax of t he setpwent f unct ion is
setpwent (keepopen);
If keepopen is nonzer o, t he Per l int er pr et er assumes t hat t he /etc/passwd f il e is t o be
accessed again, and it keeps inf or mat ion about t he passwor d f il e st or ed in int er nal
memor y. If keepopen is zer o, any inf or mat ion t he pr ogr am has r el at ed t o t he passwor d
f il e is t hr own away.
The endpwent f unct ion cl oses t he passwor d f il e and t el l s t he pr ogr am t o t hr ow away
any int er nal memor y r el at ed t o it .
The endpwent f unct ion accept s no ar gument s and r et ur ns no val ues.
endpwent();
The getpriority and setpriority Functions
In t he UNIX envir onment , each pr ocess has a pr ior it y, which t el l s t he syst em which
pr ocesses ar e impor t ant and which ar e not . Pr ior it ies ar e int eger val ues t hat var y f r om
syst em t o syst em: a t ypical r ange is f r om -20 (most impor t ant ) t o 20 (l east impor t ant ),
wit h a def aul t val ue of 0.
NOTE
Al t hough pr ior it y r anges might var y f r om syst em t o
syst em, t he gener al r ul e under UNIX is al ways t his: t he
higher t he pr ior it y number associat ed wit h a pr ocess, t he
l ess impor t ant t he pr ocess is
To change t he pr ior it y f or your pr ogr am, pr ocess, pr ocess gr oup, or user ID, cal l t he
setpriority f unct ion.
The synt ax of t he setpriority f unct ion is
setpriority (category, id, priority);
category is a scal ar val ue t hat indicat es what pr ocesses ar e t o have t heir pr ior it ies
al t er ed. To f ind t he val ue t o use, t ake t he f ol l owing act ions:
G Examine t he header f il e /usr/include/sys/resource.h
G In t his f il e, l ook up and not e t he val ues of t he const ant s PRIO_PROCESS, PRIO_PGRP,
and PRIO_USER
G Pick t he appr opr iat e val ue t o use, as descr ibed in t he r emainder of t his sect ion
NOTE
If you ar e not f amil iar wit h t he C pr ogr amming
l anguage, t he val ue of a const ant is specif ied by a
st at ement of t he f ol l owing f or m:
#define constant value
Her e, constant is a const ant such as PRIO_PROCESS, and
value is it s def ined val ue
If category is t he val ue associat ed wit h PRIO_PROCESS, onl y one pr ocess has it s pr ior it y
al t er ed. If category is t he val ue of PRIO_PGRP, ever y pr ocess in a pr ocess gr oup has it s
pr ior it y al t er ed. If category is t he val ue of PRIO_USER, ever y pr ocess bel onging t o a
par t icul ar user has it s pr ior it y al t er ed.
The val ue of id depends on category. If category is t he val ue of PRIO_PROCESS, id is t he
pr ocess ID f or t he pr ocess whose pr ior it y is t o be al t er ed. If category is t he val ue of
PRIO_PGRP, id is t he pr ocess gr oup ID f or t he gr oup whose pr ior it y is t o be al t er ed. If
category is PRIO_USER, id is t he user ID f or t he gr oup whose pr ior it y is t o be al t er ed.
NOTE
If category is t he val ue of PRIO_PROCESS or PRIO_PGRP
and id is 0, id is assumed t o be t he ID of t he cur r ent
pr ocess or pr ocess gr oup
priority is t he new pr ior it y f or t he pr ocess, gr oup, or user . You can specif y a l ower
pr ior it y val ue f or your pr ocess or pr ocesses (in ot her wor ds, specif y t hat your pr ocesses
ar e "mor e impor t ant ") onl y if you ar e a pr ivil eged user (t he super user ).
The f unct ion getpriority r et r ieves t he cur r ent pr ior it y f or a pr ocess, pr ocess gr oup, or
user .
The synt ax of t he getpriority f unct ion is
priority = getpriority (category, id);
Her e, category and id ar e ident ical t o t he equival ent ar gument s in setpriority.
priority is t he r et ur ned cur r ent pr ior it y.
List ing 15.10 is a pr ogr am t hat l ower s t he pr ior it y of ever y pr ocess you ar e cur r ent l y
r unning. It uses sever al of t he f unct ions you have seen in t oday's l esson.

List ing 15.10. A pr ogr am t hat uses setpriority and getpriority.
1: #!/usr/local/bin/perl
2:
3: print ("You're not in a hurry today, are you?\n");
4: $username = getlogin();
5: ($username, $password, $userid) = getpwnam ($username);
6: $oldpriority = getpriority (2, $userid);
7: setpriority (2, $userid, $oldpriority + 1);

$ program15_10
You're not in a hurry today, are you?
$
Line 4 of t his pr ogr am cal l s getlogin, which r et r ieves t he user 's l ogin name.
Then, l ine 5 passes t his name t o getpwnam, which r et r ieves t he user ID f r om t he
/etc/passwd f il e.
Line 6 cal l s getpriority. Because t he f ir st ar gument t o getpriority is 2 (t he val ue of
t he syst em const ant PRIO_USER), t he cur r ent pr ior it y f or al l pr ocesses owned by t he user
specif ied by t he user ID st or ed in $userid is r et ur ned.
Line 7 cal l s setpriority, adding one t o t he cur r ent pr ior it y f or t he user t o obt ain t he
new pr ior it y. As in l ine 6, t he f ir st ar gument t o setpriority is 2 (PRIO_USER), which
indicat es t hat t he cur r ent pr ior it y f or al l pr ocesses bel onging t o t his user is t o be
changed.
The getprotoent Function
The getprotoent f unct ion enabl es you t o sear ch t hr ough t he syst em pr ot ocol dat abase,
which is st or ed in t he f il e /etc/protocols.
The synt ax of t he getprotoent f unct ion is
(name, aliases, number) = getprotoent();
name is t he name associat ed wit h a par t icul ar syst em pr ot ocol . aliases is a scal ar val ue
consist ing of a l ist of al t er nat ive names f or t his syst em pr ot ocol , wit h names being
separ at ed by a space. number is t he number associat ed wit h t his par t icul ar syst em
pr ot ocol .
The f ir st cal l t o getprotoent r et ur ns t he f ir st el ement in /etc/protocols. Fur t her
cal l s r et ur n subsequent ent r ies; when /etc/protocols is exhaust ed, getprotoent
r et ur ns t he empt y l ist .
The getprotobyname and getprotobynumber Functions
The getprotobyname and getprotobynumber f unct ions pr ovide ways of sear ching in t he
/etc/protocols f il e.
The getprotobyname f unct ion enabl es you t o sear ch f or a par t icul ar pr ot ocol ent r y in
t he
/etc/protocols f il e.
The synt ax of t he getprotobyname f unct ion is
(name, aliases, number) = getprotobyname (searchname);
Her e, searchname is t he pr ot ocol name you ar e l ooking f or . name, aliases, and number ar e
t he same as in getprotoent.
Simil ar l y, getprotobynumber sear ches f or a pr ot ocol ent r y in /etc/protocols t hat
mat ches a par t icul ar pr ot ocol number .
The synt ax of t he getprotobynumber f unct ion is
(name, aliases, number) = getprotobynumber (searchnum);
searchnum is t he pr ot ocol number t o sear ch f or . name, aliases, and number ar e t he same as
in getprotoent.
Bot h f unct ions r et ur n t he empt y l ist if no mat ching pr ot ocol dat abase ent r y is f ound.
The setprotoent and endprotoent Functions
The setprotoent and endprotoent f unct ions pr ovide ot her ways of manipul at ing t he
/etc/protocols f il e.
The setprotoent f unct ion r ewinds t he /etc/protocols f il e.
The synt ax of t he setprotoent f unct ion is
setprotoent (keepopen);
If keepopen is a nonzer o val ue, t he val ue indicat es t hat t he pr ogr am shoul d keep
/etc/protocols open, because it int ends t o cont inue accessing t he syst em pr ot ocol
dat abase. Af t er setprotoent has been cal l ed, t he next cal l t o getprotoent r eads (or
r er eads) t he f ir st el ement of t he dat abase.
The endprotoent f unct ion cl oses t he /etc/protocols f il e and indicat es t hat t he pr ogr am
no l onger want s t o r ead any syst em pr ot ocol s f r om t he dat abase.
The endprotoent f unct ion r equir es no ar gument s and r et ur ns no val ues:
endprotoent();
NOTE
For mor e inf or mat ion on syst em pr ot ocol s, r ef er t o t he
getprotoent manual page on your syst em
The getservent Function
The getservent f unct ion enabl es you t o sear ch t hr ough t he syst em ser vices dat abase,
which is st or ed in t he f il e /etc/services.
The synt ax of t he getservent f unct ion is
(name, aliases, portnum, protoname) = getservent();
name is t he name associat ed wit h a par t icul ar syst em ser vice. aliases is a scal ar val ue
consist ing of a l ist of al t er nat ive names f or t his syst em ser vice; t he names ar e separ at ed
by a space.
portnum is t he por t number associat ed wit h t his par t icul ar syst em pr ot ocol , which
indicat es t he l ocat ion of t he por t at which t he ser vice is r esiding. This por t number is
r et ur ned as a packed ar r ay of int eger s, which can be unpacked using unpack (wit h a C*
f or mat specif ier ).
protoname is a pr ot ocol name (such as tcp).
The f ir st cal l t o getservent r et ur ns t he f ir st el ement in /etc/services. Fur t her cal l s
r et ur n subsequent ent r ies; when /etc/services is exhaust ed, getservent r et ur ns t he
empt y l ist .
The getservbyname and getservbyport Functions
The getservbyname and getservbyport f unct ions pr ovide ways of sear ching in t he
/etc/services f il e.
The getservbyname f unct ion enabl es you t o sear ch t he /etc/services f il e f or a
par t icul ar ser vice name.
The synt ax of t he getservbyname f unct ion is
(name, aliases, portnum, protoname) = getservbyname (searchname,
searchproto);
Her e, searchname and searchproto ar e t he ser vice name and ser vice pr ot ocol t ype t o be
mat ched. If t he name and t ype ar e mat ched, getservbyname r et ur ns t he syst em ser vice
dat abase ent r y cor r esponding t o t his name and t ype. This ent r y is t he same f our -el ement
l ist as is r et ur ned by getservent. (The empt y l ist is r et ur ned if t he name and t ype ar e not
mat ched.)
Simil ar l y, t he getservbyport f unct ion sear ches f or a ser vice name t hat mat ches a
par t icul ar ser vice por t number .
The synt ax of t he getservbyname f unct ion is
(name, aliases, portnum, protoname) = getservbyname (searchportnum,
searchproto);
searchportnum and searchproto ar e t he por t number and pr ot ocol t ype t o sear ch f or .
name, aliases, portnum, and protoname ar e t he same as in getservbyname and getservent.
The setservent and endservent Functions
The setservent and endservent f unct ions pr ovide ot her ways of manipul at ing t he
/etc/services f il e.
The setservent f unct ion r ewinds t he /etc/services f il e.
The synt ax of t he setservent f unct ion is
setservent (keepopen);
Af t er setservent has been cal l ed, t he next cal l t o getservent r et r ieves t he f ir st
el ement of t he /etc/services f il e. keepopen, if nonzer o, specif ies t hat t he /etc/services
f il e is st il l in use and is t o r emain open.
The f unct ion endservent indicat es t hat t he /etc/services f il e can be cl osed, because it
is no l onger needed.
The endservent f unct ion r equir es no ar gument s and r et ur ns no val ues:
endservent();
The chroot Function
The chroot f unct ion enabl es you t o specif y t he r oot dir ect or y f or your pr ogr am and any
subpr ocesses t hat it cr eat es.
The synt ax of t he chroot f unct ion is
chroot (dirname);
dirname is t he name of t he dir ect or y t o ser ve as t he r oot . Af t er chroot has been cal l ed,
t he dir ect or y name specif ied by dirname is appended t o ever y pat hname specif ied by your
pr ogr am and it s subpr ocesses. For exampl e, t he st at ement
chroot ("/pub");
adds /pub t o t he f r ont of ever y dir ect or y name. For exampl e, when your pr ogr am or a
subpr ocess t r ies t o access t he dir ect or y /u/jqpublic, t he dir ect or y it accesses is
act ual l y /pub/u/jqpublic.
chroot of t en is used t o r est r ict access t o a par t icul ar por t ion of a f il e syst em. It can be
cal l ed onl y if you have super user pr ivil eges on your machine and execut e per mission on
t he specif ied r oot dir ect or y.
The ioctl Function
The ioctl f unct ion enabl es you t o set syst em-dependent f il e at t r ibut es (such as t he
special char act er def init ions f or your keyboar d).
The synt ax of t he ioctl f unct ion is
ioctl (filevar, attribute, value);
filevar is a f il e var iabl e r epr esent ing a pr eviousl y opened f il e. attribute is a val ue
r epr esent ing t he oper at ion t o be per f or med. Incor por at ed as par t of t he attribute val ue
is a number indicat ing whet her t he oper at ion is r et r ieving t he val ue of an at t r ibut e or
set t ing t he val ue of an at t r ibut e.
value hol ds t he at t r ibut e val ue associat ed wit h t he oper at ion specif ied by attribute. If
t he oper at ion is set t ing an at t r ibut e, value cont ains t he new val ue of t he at t r ibut e. If
t he oper at ion is r et r ieving t he cur r ent val ue of t he at t r ibut e, value is assigned t his
cur r ent val ue.
ioctl r et ur ns a nonzer o val ue if t he oper at ion is per f or med successf ul l y, or zer o if t he
oper at ion f ail s.
NOTE
For det ail s on what oper at ions can be per f or med on your
machine, r ef er t o t he f il e /usr/include/sys/ioctl.h on
your machine. This f il e is a header f il e wr it t en in t he C
pr ogr amming l anguage t hat cont ains inf or mat ion on t he
avail abl e ioctl oper at ions
Dif f er ent machines (and devices) suppor t dif f er ent ioctl
oper at ions. Thus, a pr ogr am t hat r equest s an ioctl
oper at ion is not por t abl e if you move it f r om one machine
t o anot her . You t her ef or e shoul d use ioctl oper at ions
onl y when you must
The alarm Function
The alarm f unct ion sends a special "al ar m" signal , SIGALARM, t o your pr ogr am.
The synt ax of t he alarm f unct ion is
alarm (value);
value is an expr ession indicat ing how many seconds ar e t o pass bef or e t he al ar m goes of f .
For mor e inf or mat ion on signal s and t heir r el at ionship t o pr ocesses, r ef er t o t he
descr ipt ion of t he kill f unct ion on Day 13.
Calling the System select Function
Per l enabl es you t o cal l t he UNIX select f unct ion f r om wit hin your Per l pr ogr am.
The synt ax f or a cal l t o t he UNIX select f unct ion is
select (rmask, wmask, emask, timeout);
rmask, wmask and emask ar e bit masks, and timeout is a t imeout val ue in seconds.
For mor e inf or mat ion on select, r ef er t o t he UNIX manual page.
NOTE
The UNIX select f unct ion is dif f er ent f r om t he Per l
select f unct ion t hat you've seen in ear l ier l essons.
The Per l int er pr et er det er mines whet her a pr ogr am is
cal l ing t he Per l select f unct ion or t he UNIX select
f unct ion by count ing t he number of ar gument s: t he Per l
f unct ion expect s onl y one, and t he UNIX f unct ion
expect s f our
The dump Function
The dump f unct ion, which is def ined onl y in Per l 5, enabl es you t o gener at e a UNIX cor e
dump f r om wit hin your Per l pr ogr am.
The synt ax f or t he dump f unct ion is
dump(label);
label is an opt ional l abel , specif ying wher e execut ion is t o r est ar t if t he UNIX undump
command is execut ed.
If a cor e dump f il e cr eat ed by dump is r est ar t ed by t he
UNIX undump command, f il es t hat wer e open when t he
pr ogr am was execut ing wil l no l onger be open. This
means t hey cannot be r ead f r om or wr it t en t o
Socket-Manipulation Functions
In Ber kel ey UNIX envir onment s (ver sion 4.3BSD) and some ot her envir onment s, pr ocesses
can communicat e wit h one anot her using a connect ion device known as a socket. When a
socket has been cr eat ed, one pr ocess can wr it e dat a which can t hen be r ead by anot her
pr ocess.
Per l suppor t s var ious f unct ions t hat cr eat e socket s and set up connect ions wit h t hem.
The f ol l owing sect ions descr ibe t hese f unct ions.
The socket Function
To cr eat e a socket , cal l t he socket f unct ion. This f unct ion def ines a socket and
associat es it wit h a Per l f il e var iabl e.
The synt ax of t he socket f unct ion is
socket (socket, domain, type, format);
socket is a f il e var iabl e t hat is t o be associat ed wit h t he new socket .
domain is t he pr ot ocol f amil y t o use. The l egal val ues f or domain ar e l ist ed in t he syst em
header f il e /usr/include/sys/socket.h; t hese val ues ar e r epr esent ed by t he const ant s
PF_UNIX, PF_INET, PF_IMPLINK, and PF_NS.
type is t he t ype of socket t o cr eat e. The l egal val ues f or type ar e al so l ist ed in t he f il e
/usr/include/sys/socket.h. These l egal val ues ar e r epr esent ed by t he f ive const ant s
SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, SOCK_SEQPACKET, and SOCK_RDM.
format is t he number of t he pr ot ocol t o be used wit h t he socket . This pr ot ocol is
nor mal l y r et r ieved by cal l ing getprotobyname. (See t he manual page f or getprotobyname
f or det ail s on what pr ot ocol s ar e suppor t ed on your machine.)
The socket f unct ion r et ur ns a nonzer o val ue if t he socket has been cr eat ed and zer o if
an er r or occur s.
The bind Function
Af t er you cr eat e a socket using socket, t he next st ep is t o bind t he socket t o a
par t icul ar net wor k addr ess. To do t his, use t he bind f unct ion.
The synt ax of t he bind f unct ion is
bind (socket, address);
Her e, socket is t he f il e var iabl e cor r esponding t o t he socket cr eat ed by socket.
address is t he net wor k addr ess t o be associat ed wit h t he socket . This addr ess consist s of
t he f ol l owing el ement s:
G The addr ess t ype, which is an unsigned shor t int eger and is al ways AF_INET
(def ined in /usr/include/netdb.h or /usr/include/bsd/netdb.h).
G The number of t he por t t o use when connect ing, which is a shor t int eger in
net wor k or der
G The packed f our -byt e r epr esent at ion of t he Int er net addr ess of t he machine t o
which t he socket is t o be bound
This f unct ion r et ur ns a nonzer o val ue if t he bind oper at ion succeeds and zer o if an
er r or occur s.
To cr eat e an addr ess suit abl e f or passing t o bind, cal l pack.
$address = pack ("Sna4x8", 2, $portnum, $intaddress);
Her e, t he pack f or mat specif ier Sna4x8 indicat es an unsigned shor t int eger , f ol l owed by
a shor t int eger in net wor k or der (t he por t number ), a f our -byt e ASCII st r ing (which is
t he packed addr ess), and eight nul l byt es. This is t he f or mat t hat bind expect s when
binding an addr ess t o a socket .
The listen Function
Af t er an addr ess has been bound t o t he socket associat ed wit h each of t he machines t hat
ar e t o communicat e, t he next st ep is t o def ine a pr ocess t hat is t o be t he "l ist ening"
pr ocess. This pr ocess wait s f or connect ions t o be est abl ished wit h it . (In a cl ient -ser ver
ar chit ect ur e, t his pr ocess cor r esponds t o t he ser ver .) To def ine t his l ist ening pr ocess,
cal l t he listen f unct ion.
The synt ax of t he listen f unct ion is
listen (socket, number);
socket is t he socket cr eat ed using t he socket f unct ion. number is t he maximum number of
pr ocesses t hat can be queued up t o connect t o t his pr ocess.
listen r et ur ns a nonzer o val ue if it execut es successf ul l y, zer o if it does not .
The maximum number of pr ocesses t hat can be queued
using listen is 5. This l imit at ion is imposed by t he
Ber kel ey UNIX oper at ing syst em
The accept Function
Af t er a pr ocess t hat has been est abl ished as t he l ist ening pr ocess cal l s listen, t he next
st ep is t o have t his pr ocess cal l t he accept f unct ion. accept wait s unt il a pr ocess want s
t o connect wit h it , and t hen it r et ur ns t he addr ess of t he connect ing pr ocess.
The synt ax of t he accept f unct ion is
accept (procsocket, socket);
procsocket is a pr eviousl y undef ined f il e var iabl e t hat is t o r epr esent t he newl y
cr eat ed connect ion. The l ist ening pr ocess can t hen send t o or r eceive f r om t he ot her
pr ocess using t he f il e var iabl e specif ied in procsocket. This f il e var iabl e can be t r eat ed
l ike any ot her f il e var iabl e: t he pr ogr am can send dat a t hr ough t he socket by cal l ing
write or print, or can r ead dat a using t he <> oper at or .
socket is t he socket cr eat ed by socket and bound t o an addr ess by bind.
List ing 15.11 is an exampl e of a pr ogr am t hat uses listen and accept t o cr eat e a simpl e
ser ver . This ser ver just sends t he message Hello, world! t o any pr ocess t hat connect s t o
it . (A cl ient pr ogr am t hat r eceives t his message is l ist ed in t he next sect ion, "The connect
Funct ion.")

List ing 15.11. A simpl e ser ver pr ogr am.
1: #!/usr/local/bin/perl
2:
3: $line = "Hello, world!\n";
4:
5: $port = 2000;
6: while (getservbyport ($port, "tcp")) {
7: $port++;
8: }
9: ($d1, $d2, $prototype) = getprotobyname ("tcp");
10: ($d1, $d2, $d3, $d4, $rawserver) = gethostbyname ("silver");
11: $serveraddr = pack ("Sna4x8", 2, $port, $rawserver);
12: socket (SSOCKET, 2, 1, $prototype) || die ("No socket");
13: bind (SSOCKET, $serveraddr) || die ("Can't bind");
14: listen (SSOCKET, 1) || die ("Can't listen");
15: ($clientaddr = accept (SOCKET, SSOCKET)) ||
16: die ("Can't accept");
17: select (SOCKET);
18: $| = 1;
19: print SOCKET ("$line\n");
20: close (SOCKET);
21: close (SSOCKET);
This pr ogr am r equir es no input and gener at es no out put .
The f ir st t ask t his ser ver pr ogr am per f or ms is t o sear ch f or a por t t o use when
est abl ishing a socket connect ion. To be on t he saf e side, t he pr ogr am f ir st checks t hat
t he por t it is going t o use, por t 2000, is not r eser ved f or use by anot her pr ogr am. If it is
r eser ved, t he pr ogr am checks por t 2001, t hen por t 2002, and so on unt il it f inds an
unused por t .
To do t his checking, l ine 6 cal l s getservbyport. If getservbyport r et ur ns a non-empt y
l ist , t he por t being checked is l ist ed in t he /etc/services f il e, which means t hat it is
being used by some ot her pr ogr am. In t his case, t he por t number is incr eased by one, and
getservbyport is cal l ed again. This pr ocess cont inues unt il getservbyport r et ur ns an
empt y l ist , which indicat es t hat t he por t being checked is unused. When l ines 5-8 ar e no
l onger execut ing, t he scal ar var iabl e $port cont ains t he number of t he por t t o be used.
Line 9 cal l s getprotobyname t o r et r ieve t he /etc/protocols ent r y associat ed wit h t he
TCP pr ot ocol . The pr ot ocol number associat ed wit h t he TCP pr ot ocol is r et r ieved f r om
t his /etc/protocols ent r y and is st or ed in t he scal ar var iabl e $prototype. (The ot her
el ement s of t he l ist ar e ignor ed; t he convent ion used by t his pr ogr am is t o st or e el ement
ent r ies t hat ar e not going t o be used in var iabl es named $d1, $d2, and so on; t he d st ands
f or dummy.)
Line 10 cal l s gethostbyname t o r et r ieve t he net wor k addr ess of t he machine on which
t his ser ver is r unning. This pr ogr am assumes t hat t he ser ver is r unning on a l ocal
machine named silver. To r un t his pr ogr am on your own machine, r epl ace silver wit h
your machine name.
TIP
You can modif y t his pr ogr am t o r un on any machine. To
do so, modif y l ine 10 as shown her e:
($d1, $d2, $d3, $d4, $rawserver) = gethostbyname
('hostname');
The st r ing in backquot es, 'hostname', t el l s t he Per l
int er pr et er t o cal l t he hostname pr ogr am and r et ur n it s
out put as a scal ar val ue. The hostname pr ogr am r et ur ns
t he name of t he machine on which it is r unning.
Ther ef or e, t he cal l t o gethostbyname r et r ieves t he
addr ess
of t he machine on which you ar e r unning r egar dl ess of
what t he machine is.
This capabil it y enabl es you t o move t his pr ogr am f r om
one machine t o anot her wit hout having t o modif y it .
Not e t hat encl osing a command in backquot es wor ks f or
any UNIX command t hat r et ur ns out put . For exampl e,
t he st at ement
$user id = 'whoami';
assigns t he cur r ent l ogin user ID t o t he scal ar var iabl e
$userid (because t he UNIX command whoami displ ays t he
cur r ent l ogin user ID)
Af t er gethostbyname has been cal l ed, t he scal ar var iabl e $rawserver cont ains t he
Int er net addr ess of your machine. Line 11 cal l s pack t o conver t t he addr ess t ype, t he
por t number , and t his addr ess int o t he f or m under st ood by t he oper at ing syst em. (The
addr ess t ype par amet er , 2, is t he l ocal val ue of AF_INET, which is t he onl y addr ess t ype
suppor t ed.) This inf or mat ion is st or ed in t he scal ar var iabl e $serveraddr.
Af t er pack is cal l ed t o buil d t he ser ver addr ess, t he pr ogr am is r eady t o cr eat e a socket .
Line 12 does t his by cal l ing socket. This cal l t o socket passes it t he f il e var iabl e
SSOCKET, t he socket domain, t he socket t ype, and t he pr ot ocol number . Af t er socket is
cal l ed, t he f il e var iabl e SSOCKET r epr esent s t he "mast er socket " t hat is t o l ist en f or
connect ions. (Not e t hat t he val ues 2 and 1 passed t o socket ar e, r espect ivel y, t he l ocal
val ues of t he const ant s PF_INET and SOCK_STREAM. PF_INET indicat es Int er net -st yl e
pr ot ocol , and SOCK_STREAM indicat es t hat t r ansmission wil l be in t he f or m of a st r eam of
byt es. You l ikel y wil l not need t o use any ot her val ues f or t hese ar gument s.)
Af t er t he socket has been cr eat ed, t he next st ep is l ine 13, which associat es t he socket
wit h your machine by cal l ing bind. This cal l t o bind is passed t he f il e var iabl e SSOCKET
associat ed wit h t he socket and t he ser ver addr ess cr eat ed by t he cal l t o pack in l ine 11.
Af t er t he socket is bound t o your machine addr ess, you ar e r eady t o l ist en f or cl ient s
t hat want t o connect t o your ser ver . Line 14 does t his by cal l ing listen. This cal l t o
listen is passed t he f il e var iabl e SSOCKET and t he val ue 1; t he l at t er indicat es t hat
onl y one cl ient is l ist ened f or at any par t icul ar t ime.
Line 15 cal l s accept, which wait s unt il a cl ient pr ocess want s t o connect t o t his ser ver .
When a connect ion is est abl ished, accept cr eat es a new socket associat ed wit h t his
connect ion and uses t he f il e var iabl e SOCKET t o r epr esent it . (The addr ess of t he cl ient
connect ion is r et ur ned in $clientaddr; if you want t o, you can use unpack t o obt ain t he
addr ess, and t hen cal l gethostbyaddr t o r et r ieve t he name of t he machine on which t he
cl ient pr ocess is r unning.)
When t he connect ion has been est abl ished and t he f il e var iabl e SOCKET has been
associat ed wit h it , you can t r eat SOCKET l ike any ot her f il e var iabl e: you can r ead dat a
f r om it or wr it e dat a t o it . Lines 17 and 18 t ur n of f buf f er ing f or SOCKET, which ensur es
t hat dat a sent t hr ough t he socket is sent r ight away. (If buf f er ing is l ef t on, t he
pr ogr am won't send dat a unt il t he special int er nal buf f er is f ul l , which means t hat t he
cl ient pr ocess won't r eceive t he dat a r ight away.) Af t er buf f er ing is t ur ned of f , l ine 19
wr it es t he l ine of dat a t o SOCKET, which sends it t o t he cl ient pr ocess. (For mor e
inf or mat ion on buf f er ing and how it wor ks, r ef er t o "Redir ect ing One Fil e t o Anot her "
on Day 12, "Wor king wit h t he Fil e Syst em.")
Al t hough you can bot h send and r eceive dat a t hr ough
t he same socket , doing so is danger ous, because you r un
t he r isk of deadl ock. Deadlock occur s when t he cl ient
and ser ver pr ocesses t hink t hat t he ot her is going t o
send dat a. Neit her can pr oceed unt il t he ot her does.
The onl y way t o get out of a deadl ock is t o send signal s
t o t he pr ocesses (such as KILL).
To avoid a deadl ock, make sur e t hat you under st and how
dat a f l ows bet ween t he pr ocesses you ar e r unning
The connect Function
As you have seen, when t wo pr ocesses communicat e using a socket , one pr ocess is
designat ed as t he l ist ening pr ocess. This pr ocess cal l s listen t o indicat e t hat it is t he
l ist ening pr ocess, and t hen it cal l s accept t o wait f or a connect ion f r om anot her
pr ocess. (List ening pr ocesses ar e cal l ed servers, because t hey pr ovide ser vice t o t he
pr ocesses t hat connect t o t hem. The pr ocesses t hat connect t o ser ver s ar e cal l ed clients.)
To connect t o a pr ocess t hat has cal l ed accept and is now wait ing f or a connect ion, use
t he connect f unct ion.
The synt ax of t he connect f unct ion is
connect (socket, address);
socket is a f il e var iabl e r epr esent ing a socket cr eat ed using socket and bound using
bind. address is t he int er nal r epr esent at ion of t he Int er net addr ess t o which you want
t o connect . In t he pr ocess t o which t his pr ocess is connect ing, t his addr ess must have
been passed t o bind t o bind it t o a socket , and t he socket , in t ur n, must have been
specif ied in cal l s t o listen and accept.
Af t er connect has been cal l ed, t he pr ogr am t hat cal l s it can send dat a t o or r eceive
dat a f r om t he ot her pr ocess by means of t he f il e var iabl e specif ied in socket.
List ing 15.12 is an exampl e of a pr ogr am t hat uses connect t o obt ain dat a f r om anot her
pr ocess. (The pr ocess t hat sends t he dat a is displ ayed in List ing 15.11.)

List ing 15.12. A simpl e cl ient pr ogr am.
1: #!/usr/local/bin/perl
2:
3: $port = 2000;
4: while (getservbyport ($port, "tcp")) {
5: $port++;
6: }
7: ($d1, $d2, $prototype) = getprotobyname ("tcp");
8: ($d1, $d2, $d3, $d4, $rawclient) = gethostbyname ("mercury");
9: ($d1, $d2, $d3, $d4, $rawserver) = gethostbyname ("silver");
10: $clientaddr = pack ("Sna4x8", 2, 0, $rawclient);
11: $serveraddr = pack ("Sna4x8", 2, $port, $rawserver);
12: socket (SOCKET, 2, 1, $prototype) || die ("No socket");
13: bind (SOCKET, $clientaddr) || die ("Can't bind");
14: connect (SOCKET, $serveraddr);
15:
16: $line = <SOCKET>;
17: print ("$line\n");
18: close (SOCKET);

$ program15_12
Hello, world!
$
Lines 3-6 obt ain t he por t t o use when r eceiving dat a by means of a socket
connect ion. As in List ing 15.11, t he por t number is compar ed wit h t he l ist of por t s st or ed
in /etc/services by cal l ing getservbyport. The f ir st unused por t number gr eat er t han
or equal t o 2000 becomes t he number of t he por t t o use. (This pr ogr am and List ing 15.11
assume t hat t he same /etc/services f il e is being examined in bot h cases. If t he
/etc/services f il es ar e dif f er ent , you wil l need t o choose a por t number your sel f and
specif y t his por t number in bot h your cl ient pr ogr am and your ser ver pr ogr am-in ot her
wor ds, assign a pr especif ied val ue t o t he var iabl e $port.)
Line 7 cal l s getprotobyname t o r et r ieve t he pr ot ocol number associat ed wit h t he TCP
pr ot ocol . This pr ot ocol number is event ual l y passed t o socket.
Lines 8 and 9 r et r ieve t he Int er net addr esses of t he cl ient (t his pr ogr am) and t he ser ver
(t he pr ocess t o connect t o). $rawclient is assigned t he Int er net addr ess of t he cl ient ,
and $rawserver is assigned t he Int er net addr ess of t he ser ver ; each of t hese addr esses is
a f our -byt e scal ar val ue.
Lines 10 and 11 t ake t he addr esses st or ed in $rawclient and $rawserver and conver t
t hem t o t he f or m used by t he socket pr ocessing f unct ions. In bot h cases, t he 2 passed t o
pack is t he l ocal val ue f or AF_INET (t he onl y t ype of addr ess suppor t ed in t he UNIX
envir onment ). Not e t hat l ine 10 doesn't bot her specif ying a por t val ue t o pass t o pack;
t his is because t he connect ion uses t he por t specif ied in t he ser ver addr ess in l ine 11.
Line 12 now cal l s socket t o cr eat e a socket f or t he cur r ent pr ogr am (t he cl ient ). As in
t he cal l t o socket in List ing 15.11, t he val ues 2 and 1 passed t o socket ar e t he l ocal
val ues of t he const ant s PF_INIT and SOCK_STREAM; if t hese val ues ar e dif f er ent on your
machine, you need t o r epl ace t he val ues shown her e wit h t he ones def ined f or your
machine. The cal l t o socket in l ine 12 associat es t he f il e var iabl e SOCKET wit h t he newl y
cr eat ed socket .
Af t er t he socket has been cr eat ed, l ine 13 cal l s bind t o associat e t he socket wit h t he
cl ient pr ogr am. bind r equir es t wo ar gument s: t he f il e var iabl e associat ed wit h t he
socket t hat has just been cr eat ed, and t he addr ess of t he cl ient machine as packed by
l ine 10.
Line 14 now t r ies t o connect t o t he ser ver pr ocess by cal l ing connect and passing it t he
ser ver addr ess cr eat ed by l ine 11. If t he connect ion is successf ul , you can send and
r eceive dat a t hr ough t he socket using t he SOCKET f il e var iabl e.
The SOCKET f il e var iabl e behaves just l ike any ot her f il e var iabl e. This means t hat l ine
16 r eads a l ine of dat a f r om t he ser ver pr ocess. Because t he ser ver pr ocess is sending t he
char act er st r ing Hello, world! (f ol l owed by a newl ine char act er ), t his is t he st r ing
t hat is assigned t o $line. Line 17 t hen pr int s $line, which means t hat t he f ol l owing
appear s on your scr een:
Hello, world!
Af t er t he cl ient pr ocess is f inished wit h t he socket, l ine 18 cal l s close. This cal l
indicat es t hat t he pr ogr am is f inished wit h t he socket . (Af t er t he socket is cl osed by
bot h t he ser ver and t he cl ient pr ogr ams, t he ser ver pr ogr am can accept a connect ion
f r om anot her cl ient pr ocess, if desir ed.)
The shutdown Function
When t wo pr ocesses ar e communicat ing using a socket , dat a can be sent in eit her
dir ect ion: t he cl ient can r eceive dat a f r om t he ser ver , or vice ver sa. The shutdown
f unct ion enabl es you t o indicat e t hat t r af f ic in one or bot h dir ect ions is no l onger
needed.
The synt ax f or t he shutdown f unct ion is
shutdown (socket, direction);
Her e, socket is t he f il e var iabl e associat ed wit h t he socket whose t r af f ic is t o be
r est r ict ed. direction is one of t he f ol l owing val ues:
G 0 indicat es t hat t he pr ogr am can send t hr ough t he socket but can no l onger
r eceive dat a.
G 1 indicat es t hat t he pr ogr am can r eceive dat a f r om t he socket but can no l onger
send.
G 2 indicat es t hat bot h sending and r eceiving ar e disal l owed.
NOTE
To t er minat e communicat ion t hr ough a socket , cal l
close and pass it t he f il e var iabl e associat ed wit h t he
socket :
close (SOCKET);
This l ine cl oses t he socket r epr esent ed by SOCKET
The socketpair Function
The socketpair f unct ion is simil ar t o socket, but it cr eat es a pair of socket s r at her t han
just one socket .
The synt ax of t he socketpair f unct ion is
socketpair (socket1, socket2, domain, type, format);
socket1 is t he f il e var iabl e t o be associat ed wit h t he f ir st newl y cr eat ed socket , and
socket2 is t he f il e var iabl e t o be associat ed wit h t he second socket .
As in socket, domain is t he pr ot ocol f amil y t o use, type is t he t ype of socket t o cr eat e,
and format is t he number of t he pr ot ocol t o be used wit h t he socket .
socketpair of t en is used t o cr eat e a bidir ect ional communicat ion channel bet ween a
par ent and a chil d pr ocess.
Some machines t hat suppor t socket s do not suppor t
socketpair
The getsockopt and setsockopt Functions
The getsockopt and setsockopt f unct ions enabl e you t o obt ain and set socket opt ions.
To obt ain t he cur r ent val ue of a socket opt ion in your envir onment , cal l t he
getsockopt f unct ion.
The synt ax of t he getsockopt f unct ion is
retval = getsockopt (socket, opttype, optname);
socket is t he f il e var iabl e associat ed wit h t he socket whose opt ion you want t o r et r ieve.
opttype is t he t ype of opt ion (or opt ion l evel ). The val ue of t he syst em const ant
SOL_SOCKET specif ies a "socket l evel " opt ion. To f ind out t he ot her possibl e val ues f or
opttype, r ef er t o t he syst em header f il e /usr/include/sys/socket.h.
optname is t he name of t he opt ion whose val ue is t o be r et r ieved; retval is t he val ue of
t his opt ion.
To set a socket opt ion, cal l setsockopt.
The synt ax of t he setsockopt f unct ion is
setsockopt (socket, opttype, optname, value);
Her e, socket, opttype, and optname ar e t he same as in getsockopt, and value is t he new
val ue of t he optname opt ion.
NOTE
Socket opt ions ar e syst em dependent (and a f ul l
t r eat ment of t hem is beyond t he scope of t his book). For
mor e inf or mat ion on socket opt ions, r ef er t o t he
getsockopt and setsockopt manual pages on your
machine or t o t he /usr/include/sys/socket.h header
f il e
The getsockname and getpeername Functions
The getsockname and getpeername f unct ions enabl e you t o r et r ieve t he addr esses of t he
t wo ends of a socket connect ion.
The getsockname f unct ion r et ur ns t he addr ess of t his end of a socket connect ion (t he
end cr eat ed by t he cur r ent l y r unning pr ogr am).
The synt ax of t he getsockname f unct ion is
retval = getsockname (socket);
As in t he ot her socket f unct ions, socket is t he f il e var iabl e associat ed wit h a par t icul ar
socket . retval is t he r et ur ned addr ess.
The r et ur ned addr ess is in packed f or mat as buil t by t he cal l s t o pack in List ing 15.11
and List ing 15.12.
The f ol l owing code r et r ieves a socket addr ess and conver t s it int o r eadabl e f or m:
$rawaddr = getsockname (SOCKET);
($d1, $d2, @addrbytes) = unpack ("SnC4x8", $rawaddr);
$readable = join (".", @addrbytes);
NOTE
Nor mal l y, you al r eady have t he addr ess r et ur ned by
getsockname because you need t o pass it t o bind t o
associat e t he socket wit h your machine
To r et r ieve t he addr ess of t he ot her end of t he socket connect ion, cal l getpeername.
The synt ax of t he getpeername f unct ion is
retval = getpeername (socket);
As in getsockname, socket is t he f il e var iabl e associat ed wit h t he socket , and retval is
t he r et ur ned addr ess.
NOTE
The addr ess r et ur ned by getpeername is nor mal l y
ident ical t o t he addr ess r et ur ned by accept
The UNIX System V IPC Functions
The f unct ions you've just seen descr ibe int er pr ocess communicat ion using socket s.
Socket s ar e suppor t ed on machines r unning t he 4.3BSD (Ber kel ey UNIX) oper at ing syst em
and on some ot her UNIX oper at ing syst ems as wel l .
Some machines t hat do not suppor t socket s suppor t a set of UNIX Syst em V int er pr ocess
communicat ion (IPC) f unct ions. These f unct ions consist of t he f ol l owing:
G Funct ions t hat send messages f r om one pr ocess t o anot her by means of a message
queue
G Funct ions t hat cr eat e and manipul at e shar ed memor y
G Funct ions t hat cr eat e and manipul at e semaphor es
Per l enabl es you t o use t hese IPC f unct ions by def ining Per l f unct ions wit h t he same
names as t he IPC f unct ions. The f ol l owing sect ions pr ovide a br ief descr ipt ion of t hese
f unct ions.
For mor e inf or mat ion on any IPC f unct ion, r ef er t o t he manual page f or t hat f unct ion.
IPC Functions and the require Statement
Bef or e you can use any Syst em V IPC f unct ions, you f ir st must give t he pr ogr am t he
inf or mat ion it needs t o use t hem.
To do t his, add t he f ol l owing st at ement s t o your pr ogr am, immediat el y f ol l owing t he
#!/usr/local/bin/perl header l ine:
require "ipc.ph";
require "msg.ph";
require "sem.ph";
require "shm.ph";
The require st at ement is l ike t he #include st at ement in t he C pr epr ocessor : it t akes t he
cont ent s of t he specif ied f il e and incl udes t hem as par t of your pr ogr am.
The synt ax f or t he require st at ement is
require "name";
Her e, name is t he name of t he f il e t o be added t o your pr ogr am.
For exampl e, t he f ol l owing st at ement incl udes t he f il e ipc.ph as par t of your pr ogr am:
require "ipc.ph";
NOTE
If t he Per l int er pr et er compl ains t hat it cannot f ind a
f il e t hat you ar e t r ying t o incl ude using require, one of
t wo t hings is wr ong:
G The buil t -in ar r ay var iabl e @INC is not def ined
pr oper l y.
G The f il e does not exist .
See t he descr ipt ion of @INC on Day 17, "Syst em
Var iabl es," f or mor e det ail s
The msgget Function
To use t he Syst em V message-passing f acil it y, t he f ir st st ep is t o cr eat e a message queue
ID t o r epr esent a par t icul ar message queue. To do t his, cal l t he msgget f unct ion.
The synt ax of t he msgget f unct ion is
msgid = msgget (key, flag);
Her e, key is eit her IPC_PRIVATE or an ar bit r ar y const ant . If key is IPC_PRIVATE or flag
has IPC_CREAT set , t he message queue is cr eat ed, and it s queue ID is r et ur ned in msgid.
If msgget is unabl e t o cr eat e t he message queue, msgid is set t o t he nul l st r ing.
The msgsnd Function
To send a message t o a message queue, cal l t he msgsnd f unct ion.
The synt ax of t he msgsnd f unct ion is
msgsnd (msgid, message, flags);
msgid is t he message queue ID r et ur ned by msgget. message is t he t ext of t he message, and
flags specif ies opt ions t hat af f ect t he message.
msgsnd r et ur ns a nonzer o val ue if t he send oper at ion succeeds, zer o if an er r or occur s.
For mor e inf or mat ion on t he f or mat of t he message sent by msgsnd, r ef er t o your msgsnd
manual page.
The msgrcv Function
To obt ain a message f r om a message queue, cal l t he msgrcv f unct ion.
The synt ax of t he msgrcv f unct ion is
msgrcv (msgid, message, size, mesgtype, flags);
Her e, msgid is t he ID of t he message queue, as r et ur ned by msgget. message is a scal ar
var iabl e (or ar r ay el ement ) in which t he message is t o be st or ed. size is t he size of t he
message, pl us t he size of t he message t ype; t his message t ype is specif ied in mesgtype. flags
specif ies opt ions t hat af f ect t he message.
msgrcv r et ur ns a nonzer o val ue if t he send oper at ion succeeds, zer o if an er r or occur s.
The msgctl Function
The msgctl f unct ion enabl es you t o set opt ions f or message queues and send commands
t hat af f ect t hem.
The synt ax of t he msgctl f unct ion is
msgctl (msgid, msgcmd, msgarg);
msgid is t he message queue ID. msgcmd is t he command t o be sent t o t he message queue; t he
l ist of avail abl e commands is def ined in t he f il e /usr/include/sys/ipc.h.
Some of t he commands t hat can be specif ied by msgcmd set t he val ues of message queue
opt ions. If one of t hese commands is specif ied, t he new val ue of t he opt ion is specif ied in
msgarg.
If an er r or occur s, msgctl r et ur ns t he undef ined val ue. msgctl al so can r et ur n zer o or a
nonzer o val ue.
The shmget Function
To use t he Syst em V shar ed memor y capabil it y, you must f ir st cr eat e t he shar ed memor y.
To do t his, cal l t he shmget f unct ion.
The synt ax of t he shmget f unct ion is
shmid = shmget (key, size, flag);
Her e, key is eit her IPC_PRIVATE or an ar bit r ar y const ant . If key is IPC_PRIVATE or flag
has IPC_CREAT set , t he shar ed memor y segment is cr eat ed, and it s ID is r et ur ned in shmid.
size is t he size of t he cr eat ed shar ed memor y (in byt es). If shmget is unabl e t o cr eat e t he
message queue, shmid is set t o t he nul l st r ing.
The shmwrite Function
To send dat a t o a par t icul ar segment of shar ed memor y, cal l t he shmwrite f unct ion.
The synt ax of t he shmwrite f unct ion is
shmwrite (shmid, text, pos, size);
shmid is t he shar ed memor y ID r et ur ned by shmget. text is t he char act er st r ing t o wr it e
t o t he shar ed memor y, pos is t he number of byt es t o skip over in t he shar ed memor y
bef or e wr it ing t o it , and size is t he number of byt es t o wr it e.
This f unct ion r et ur ns a nonzer o val ue if t he wr it e oper at ion succeeds; it r et ur ns zer o if
an er r or occur s.
NOTE
If t he char act er st r ing specif ied by text is l onger t han
t he val ue specif ied by size, onl y t he f ir st size byt es of
t ext ar e wr it t en t o t he shar ed memor y.
If t he char act er st r ing specif ied by text is shor t er t han
t he val ue specif ied by size, shmwrite f il l s t he l ef t over
space wit h nul l char act er s
The shmread Function
To obt ain dat a f r om a segment of shar ed memor y, cal l t he shmread f unct ion.
The synt ax of t he shmread f unct ion is
shmread (shmid, retval, pos, size);
Her e, shmid is t he shar ed memor y ID r et ur ned by shmget. retval is a scal ar var iabl e (or
ar r ay el ement ) in which t he r et ur ned dat a is t o be st or ed. pos is t he number of byt es t o
skip in t he shar ed memor y segment bef or e copying t o retval, and size is t he number of
byt es t o copy.
This f unct ion r et ur ns a nonzer o val ue if t he r ead oper at ion succeeds, and it r et ur ns
zer o if an er r or occur s.
The shmctl Function
The shmctl f unct ion enabl es you t o set opt ions f or shar ed memor y segment s and send
commands t hat af f ect t hem.
The synt ax of t he shmctl f unct ion is
shmctl (shmid, shmcmd, shmarg);
shmid is t he shar ed memor y ID r et ur ned by shmget. shmcmd is t he command t hat af f ect s
t he shar ed memor y; t he l ist of avail abl e commands is def ined in t he header f il e named
/usr/include/sys/ipc.h.
Some of t he commands t hat can be specif ied by shmcmd set t he val ues of shar ed memor y
opt ions. If one of t hese commands is specif ied, t he new val ue of t he opt ion is specif ied in
shmarg.
If an er r or occur s, shmctl r et ur ns t he undef ined val ue. shmctl al so can r et ur n zer o or a
nonzer o val ue.
The semget Function
To use t he Syst em V semaphor e f acil it y, you must f ir st cr eat e t he semaphor e. To do t his,
cal l t he semget f unct ion.
The synt ax of t he semget f unct ion is
semid = semget (key, num, flag);
Her e, key is eit her IPC_PRIVATE or an ar bit r ar y const ant . If key is IPC_PRIVATE or flag
has IPC_CREAT set , t he shar ed memor y segment is cr eat ed, and it s ID is r et ur ned in semid.
num is t he number of semaphor es cr eat ed. If semget is unabl e t o cr eat e t he semaphor e,
semid is set t o t he nul l st r ing.
The semop Function
To per f or m a semaphor e oper at ion, cal l t he semop f unct ion.
The synt ax of t he semop f unct ion is
semop (semid, semstructs);
Her e, semid is t he semaphor e ID r et ur ned by semget, and semstructs is a char act er st r ing
consist ing of an ar r ay of semaphor e st r uct ur es. Each semaphor e st r uct ur e consist s of
t he f ol l owing component s, each of which is a shor t int eger (as cr eat ed by t he s f or mat
char act er in pack):
G The number of semaphor es
G The semaphor e oper at ion
G The semaphor e f l ags, if any
This f unct ion r et ur ns a nonzer o val ue if t he semaphor e oper at ion is successf ul , zer o if
an er r or occur s.
NOTE
For mor e inf or mat ion on semaphor e oper at ions and t he
semaphor e st r uct ur e, r ef er t o t he semop manual page
The semctl Function
The semctl f unct ion enabl es you t o set opt ions f or semaphor es and send commands t hat
af f ect t hem.
The synt ax of t he semctl f unct ion is
semctl (semid, semcmd, semarg);
semid is t he semaphor e ID r et ur ned by semget. semcmd is t he command t hat af f ect s t he
semaphor e; t he l ist of avail abl e commands is def ined in t he f il e /usr/include/sys/ipc.h.
Some of t he commands t hat can be specif ied by semcmd set t he val ues of semaphor e
opt ions. If one of t hese commands is specif ied, t he new val ue of t he opt ion is specif ied in
semarg.
If an er r or occur s, semctl r et ur ns t he undef ined val ue. semctl al so can r et ur n zer o or a
nonzer o val ue.
Summary
Today you l ear ned about Per l f unct ions t hat emul at e syst em l ibr ar y f unct ions, per f or m
Ber kel ey UNIX socket oper at ions, and per f or m Syst em V IPC oper at ions.
Per l f unct ions t hat emul at e syst em l ibr ar y f unct ions per f or m t he f ol l owing t asks,
among ot her s:
G Read t he /etc/group f il e, which l ist s t he user gr oups f or your machine
G Read t he /etc/networks f il e, which l ist s net wor ks t o which your machine is
connect ed
G Read f r om t he /etc/hosts f il e, which l ist s t he r emot e machines accessibl e f r om
your l ocal net wor k
G Obt ain t he cur r ent l ogin user ID
G Ret r ieve t he cur r ent pr ocess gr oup and par ent pr ocess ID
G Read t he /etc/passwd f il e, which l ist s inf or mat ion about t he user s who have
access t o your machine
G Obt ain t he cur r ent pr ior it y f or your pr ogr am and set it t o anot her val ue
G Read t he /etc/protocols f il e, which l ist s t he t ypes of pr ot ocol s avail abl e f or
int er pr ocess communicat ion
G Read t he /etc/services f il e, which l ist s t he por t number s associat ed wit h syst em
ser vices on your machine
Today you al so l ear ned about t he Ber kel ey UNIX socket mechanism, which pr ovides
int er pr ocess communicat ion using a cl ient -ser ver model . The Syst em V IPC message
queue, shar ed memor y, and semaphor e capabil it ies ar e al so br ief l y cover ed.
Q&A
Q: What is t he dif f er ence bet ween getnetent and gethostent, and which one
accesses /etc/networks?
A: On most syst ems, getnetent accesses t he cont ent s of /etc/networks, which l ist s
t he names and number s of t he net wor ks f or your machine. gethostent, on t he
ot her hand, accesses t he cont ent s of /etc/hosts, which l ist s t he names and
addr esses of ot her machines on l ocal and r emot e net wor ks.
Q: What wil l happen if I est abl ish a socket connect ion using a por t number
l ist ed in /etc/services?
A: If t he syst em ser vice is al ways act ive, t he syst em l ikel y wil l not enabl e you t o
est abl ish a socket connect ion using t his por t . If t he syst em ser vice r uns
int er mit t ent l y, you r un t he r isk of disr upt ing it .
In your pr ogr ams, it is al ways best t o use a por t never used by any ot her syst em
ser vice.
Q: How did socket s get t heir name?
A: A ser ver pr ocess t hat is l ist ening f or cl ient s is l ike an el ect r ical socket on your
wal l : any cl ient pr ocess wit h t he appr opr iat e pr ot ocol can "pl ug int o" it .
Q: What is t he pur pose of a semaphor e?
A: A semaphor e is a met hod of ensur ing t hat onl y one pr ocess can r un a par t icul ar
segment of code or access a par t icul ar chunk of shar ed memor y st or age at any
given t ime.
A f ul l descr ipt ion of how semaphor es wor k is beyond t he scope of t his book. Many
books on oper at ing syst ems can give you an int r oduct ion t o t he concept s used in
semaphor es. Al so, t he UNIX Syst em V manual pages f or t he semaphor e f unct ions
l ist ed in t oday's l esson pr ovide a br ief descr ipt ion of how semaphor es wor k.
Q: The machine name I r et r ieved using gethostbyaddr has a l ot of f unny
char act er s in it . Why?
A: The addr ess you've r et r ieved is an Int er net domain addr ess, which is a l ist of
names separ at ed by per iods (.). These domain names ensur e t hat each Int er net
user and machine can be dist inguished f r om t he mil l ions of ot her user s and
machines ar ound t he wor l d.
For mor e det ail s on t he Int er net and how t o use it , r ef er t o a book on t he subject
(many ar e avail abl e).
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed, and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. Which f unct ions manipul at e t he f ol l owing f il es?
a. /etc/passwd
b. /etc/hosts
c. /etc/networks
d. /etc/services
2. Which of t he f ol l owing f unct ions ar e cal l ed by cl ient pr ocesses and which by
ser ver pr ocesses when per f or ming socket oper at ions? In what or der shoul d t hese
f unct ions be cal l ed?
a. Bind
b. listen
c. socket
d. accept
e. connect
3. What do t he f ol l owing f unct ions do?
a. getpwuid
b. setprotoent
c. gethostbyaddr
d. getgrent
e. getservbyport
4. How do you send inf or mat ion using a socket ?
5. Descr ibe how t o l ist al l t he (numer ic) user IDs on your machine.
Exercises
1. Wr it e a pr ogr am t hat l ist s (by name) al l t he gr oups int o which user IDs ar e sor t ed
on your machine. List al l t he user names in each gr oup. Sor t t he gr oups, and t he
user names in each gr oup, in al phabet ical or der .
2. Wr it e a pr ogr am t hat l ist s ever y user name on your machine and pr int s t he home
dir ect or y f or each.
3. Wr it e a pr ogr am t hat l ist s t he shel l s used by user s on your machine. List t he
number of user s of each shel l , and sor t t he l ist in descending or der of use.
4. Wr it e a pr ogr am t hat spl it s int o t wo ident ical pr ocesses, and have each pr ocess
pr int t he pr ocess ID of t he ot her .
5. Wr it e a pr ogr am t hat sends a specif ic f il e, /u/jqpublic/testfile, t o cl ient s who
r equest it . The pr ogr am shoul d send t he f il e by cr eat ing a copy of it sel f using
fork, and it shoul d be abl e t o send t o f ive cl ient s at once.
6. BUG BUSTER: What is wr ong wit h t he f ol l owing pr ogr am?
#!/usr/local/bin/perl
print ("Network names and numbers at your site:\n");
while (($name, $d1, $d2, $address) = getnetent()) {
print ("$name, at address $address\n");
}

Chapter 16
Command-Line Options
CONTENTS
G Specif ying Opt ions
H Specif ying Opt ions on t he Command Line
H Specif ying an Opt ion in t he Pr ogr am
G The -v Opt ion: Pr int ing t he Per l Ver sion Number
G The -c Opt ion: Checking Your Synt ax
G The -w Opt ion: Pr int ing War nings
H Checking f or Possibl e Typos
H Checking f or Redef ined Subr out ines
H Checking f or Incor r ect Compar ison Oper at or s
G The -e Opt ion: Execut ing a Singl e-Line Pr ogr am
G The -s Opt ion: Suppl ying Your Own Command-Line Opt ions
H The -s Opt ion and Ot her Command-Line Ar gument s
G The -P Opt ion: Using t he C Pr epr ocessor
H The C Pr epr ocessor : A Quick Over view
G The -I Opt ion: Sear ching f or C Incl ude Fil es
G The -n Opt ion: Oper at ing on Mul t ipl e Fil es
G The -p Opt ion: Oper at ing on Fil es and Pr int ing
G The -i Opt ion: Edit ing Fil es
H Backing Up Input Fil es Using t he -i Opt ion
G The -a Opt ion: Spl it t ing Lines
G The -F Opt ion: Specif ying t he Spl it Pat t er n
G The -0 Opt ion: Specif ying Input End-of -Line
G The -l Opt ion: Specif ying Out put End-of -Line
G The -x Opt ion: Ext r act ing a Pr ogr am f r om a Message
G Miscel l aneous Opt ions
H The -u Opt ion
H The -U Opt ion
H The -S Opt ion
H The -D Opt ion
H The -T Opt ion: Wr it ing Secur e Pr ogr ams
G The -d Opt ion: Using t he Per l Debugger
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson descr ibes t he opt ions you can specif y t o cont r ol how your Per l pr ogr am
oper at es. These opt ions pr ovide many f eat ur es, incl uding t hose t hat per f or m t he
f ol l owing t asks:
G Check synt ax
G Pr int war nings
G Use pr epr ocessor commands
G Fil e edit ing
G Change t he "end of input l ine" mar ker
Today's l esson begins wit h a descr ipt ion of how t o suppl y opt ions t o your Per l pr ogr am.
Specifying Options
Ther e ar e t wo ways t o suppl y opt ions t o a Per l pr ogr am:
G On t he command l ine, when you ent er t he command t hat st ar t s your Per l pr ogr am
G On t he f ir st l ine of your Per l pr ogr am
The f ol l owing sect ions descr ibe t hese met hods of suppl ying opt ions.
Specifying Options on the Command Line
One way t o specif y opt ions f or a Per l pr ogr am is t o ent er t hem on t he command l ine when
you ent er t he command t hat st ar t s your pr ogr am.
The synt ax f or specif ying opt ions on t he command l ine is
perl options program
Her e, program is t he name of t he Per l pr ogr am you want t o r un, and options is t he l ist of
opt ions you want t o suppl y t o t he pr ogr am.
For exampl e, t he f ol l owing command r uns t he Per l pr ogr am named test1 and passes it
t he opt ions -s and -w. (You'l l l ear n about t hese and ot her opt ions l at er t oday.)
$ perl -s -w test1
Some opt ions need t o be specif ied al ong wit h a val ue. For exampl e, t he -0 opt ion r equir es
an int eger t o be passed wit h it :
$ perl -0 26 test1
Her e, t he int eger 26 is associat ed wit h t he opt ion -0.
If you want , you can omit t he space bet ween t he opt ion and it s associat ed val ue, as in
t he f ol l owing:
$ perl -026 test1
As bef or e, t his command associat es 26 wit h t he -0 opt ion. In eit her case, t he val ue
associat ed wit h an opt ion must al ways immediat el y f ol l ow t he opt ion.
NOTE
If an opt ion does not r equir e an associat ed val ue, you
can put anot her opt ion immediat el y af t er it wit hout
specif ying an addit ional - char act er or space. For
exampl e, t he f ol l owing commands ar e equival ent :
$ perl -s -w test1
$ perl -sw test1
You can put an opt ion t hat r equir es a val ue as par t of a
gr oup of opt ions, pr ovided t hat it is l ast in t he gr oup. For
exampl e, t he f ol l owing commands ar e equival ent :
$ perl -s -w -0 26 test1
$ perl -sw026 test
Specifying an Option in the Program
Anot her way t o specif y a command opt ion is t o incl ude it as par t of t he header comment
f or t he pr ogr am. For exampl e, suppose t hat t he f ir st l ine of your Per l pr ogr am is t his:
#!/usr/local/bin/perl -w
In t his case, t he -w opt ion is aut omat ical l y specif ied when you st ar t t he pr ogr am.
Per l 4 enabl es you t o specif y onl y one opt ion (or gr oup
of opt ions) on t he header comment l ine. This means t hat
t he f ol l owing l ine gener at es an "unr ecognized swit ch"
er r or message:
#!/usr/local/bin/perl -w -s
Per l 5 enabl es as many swit ches as you l ike on t he
command l ine. However , some oper at ing syst ems chop t he
header l ine af t er 32 char act er s, so be car ef ul if you ar e
pl anning t o use a l ar ge number of swit ches
NOTE
Opt ions specif ied on t he command l ine over r ide opt ions
specif ied in t he header comment . For exampl e, if your
header comment is
#!/usr/local/bin/perl -w
and you st ar t your pr ogr am wit h t he command
$ perl -s test1
t he pr ogr am wil l r un wit h t he -s opt ion specif ied but
not t he -w opt ion
The -v Option: Printing the Perl Version Number
The -v opt ion enabl es you t o f ind out what ver sion of Per l is r unning on your machine.
When t he Per l int er pr et er sees t his opt ion, it pr int s inf or mat ion on it sel f and t hen exit s
wit hout r unning your pr ogr am.
This means t hat if you suppl y a command such as t he f ol l owing, t he f il e test1 is not
execut ed:
$ perl -v test1
Her e is sampl e out put f r om t he -v command:
This is perl, version 5.001
Unofficial patch level 1m
Copyright (c) 1987-1994, Larry Wall
Perl may be copied only under the terms of either the Artistic License
or the GNU General Public License, which may be found in the Perl 5.0
source kit.
The onl y r eal l y usef ul t hings her e, besides t he copyr ight not ice, ar e t he ver sion number
of t he Per l you ar e r unning-in t his case, 4.0-and t he pat ch l evel , which indicat es how
many r epair s, or pat ches, have been made t o t his ver sion. Her e, t he pat ch l evel is 36
(which, at t his wr it ing, is t he l at est r el ease of Per l ver sion 4.0).
No ot her opt ions shoul d be specif ied if you specif y t he -v opt ion, because none of t hem
woul d do anyt hing in t his case anyway.
The -c Option: Checking Your Syntax
The -c opt ion t el l s t he Per l int er pr et er t o check whet her your Per l pr ogr am is cor r ect
wit hout act ual l y r unning it . If it is cor r ect , t he Per l int er pr et er pr int s t he f ol l owing
message (in which filename is t he name of your pr ogr am) and t hen exit s wit hout
execut ing your pr ogr am:
filename syntax OK
If t he Per l int er pr et er det ect s er r or s, it displ ays t hem just as it nor mal l y does. Af t er
pr int ing t he er r or messages, it pr int s t he f ol l owing message, in which filename is t he
name of your pr ogr am:
filename had compilation errors
Again, t her e is no point in suppl ying ot her opt ions if you specif y t he -c opt ion because
t he Per l int er pr et er isn't act ual l y r unning t he pr ogr am; t he onl y except ion is t he -w
opt ion, which pr int s war nings. This opt ion is descr ibed in t he f ol l owing sect ion.
The -w Option: Printing Warnings
As you have seen on t he pr eceding days, some mist akes ar e easy t o make when you ar e
wr it ing a Per l pr ogr am, such as accident al l y t yping t he wr ong var iabl e name, or using
== when you r eal l y mean t o use eq. Because cer t ain mist akes cr op up f r equent l y, t he
Per l int er pr et er pr ovides an opt ion t hat checks f or t hem.
This opt ion, t he -w opt ion, pr int s a war ning ever y t ime t he Per l int er pr et er sees
somet hing t hat might cause a pr obl em. For exampl e, if t he int er pr et er sees t he st at ement
$y = $x;
and hasn't seen $x bef or e (which means t hat $x is undef ined), it pr int s a war ning message
in t he f ol l owing f or m if you ar e r unning Per l 4:
Possible typo: "x" at filename line linenum.
Her e, filename is t he name of your Per l pr ogr am, and linenum is t he number of t he l ine
on which t he int er pr et er has det ect ed a pot ent ial pr obl em.
If you ar e r unning Per l 5, t he message is simil ar , but al so incl udes t he name of t he
cur r ent package:
Identifier "main::x" used only once: possible typo at filename line
linenum.
For mor e inf or mat ion on packages, see Day 19, "Object -Or ient ed Pr ogr amming in Per l ."
The f ol l owing sect ions pr ovide a par t ial l ist of t he pot ent ial pr obl ems det ect ed by t he -
w opt ion. (If you ar e r unning Per l 5, t he -w opt ion pr ovides dozens of usef ul war nings.
Consul t t he Per l manual pages f or a compl et e l ist .)
NOTE
The -w opt ion can be combined wit h t he -c opt ion t o
pr ovide a means of checking your synt ax f or er r or s and
pr obl ems bef or e you act ual l y r un t he pr ogr am
Checking for Possible Typos
As you have seen, a st at ement such as t he f ol l owing one l eads t o a war ning message if $x
has not been pr eviousl y def ined:
$y = $x;
The "possibl e t ypo" er r or message al so appear s in t he f ol l owing cir cumst ances, among
ot her s:
G If a var iabl e is assigned t o but is never used again
G If a f il e var iabl e is r ef er r ed t o wit hout being specif ied in an open st at ement
Of cour se, t he possibl e-t ypo message might f l ag l ines t hat don't act ual l y cont ain t ypos.
Fol l owing ar e t wo of t he most common sit uat ions in which a possibl e t ypo act ual l y is
cor r ect code:
G The Per l 4 int er pr et er somet imes conf uses a pr int f or mat specif ier wit h a f il e
var iabl e and cl aims t hat t he name of t he pr int f or mat specif ier is a possibl e t ypo.
For exampl e, t he st at ement
format BLANK =
.
G (which enabl es you t o pr int a bl ank l ine on a f or mat t ed page) might gener at e t he
war ning message
Possible typo: "BLANK" at file1 line 26.
G This war ning message might appear even if t he pr int f or mat is act ual l y used in t he
pr ogr am, because it is specif ied by a st at ement such as
$~ = "BLANK";
G and t he Per l int er pr et er doesn't r eal ize t hat t he st r ing BLANK r ef er s t o t he BLANK
pr int f or mat .
G The Per l 5 int er pr et er does not gener at e t his war ning message.
G If you cal l a f unct ion t hat r et ur ns a l ist , and you need onl y an el ement of t he
l ist , one way t o ext r act t hat singl e el ement is t o assign t he ot her el ement s t o
dummy var iabl es. For exampl e, if you want t o r et r ieve just t he gr oup ID when you
cal l getgrnam, you can do so as shown her e:
($d1, $d2, $groupid) = getgrnam ($groupname);
G Her e, t he scal ar var iabl es $d1 and $d2 ar e dummy var iabl es t hat hol d t he
el ement s of t he gr oup f il e ent r y t hat you do not need. If (as is l ikel y) $d1 and $d2
ar e not r ef er r ed t o again, t he -w opt ion t r eat s $d1 and $d2 as possibl e t ypos.
Checking for Redefined Subroutines
One usef ul f eat ur e of t he -w opt ion is t hat it checks whet her t wo subr out ines of t he
same name have been def ined in t he pr ogr am. (Nor mal l y, if t he Per l int er pr et er sees t wo
subr out ines of t he same name, it quiet l y r epl aces t he f ir st subr out ine wit h t he second
one and car r ies on.)
If , f or exampl e, t wo subr out ines named x ar e def ined in a pr ogr am, t he -w opt ion pr int s a
message simil ar t o t he f ol l owing one:
Subroutine x redefined at file1 line 46.
The l ine number specif ied is t he l ine t hat st ar t s t he second subr out ine.
When t he -w opt ion has det ect ed t his pr obl em, you can decide which subr out ine t o
r ename or t hr ow away.
Checking for Incorrect Comparison Operators
Anot her r eal l y hel pf ul f eat ur e of t he -w opt ion is t hat it checks whet her you ar e
t r ying t o compar e a st r ing using t he == oper at or .
In a st at ement such as t he f ol l owing:
if ($x == "humbug") {
...
}
t he condit ional expr ession
$x == "humbug"
is equival ent t o t he expr ession
$x == 0
because al l char act er st r ings ar e conver t ed t o 0 when used in a numer ic cont ext (a
pl ace wher e a number is expect ed). This is cor r ect in Per l , but it is not l ikel y t o be what
you want .
If t he -w opt ion is specif ied and t he Per l int er pr et er sees a st at ement such as t his one, it
pr int s a message simil ar t o t he f ol l owing if you ar e r unning Per l 4:
Possible use of == on string value at file1 line 26.
In Per l 5, t he f ol l owing war ning is pr int ed:
Argument "humbug" isn't numeric for numeric eq at file1 line 26.
In eit her case, t his war ning enabl es you det ect t hese incor r ect == oper at or s and r epl ace
t hem wit h eq oper at or s, which compar e st r ings.
The -w oper at or doesn't det ect t he opposit e pr obl em,
namel y:
if ($x eq 46) {
...
}
In t his case, t he Per l int er pr et er conver t s 46 t o t he
st r ing 46 and per f or ms a st r ing compar ison.
Because a number and it s st r ing equival ent usual l y
mean t he same t hing, t his nor mal l y doesn't cause a
pr obl em. Wat ch out , t hough, f or oct al number s in st r ing
compar isons, as in t he f ol l owing exampl e:
if ($x eq 046) {
...
}
Her e, t he oct al val ue 046 is conver t ed t o t he number 38
bef or e being conver t ed t o a st r ing. If you r eal l y want t o
compar e $x t o 046, t his code wil l not pr oduce t he r esul t s
you expect .
Anot her t hing t o wat ch out f or is t his: In Per l 4, t he -w
opt ion does not check f or condit ional expr essions such as
t he f ol l owing:
if ($x = 0) {
...
}
because t her e ar e many cases in Per l in which t he =
assignment oper at or bel ongs inside a condit ional
expr ession. You wil l have t o manual l y check t hat you
ar e not specif ying = (assignment ) when you r eal l y mean
t o use == (equal it y compar ison).
Per l 5 f l ags t his wit h t he f ol l owing message:
Found = in conditional, should be == at filename
line filenum
The -e Option: Executing a Single-Line Program
The -e opt ion enabl es you t o execut e a Per l pr ogr am f r om your shel l command l ine. For
exampl e, t he command
$ perl -e "print ('Hello');"
pr int s t he f ol l owing st r ing on your scr een:
Hello
You can al so specif y mul t ipl e -e opt ions. In t his case, t he Per l st at ement s ar e execut ed
l ef t t o r ight . For exampl e, t he command
$ perl -e "print ('Hello');" -e "print (' there');"
pr int s t he f ol l owing st r ing on your scr een:
Hello there
By it sel f , t he -e opt ion is not al l t hat usef ul . It becomes usef ul , however , when you use
it in conjunct ion wit h some of t he ot her opt ions you'l l see in t oday's l esson.
You can l eave of f t he cl osing semicol on in a Per l
st at ement passed via t he -e opt ion, if you want t o:
$ perl -e "print ('Hello')"
If you ar e suppl ying t wo or mor e -e opt ions, however , t he
Per l int er pr et er st r ings t hem t oget her and t r eat s t hem
as t hough t hey ar e a singl e Per l pr ogr am. This means
t hat t he f ol l owing command gener at es an er r or because
t her e must be a semicol on af t er t he st at ement specif ied
wit h t he f ir st -e opt ion:
$ perl -e "print ('Hello')" -e "print (' there')
The -s Option: Supplying Your Own Command-Line Options
As you can see f r om t his chapt er , you can cont r ol t he behavior of Per l by specif ying
var ious command-l ine opt ions. You can cont r ol t he behavior of your own Per l pr ogr ams
by spec-if ying command-l ine opt ions f or t hem t oo. To do t his, specif y t he -s opt ion when
you cal l t he pr ogr am.
Her e's an exampl e of a command t hat passes an opt ion t o a Per l pr ogr am:
$ perl -s testfile -q
This command st ar t s t he Per l pr ogr am testfile and passes it t he -q opt ion.
To be abl e t o pass opt ions t o your pr ogr am, you must
specif y t he Per l -s opt ion. The f ol l owing command does
not pass -q as an opt ion:
$ perl testfile -q
In t his case, -q is just an or dinar y ar gument t hat is
passed t o your pr ogr am and st or ed in t he buil t -in ar r ay
var iabl e @ARGV.
The easiest way t o r emember t o incl ude -s is t o specif y it
as par t of your header comment :
#!/usr/local/bin/perl -s
This ensur es t hat your pr ogr am al ways wil l check f or
opt ions. (Unl ess, of cour se, you over r ide t he opt ion check
by pr oviding ot her Per l opt ions on t he command l ine
when you invoke t he pr ogr am.
If an opt ion is specif ied when you invoke your Per l pr ogr am, t he scal ar var iabl e whose
name is t he same as t he opt ion is aut omat ical l y set t o 1 bef or e pr ogr am execut ion begins.
For exampl e, if a Per l pr ogr am named testfile is cal l ed wit h t he -q opt ion, as in t he
f ol l owing, t he scal ar var iabl e $q is aut omat ical l y set t o 1:
$ perl -s testfile -q
You t hen can use t his var iabl e in a condit ional expr ession t o t est whet her t he opt ion
has been set .
NOTE
If -q is t r eat ed as an opt ion, it does not appear in t he
syst em var iabl e @ARGV. A command-l ine ar gument eit her
set s an opt ion or is added t o @ARGV
Opt ions can be l onger t han a singl e char act er . For exampl e, t he f ol l owing command set s
t he val ue of t he scal ar var iabl e $potato t o 1:
$ perl -s testfile -potato
You al so can set an opt ion t o a val ue ot her t han 1 by specif ying = and t he desir ed val ue
on t he command l ine:
$ perl -s testfile -potato="hot"
This l ine set s t he val ue of $potato t o hot.
List ing 16.1 is a simpl e exampl e of a pr ogr am t hat uses command-l ine opt ions t o cont r ol
it s behavior . This pr ogr am pr int s inf or mat ion about t he user cur r ent l y l ogged in.

List ing 16.1. An exampl e of a pr ogr am t hat uses command-l ine opt ions.
1: #!/usr/local/bin/perl -s
2:
3: # This program prints information as specified by
4: # the following options:
5: # -u: print numeric user ID
6: # -U: print user ID (name)
7: # -g: print group ID
8: # -G: print group name
9: # -d: print home directory
10: # -s: print login shell
11: # -all: print everything (overrides other options)
12:
13: $u = $U = $g = $G = $d = $s = 1 if ($all);
14: $whoami = "whoami";
15: chop ($whoami);
16: ($name, $d1, $userid, $groupid, $d2, $d3, $d4,
17: $homedir, $shell) = getpwnam ($whoami);
18: print ("user id: $userid\n") if ($u);
19: print ("user name: $name\n") if ($U);
20: print ("group id: $groupid\n") if ($g);
21: if ($G) {
22: ($groupname) = getgrgid ($groupid);
23: print ("group name: $groupname\n");
24: }
25: print ("home directory: $homedir\n") if ($d);
26: print ("login shell: $shell\n") if ($s);

$ program16_1 -U -d
user name: dave
home directory: /ag1/dave
$
The header comment in l ine 1 specif ies t hat t he -s opt ion is t o be
aut omat ical l y specif ied when t his Per l pr ogr am is invoked. This ensur es t hat opt ions can
al ways be passed t o t his pr ogr am (unl ess, of cour se, you over r ide t he -s opt ion on t he
command l ine, as descr ibed ear l ier ).
The comment s in l ines 3-11 pr ovide inf or mat ion on what opt ions t he pr ogr am suppor t s.
This inf or mat ion is usef ul when someone is r eading or modif ying t he pr ogr am because
t her e is no ot her way t o t el l which scal ar var iabl es ar e used t o t est opt ions.
The opt ion -all indicat es t hat t he pr ogr am is t o pr int ever yt hing; if t his opt ion is
specif ied, t he scal ar var iabl e $all is set t o 1. To cut down on t he number of compar isons
l at er , l ine 13 checks whet her $all is 1; if it is, t he ot her scal ar var iabl es cor r esponding
t o command-l ine opt ions ar e set t o 1. This t echnique ensur es t hat t he f ol l owing
commands ar e equival ent (assuming t hat your pr ogr am is named program16_1):
$ program16_1 -all
$ program16_1 -u -U -g -G -d -s
The scal ar var iabl es l ist ed in l ine 13 can be assigned t o, even t hough t hey cor r espond t o
possibl e command-l ine opt ions, because t hey behave just l ike ot her Per l scal ar var iabl es.
Lines 14-17 pr ovide t he r aw mat er ial f or t he var ious pr int oper at ions in t his pr ogr am. To
st ar t , when t he Per l int er pr et er sees t he st r ing 'whoami', it cal l s t he syst em command
whoami, which r et ur ns t he name of t he user r unning t he pr ogr am. This name is t hen
passed t o getpwnam, which sear ches t he passwor d f il e /etc/passwd and r et r ieves t he
ent r y f or t his par t icul ar user .
Line 18 checks whet her t he -u opt ion has been specif ied. To do t his, it checks whet her $u
has a nonzer o val ue. If it does, t he user ID is pr int ed. (The user ID is al so pr int ed if -all
has been specif ied because l ine 13 set s $u t o a nonzer o val ue in t his case.)
Simil ar l y, l ine 19 pr int s t he user name if -U has been specif ied, l ine 20 pr int s t he gr oup ID
if -g has been specif ied, l ine 25 pr int s t he home dir ect or y if -d has been specif ied, and l ine
26 pr int s t he f il ename of t he l ogin shel l if -s has been specif ied.
Lines 21-24 check whet her t o pr int t he gr oup name. If -g has been specif ied, $g is nonzer o,
and l ine 22 cal l s getgrid t o r et r ieve t he gr oup name.
NOTE
Because command-l ine opt ions can change t he init ial
val ues of scal ar var iabl es, it is a good idea t o al ways
assign a val ue t o a scal ar var iabl e bef or e you use it .
Consider t he f ol l owing exampl e:
#!/usr/local/bin/perl
while ($count < 10) {
print ("$count\n");
$count++;
}
This pr ogr am nor mal l y pr int s t he number s f r om 0 t o 9
because $count is assumed t o have an init ial val ue of 0.
However , if t his pr ogr am is cal l ed wit h t he -count
opt ion, t he init ial val ue of $count becomes somet hing
ot her t han 0, and t he pr ogr am behaves dif f er ent l y.
If you add t he f ol l owing st at ement bef or e t he while
l oop, t he pr ogr am al ways pr int s t he number s 0 t o 9
r egar dl ess of what opt ions ar e specif ied on t he command
l ine:
$count = 0
The -s Option and Other Command-Line Arguments
You can suppl y bot h opt ions and command-l ine ar gument s t o your pr ogr am (pr ovided
t hat you suppl y t he -s opt ion t o Per l ). These ar e t he r ul es t hat t he Per l int er pr et er
f ol l ows:
G Any ar gument s immediat el y f ol l owing t he pr ogr am name t hat st ar t wit h a - ar e
assumed t o be opt ions.
G Any ar gument t hat does not st ar t wit h a - is assumed t o be an or dinar y ar gument
and not an opt ion.
G When t he Per l int er pr et er sees an ar gument t hat is not an opt ion, al l subsequent
ar gument s ar e al so t r eat ed as or dinar y ar gument s, not opt ions, even if t hey st ar t
wit h a -.
This means, f or exampl e, t hat t he f ol l owing command t r eat s -w as an opt ion t o testfile,
and foo and -e as or dinar y ar gument s:
$ perl -s testfile -w foo -e
The special ar gument -- al so indicat es "end of opt ions." For exampl e, t he f ol l owing
command t r eat s -w as an opt ion and -e as an or dinar y ar gument . The -- is t hr own away.
$ perl -s testfile -w - -e
The -P Option: Using the C Preprocessor
The C pr epr ocessor is a pr ogr am t hat t akes code wr it t en in t he C pr ogr amming l anguage
and sear ches f or special pr epr ocessor st at ement s. In Per l , t he -P opt ion enabl es you t o
use t his pr epr ocessor wit h your Per l pr ogr am:
$ perl -P myprog
Her e, t he Per l pr ogr am myprog is f ir st r un t hr ough t he C pr epr ocessor . The r esul t ing
out put is t hen passed t o t he Per l int er pr et er f or execut ion.
NOTE
Per l pr ovides no way t o just r un t he C pr epr ocessor on a
Per l pr ogr am. To do t his, you'l l need a C compil er t hat
pr ovides an opt ion which specif ies "pr epr ocessor onl y."
Ref er t o t he document at ion f or your C compil er f or
det ail s about how t o do t his
The f ol l owing sect ions descr ibe some of t he most commonl y used C pr epr ocessor
commands.
The C Preprocessor: A Quick Overview
C pr epr ocessor st at ement s al ways empl oy t he f ol l owing synt ax:
#command value
Each C pr epr ocessor st at ement st ar t s wit h a # char act er . command is t he pr epr ocessor
oper at ion t o per f or m, and value is t he (opt ional ) val ue associat ed wit h t his oper at ion.
Macro Substitution: The #define Operator
The most common pr epr ocessor st at ement is #define. This st at ement t el l s t he
pr epr ocessor t o r epl ace ever y occur r ence of a par t icul ar char act er st r ing wit h a
specif ied val ue.
The synt ax f or #define is
#define macro value
This st at ement r epl aces al l occur r ences of t he char act er st r ing macro wit h t he val ue
specif ied by value. This oper at ion is known as macro substitution. macro can cont ain l et t er s,
digit s, or under scor es.
The val ue specif ied in a #define st at ement can be any char act er st r ing or number . For
exampl e, t he f ol l owing st at ement r epl aces al l occur r ences of USERNAME wit h t he st r ing
"dave" (incl uding t he quot at ion mar ks):
#define USERNAME "dave"
This st at ement r epl aces EXPRESSION wit h t he st r ing (14+6), incl uding t he par ent heses:
#define EXPRESSION (14+6)
NOTE
When you ar e using #define wit h a val ue t hat is an
expr ession, it is usual l y a good idea t o encl ose t he val ue
in par ent heses. For exampl e, consider t he f ol l owing Per l
st at ement :
$result = EXPRESSION * 5;
If your pr epr ocessor command is
#define EXPRESSION 14+6
t he r esul t ing Per l st at ement becomes
$result = 14 + 6 * 5;
which assigns 44 t o $result (because t he mul t ipl icat ion is
per f or med f ir st ). If you encl ose t he pr epr ocessor
expr ession in par ent heses, as in
#define EXPRESSION (14+6)
t he st at ement becomes
$result = (14 + 6) * 5;
which yiel ds t he r esul t 100, which is l ikel y what you
want .
Al so, you al ways shoul d encl ose any par amet er s
(descr ibed in t he f ol l owing sect ion) in par ent heses, f or
t he same r eason
Passing Arguments Using #define
You can specif y one or mor e par amet er s wit h your #define st at ement . This capabil it y
enabl es you t o t r eat t he pr epr ocessor command l ike a simpl e f unct ion t hat accept s
ar gument s. For exampl e, t he f ol l owing pr epr ocessor st at ement t akes a specif ied val ue
and uses it as an exponent :
#define POWEROFTWO(val) (2 ** (val))
In t he Per l st at ement
$result = POWEROFTWO(1.3 + 2.6) + 4;
t he pr epr ocessor subst it ut es t he expr ession 1.3 + 2.6 f or val and pr oduces t his:
$result = (2 ** (1.3 + 2.6)) + 4;
You can suppl y mor e t han one par amet er wit h a #define st at ement . For exampl e,
consider t he f ol l owing st at ement :
#define EXPONENT (base, exp) ((base) ** (exp))
Now, t he st at ement
$result = EXPONENT(4, 11);
yiel ds t he f ol l owing r esul t af t er pr epr ocessing:
$result = ((4) ** (11));
The Per l int er pr et er ignor es t he ext r a par ent heses.
TIP
By convent ion, macr os def ined using #define nor mal l y
use al l upper case l et t er s (pl us occasional digit s and
under scor es). This makes it easier t o dist inguish macr os
f r om ot her var iabl e names or char act er st r ings
List ing 16.2 is an exampl e of a Per l pr ogr am t hat uses a #define st at ement t o per f or m
macr o subst it ut ion. This l ist ing is just List ing 15.4 wit h t he pr epr ocessor st at ement
added.

List ing 16.2. A pr ogr am t hat uses a #define st at ement .
1: #!/usr/local/bin/perl -P
2:
3: #define AF_INET 2
4: print ("Enter an Internet address:\n");
5: $machine = <STDIN>;
6: $machine =~ s/^\s+|\s+$//g;
7: @addrbytes = split (/\./, $machine);
8: $packaddr = pack ("C4", @addrbytes);
9: if (!(($name, $altnames, $addrtype, $len, @addrlist) =
10: gethostbyaddr ($packaddr, AF_INET))) {
11: die ("Address $machine not found.\n");
12: }
13: print ("Principal name: $name\n");
14: if ($altnames ne "") {
15: print ("Alternative names:\n");
16: @altlist = split (/\s+/, $altnames);
17: for ($i = 0; $i < @altlist; $i++) {
18: print ("\t$altlist[$i]\n");
19: }
20: }

$ program16_2
Enter an Internet address:
128.174.5.59
Principal name: ux1.cso.uiuc.edu
$
Line 3 def ines t he macr o AF_INET and assigns it t he val ue 2. When t he C
pr epr ocessor sees AF_INET in l ine 10, it r epl aces it wit h 2, which is t he val ue of AF_INET
on t he cur r ent machine (as specif ied in t he header f il e /usr/include/netdb.h or
/usr/include/bsd/netdb.h).
If t his pr ogr am is moved t o a machine t hat def ines a dif f er ent val ue f or AF_INET, al l you
need t o do t o get t his pr ogr am t o wor k is change l ine 3 t o use t he val ue on t hat
machine.
Using Macros in #define Statements
You can use a pr eviousl y def ined macr o as t he val ue in anot her #define st at ement . The
f ol l owing is an exampl e:
#define FIRST 1
#define SECOND FIRST
$result = 43 + SECOND;
Her e, t he macr o FIRST is def ined t o be equival ent t o t he val ue 1, and SECOND is def ined t o
be equival ent t o FIRST. This means t hat t he st at ement f ol l owing t he macr o def init ions is
equival ent t o t he f ol l owing st at ement :
$result = 43 + 1;
Conditional Execution Using #ifdef and #endif
The #ifdef and #endif st at ement s cont r ol whet her a given gr oup of st at ement s is t o be
incl uded as par t of your pr ogr am.
The synt ax f or t he #ifdef and #endif st at ement s is
#ifdef macro
code
#endif
Her e, macro is any char act er st r ing t hat can appear in a #define st at ement . code is one
or mor e l ines of your Per l pr ogr am.
When t he C pr epr ocessor sees an #ifdef st at ement , it checks whet her t he macr o has been
def ined using t he #define st at ement . If it has, t he code specif ied by code is incl uded as
par t of t he pr ogr am. If it has not , t he code specif ied by code is skipped.
NOTE
The code encl osed by #ifdef and #endif does not have t o
be a compl et e Per l st at ement . For exampl e, t he
f ol l owing code is l egal :
$result = 14 * 2
#ifdef PLUSONE
+ 1
#endif
;
Her e, $result is assigned 17 if PLUSONE is def ined, 16 if it 's
not .
Be car ef ul , t hough: If you abuse #ifdef, t he r esul t ing
pr ogr am might become dif f icul t t o r ead
The #ifndef and #else Statements
The #ifndef and #else st at ement s pr ovide addit ional cont r ol over when par t s of your
pr ogr am ar e t o be execut ed.
The #ifndef st at ement enabl es you t o def ine code t hat is t o be execut ed when a
par t icul ar macr o is not def ined.
The synt ax f or #ifndef is t he same as f or #ifdef:
#ifndef macro
code
#endif
For exampl e:
#ifndef MYMACRO
$result = 26;
#endif
The assignment is per f or med onl y if MYMACRO has not appear ed in a #define st at ement .
The #else st at ement enabl es you t o specif y code t o be execut ed if a macr o is def ined and
an al t er nat ive t o choose if t he macr o is not def ined. For exampl e:
#ifdef MYMACRO
$result = 47;
#else
print ("Hello, world!\n");
#endif
Her e, if MYMACRO has been def ined by a #define st at ement , t he f ol l owing st at ement is exe-
cut ed:
$result = 47;
If MYMACRO has not been def ined, t he f ol l owing st at ement is execut ed:
print ("Hello, world!\n");
You can use #else wit h #ifndef, as in t he f ol l owing:
#ifndef MYMACRO
print ("Hello, world!\n");
#else
$result = 47;
#endif
This code is ident ical t o t he #ifdef-#else-#endif sequence shown ear l ier in t his sect ion.
The #if Statement
The #if st at ement enabl es you t o specif y t hat cer t ain l ines of your pr ogr am ar e t o be
incl uded onl y if t he expr ession incl uded wit h t he st at ement is nonzer o.
The synt ax f or t he #if st at ement is
#if expr
code
#endif
Her e, expr is t he expr ession t o be eval uat ed, and code is t he code t o be execut ed if expr is
nonzer o.
For exampl e, t he f ol l owing st at ement is execut ed onl y if t he expr ession 14 + 3 is
nonzer o (which it al ways is, of cour se):
#if 14 + 3
$result = 26;
#endif
You can use a macr o def init ion as par t of an #if st at ement . If t he macr o is def ined, it has
a nonzer o val ue in an #if expr ession; if it is not def ined, it has t he val ue zer o. Consider
t he f ol l owing exampl e:
#if MACRO1 || MACRO2
$result = 47;
#endif
When t he pr epr ocessor sees t he #if st at ement , it eval uat es t he expr ession MACRO1 ||
MACRO2. This expr ession has a nonzer o val ue if eit her MACRO1 or MACRO2 is nonzer o.
Ther ef or e, t he f ol l owing st at ement is execut ed if eit her MACRO1 or MACRO2 is def ined:
$result = 47;
The #if st at ement pr ovides a quick way t o r emove l ines of code f r om your pr ogr am
t empor ar il y:
#if 0
$result = 46;
print ("This line is not printed right now.\n");
#endif
Her e, t he expr ession incl uded wit h t he #if st at ement is al ways zer o, which means t hat
t he st at ement s bet ween #if and #endif ar e al ways skipped.
You can use #else wit h #if, as in t he f ol l owing exampl e:
#if MACRO1 || MACRO2
print ("MACRO1 or MACRO2 is defined.\n");
#else
print ("MACRO1 and MACRO2 are not defined.\n");
#endif
This code incl udes t he f ir st pr int st at ement if MACRO1 or MACRO2 has been def ined using
#define, and it incl udes t he second pr int st at ement if neit her has been def ined.
You cannot use t he ** (exponent iat ion) oper at or in an
#if st at ement because ** is not suppor t ed in t he C
pr ogr amming l anguage
Nesting Conditional Execution Statements
You can put one #ifdef-#else-#endif const r uct inside anot her . For exampl e:
#ifdef MACRO1
#ifdef MACRO2
print ("MACRO1 yes, MACRO2 yes\n");
#else
print ("MACRO1 yes, MACRO2 no\n");
#endif
#else
#ifdef MACRO2
print ("MACRO1 no, MACRO2 yes\n");
#else
print ("MACRO1 no, MACRO2 no\n");
#endif
#endif
You al so can put an #if-#else-#endif const r uct or an #ifndef-#else-#endif const r uct
inside an #ifdef-#else-#endif const r uct , or vice ver sa. The onl y r est r ict ion is t hat t he
inner const r uct must be compl et el y cont ained in one par t of t he out er const r uct .
Including Other Files Using #include
Anot her pr epr ocessor command t hat is quit e usef ul is t he #include command. This
command t el l s t he C pr epr ocessor t o incl ude t he cont ent s of t he specif ied f il e as par t of
t he pr ogr am.
The synt ax f or t he #include command is
#include filename
filename is t he name of t he f il e t o be incl uded.
For exampl e, t he f ol l owing command incl udes t he cont ent s of myincfile.h as par t of
t he pr ogr am:
#include <myincfile.h>
When an #include st at ement is f ound in a Per l pr ogr am, t he C pr epr ocessor sear ches f or
t he f il e in t he cur r ent dir ect or y and t he /usr/local/lib/perl dir ect or y. (The -I opt ion,
descr ibed in t he f ol l owing sect ion, enabl es you t o sear ch in ot her dir ect or ies.) To
inst r uct t he C pr epr ocessor t o sear ch onl y t he cur r ent dir ect or y, encl ose t he f il ename
in doubl e quot at ion mar ks r at her t han angl e br acket s.
#include "myincfile.h"
This command l imit s t he sear ch f or myincfile.h t o t he cur r ent dir ect or y.
You can specif y an ent ir e pat hname in an #include st at ement , as in t he f ol l owing
exampl e:
#include "/u/dave/myincfile.h"
This command r et r ieves t he cont ent s of /u/dave/myincfile.h and adds t hem t o t he
pr ogr am.
NOTE
Per l al so enabl es you t o incl ude ot her f il es as par t of a
pr ogr am using t he require st at ement . For mor e
inf or mat ion on require, r ef er t o
Day 19, "Object -Or ient ed Pr ogr amming in Per l .
The -I Option: Searching for C Include Files
You use t he -I opt ion wit h t he -P opt ion. It enabl es you t o specif y wher e t o l ook f or
incl ude f il es t o be pr ocessed by t he C pr epr ocessor . For exampl e:
perl -P -I /u/dave/myincdir testfile
This command t el l s t he Per l int er pr et er t o sear ch t he dir ect or y /u/dave/myincdir f or
incl ude f il es (as wel l as t he def aul t dir ect or ies).
To specif y mul t ipl e dir ect or ies t o sear ch, r epeat t he -I opt ion:
perl -P -I /u/dave/dir1 -I /u/dave/dir2 testfile
This command sear ches in bot h /u/dave/dir1 and /u/dave/dir2.
NOTE
The dir ect or ies specif ied in t he -I opt ion al so ar e added
t o t he syst em var iabl e @INC. This t echnique ensur es t hat
t he require f unct ion can sear ch in t he same dir ect or ies
as t he C pr epr ocessor .
For mor e inf or mat ion on @INC, r ef er t o Day 17, "Syst em
Var iabl es." For mor e inf or mat ion on require, r ef er t o
Day 19
The -n Option: Operating on Multiple Files
One of t he most common t asks in Per l pr ogr ams and in UNIX commands is t o r ead t he
cont ent s of sever al input f il es one l ine at a t ime and pr ocess each input l ine as it is r ead.
In t hese pr ogr ams and commands, t he names of t he input f il es ar e suppl ied on t he
command l ine. A simpl e exampl e is t he UNIX command cat:
$ cat file1 file2 file3 ...
This command r eads one l ine of input at a t ime and wr it es it t o t he st andar d out put f il e.
In Per l , one way t o r ead t he cont ent s of sever al input f il es, one l ine at a t ime, is t o
encl ose t he <> oper at or in a while l oop:
while ($line = <>) {
# process $line in here
}
Anot her met hod is t o specif y t he -n opt ion. This opt ion t akes your pr ogr am and execut es
it once f or each l ine of input in each of t he f il es specif ied on t he command l ine.
List ing 16.3 is a simpl e exampl e of a pr ogr am t hat uses t he -n opt ion. It put s ast er isks
ar ound each input l ine and t hen pr int s it .

List ing 16.3. A simpl e pr ogr am t hat uses t he -n opt ion.
1: #!/usr/local/bin/perl -n
2:
3: # input line is stored in the system variable $_
4: $line = $_;
5: chop ($line);
6: printf ("* %-52s *\n", $line);

$ program16_3
* This test file has only one line in it. *
$
The -n opt ion encl oses t he pr ogr am shown her e in an invisibl e while l oop.
Each t ime t he pr ogr am is execut ed, t he next l ine of input f r om one of t he input f il es is
r ead and is st or ed in t he syst em var iabl e $_. Line 4 t akes t his l ine and copies it int o
anot her scal ar var iabl e, $line; l ine 5 t hen r emoves t he l ast char act er -t he t r ail ing
newl ine char act er -f r om t his l ine.
Line 6 uses printf t o wr it e t he input l ine t o t he st andar d out put f il e. Because printf is
f or mat t ing t he input , t he ast er isks al l appear in t he same col umns (col umn 1 and col umn
56) on your scr een.
NOTE
The pr evious pr ogr am is equival ent t o t he f ol l owing
Per l pr ogr am (which does not use t he -n opt ion):
#!/usr/local/bin/perl
while (< >) {
# input line is stored in the system variable $_
$line = $_;
chop ($line);
printf ("* %-72s *\n", $line);
}
The -n and -e opt ions wor k wel l t oget her . For exampl e, t he f ol l owing command is
equival ent t o t he cat command:
$ perl -n -e "print $_;" file1 file2 file3
The print $_; ar gument suppl ied wit h t he -e opt ion is a one-l ine Per l pr ogr am. Because
t he -n opt ion execut es t he pr ogr am once f or each input l ine and r eads each input l ine
int o t he syst em var iabl e $_, t he st at ement
print $_;
pr int s each input l ine in t ur n, which is exact l y what t he cat command does. (Not e t hat
t he par ent heses t hat nor mal l y encl ose t he ar gument passed t o print have been omit t ed
in t his case.)
The pr evious command can be made even simpl er :
$ perl -n -e "print" file1 file2 file3
By def aul t , if no ar gument is suppl ied, print assumes t hat it is t o pr int t he cont ent s of
$_. And, if t he pr ogr am consist s of a singl e st at ement , t her e is no need t o incl ude t he
cl osing semicol on.
The pat t er n mat ching and subst it ut ion oper at or s al so oper at e on $_ by def aul t . For
exampl e, t he f ol l owing st at ement examines t he cont ent s of $_ and sear ches f or a digit :
$found = /[0-9]/;
This def aul t behavior makes it easy t o incl ude a sear ch or a subst it ut ion in a singl e-l ine
command. For exampl e:
$ perl -n -e "print if /[0-9]/" file1 file2 file3
This command r eads each l ine of t he f il es file1, file2, and file3. If an input l ine
cont ains a digit , it is pr int ed.
NOTE
Sever al ot her f unct ions use $_ as t he def aul t scal ar
var iabl e t o oper at e on, which makes t hose f unct ions
ideal f or use wit h t he -n and -e opt ions. A f ul l l ist of
t hese f unct ions is pr ovided in t he descr ipt ion of t he $_
syst em var iabl e, which is cont ained in Day 17
The -p Option: Operating on Files and Printing
The -p opt ion is simil ar t o t he -n opt ion: it r eads each l ine of it s input f il es in t ur n.
However , t he -p opt ion al so pr int s each l ine it r eads.
This means, f or exampl e, t hat you can simul at e t he behavior of t he UNIX cat command
wit h t he f ol l owing command:
$ perl -p -e ";" file1 file2 file3
Her e, t he ; is a Per l pr ogr am consist ing of one st at ement t hat does not hing.
The -p opt ion is designed f or use wit h t he -i opt ion, descr ibed in t he f ol l owing sect ion.
NOTE
If bot h t he -p and t he -n opt ions ar e specif ied, t he -n
opt ion is ignor ed
The -i Option: Editing Files
As you have seen, t he -n and -p opt ions r ead l ines f r om t he f il es specif ied on t he
command l ine. The -i opt ion, when used wit h t he -p opt ion, t akes t he input l ines being
r ead and wr it es t hem back out t o t he f il es f r om which t hey came. This pr ocess enabl es
you t o edit f il es using commands simil ar t o t hose used in t he UNIX sed command.
For exampl e, consider t he f ol l owing command:
$ perl -p -i -e "s/abc/def/g;" file1 file2 file3
This command cont ains a one-l ine Per l pr ogr am t hat examines t he scal ar var iabl e $_ and
changes al l occur r ences of abc int o def. (Recal l t hat t he subst it ut ion oper at or
oper at es on $_ if t he =~ oper at or is not specif ied.) The -p opt ion ensur es t hat $_ is
assigned each l ine of each input f il e in t ur n and t hat t he pr ogr am is execut ed once f or
each input l ine. Thus, t his command changes al l occur r ences of abc in t he f il es file1,
file2, and file3 t o def.
Do not use t he -i opt ion wit h t he -n opt ion unl ess you
know what you'r e doing. The f ol l owing command al so
changes al l occur r ences of abc t o def, but it doesn't
wr it e out t he input l ines af t er it changes t hem:
$ perl -n -i -e "s/abc/def/g;" file1 file2 file3
Because t he -i opt ion specif ies t hat t he input f il es ar e t o
be edit ed, t he r esul t is t hat t he cont ent s of file1, file2,
and file3 ar e compl et el y dest r oyed
The -i opt ion al so wor ks on pr ogr ams t hat do not use t he -p opt ion but do cont ain t he
<> oper at or inside a l oop. For exampl e, consider t he f ol l owing command:
$ perl -i file1 file2 file3
In t his case, t he Per l int er pr et er copies t he f ir st f il e, file1, t o a t empor ar y f il e and
opens t he t empor ar y f il e f or r eading. Then, it opens file1 f or wr it ing and set s t he
def aul t out put f il e (t he f il e used by cal l s t o print, write, and printf) t o be file1.
Af t er t he pr ogr am f inishes r eading t he t empor ar y f il e t o which file1 was copied, it t hen
copies file2 t o a t empor ar y f il e, opens it f or r eading, opens file2 f or wr it ing, and set s
t he def aul t out put f il e t o be file2. This pr ocess cont inues unt il t he pr ogr am r uns out of
input f il es.
List ing 16.4 is a simpl e exampl e of a pr ogr am t hat edit s using t he -i opt ion and t he < >
oper at or . This pr ogr am eval uat es any ar it hmet ic expr essions (cont aining int eger s) it sees
on a singl e l ine and r epl aces t hem wit h t heir r esul t s.

List ing 16.4. A pr ogr am t hat edit s f il es using t he -i opt ion.
1: #!/usr/local/bin/perl -i
2:
3: while ($line = <>) {
4: while ($line =~
5: s#\d+\s*[*+-/]\s*\d+(\s*[*+-/]\s*\d+)*#<x>#) {
6: eval ("\$result = $&;");
7: $line =~ s/<x>/$result/;
8: }
9: print ($line);
10: }

This pr ogr am pr oduces no out put because out put is wr it t en t o t he f il es specif ied on t he
command l ine.
The <> oper at or at t he beginning of t he while l oop (l ine 3) r eads a l ine at a
t ime f r om t he input f il e or f il es. Each l ine is sear ched using t he pat t er n shown in l ine 5.
This pat t er n mat ches any subst r ing cont aining t he f ol l owing el ement s (in t he or der
given):
1. One or mor e digit s
2. Zer o or mor e spaces
3. An *, +, -, or / char act er
4. Zer o or mor e spaces
5. One or mor e digit s
6. Zer o or mor e of t he pr eceding f our subpat t er ns (which mat ches t he l ast par t of
expr essions such as 4 + 7 - 3)
This pat t er n is r epl aced by a pl acehol der subst r ing, <x>.
Lines 6 and 7 ar e execut ed once f or each pat t er n mat ched in t he input l ine. The mat ched
pat t er n, an ar it hmet ic expr ession, is aut omat ical l y st or ed in t he syst em var iabl e $&; l ine
6 subst it ut es t his expr ession int o a char act er st r ing and passes t his char act er st r ing t o
t he f unct ion eval. The cal l t o eval cr eat es a subpr ogr am t hat eval uat es t he expr ession
and r et ur ns t he r esul t in t he scal ar var iabl e $result. Line 7 r epl aces t he pl acehol der ,
<x>, wit h t he r esul t r et ur ned in $result.
When al l t he ar it hmet ic expr essions have been eval uat ed and subst it ut ed f or , t he inner
while l oop t er minat es, and l ine 9 cal l s print. Because t he -i opt ion has been set , t he
l ine is wr it t en back t o t he or iginal input f il e f r om which it came.
NOTE
Even t hough you do not know t he name of t he f il e
var iabl e t hat r epr esent s t he f il e being edit ed, you can
st il l set t he def aul t out put
f il e var iabl e t o some ot her f il e and change it back l at er .
To per f or m t his t ask, r ecal l t hat t he select f unct ion
r et ur ns t he f il e var iabl e associat ed wit h t he cur r ent
def aul t f il e:
$editfile = select (MYFILE); # change default file
# do your write operations here
select ($editfile); # change default file back
Af t er t he second select cal l has been per f or med, t he
def aul t out put f il e is, once again, t he f il e being edit ed
Backing Up Input Files Using the -i Option
By def aul t , t he -i opt ion over wr it es t he exist ing input f il es. If you wish, you can save a
copy of t he or iginal input f il e or f il es bef or e over wr it ing t hem. To do t his, specif y a f il e
ext ension wit h t he -i opt ion:
$ perl -i .old file1 file2 file3
Her e, t he .old f il e ext ension specif ied wit h t he -i opt ion t el l s t he Per l int er pr et er t o
copy file1 t o file1.old bef or e over wr it ing it . Simil ar l y, t he int er pr et er copies file2 t o
file2.old, and file3 t o file3.old.
The f il e ext ension specif ied wit h t he -i opt ion can be any char act er st r ing. By
convent ion, f il e ext ensions usual l y begin wit h a per iod; t his convent ion makes it easier
f or you t o spot t hem when you l ist t he f il es in your dir ect or y.
TIP
If you ar e using t he -i opt ion wit h a pr ogr am you ar e not
f amil iar wit h, it is a good idea t o specif y a f il e ext ension.
Doing so ensur es t hat your f il es ar e not damaged if t he
pr ogr am does not wor k t he way you expect
The -a Option: Splitting Lines
The -a opt ion is used wit h t he -n or -p opt ion. If t he -a opt ion is set , each input l ine t hat
is r ead is aut omat ical l y spl it int o a l ist of "wor ds" (sequences of char act er s t hat ar e
not whit e space); t his l ist of wor ds is st or ed in a special syst em ar r ay var iabl e named @F.
For exampl e, if your input f il e cont ains t he l ine
This is a test.
and if a pr ogr am t hat is cal l ed wit h t he -a opt ion r eads t his l ine, t he ar r ay @F cont ains
t he l ist
("This", "is", "a", "test.")
The -a opt ion is usef ul f or ext r act ing inf or mat ion f r om f il es. Suppose t hat your input
f il es cont ain r ecor ds of t he f or m
company_name quantity_ordered total_cost
such as, f or exampl e,
JOHN H. SMITH 10 47.32
List ing 16.5 shows how you can use t he -a opt ion t o easil y pr oduce a pr ogr am t hat
ext r act s t he quant it y and t ot al cost f iel ds f r om t hese f il es.

List ing 16.5. An exampl e of t he -a opt ion.
1: #!/usr/local/bin/perl
2:
3: # This program is called with the -a and -n options.
4: while ($F[0] =~ /[^\d.]/) {
5: shift (@F);
6: next if (!defined($F[0]));
7: }
8: print ("$F[0] $F[1]\n");

$ perl -a -n program16_5
10 47.32
106 11.54
$
Because t he pr ogr am is cal l ed wit h t he -a opt ion, t he ar r ay var iabl e @F
cont ains a l ist , each el ement of which is a wor d f r om t he cur r ent input l ine.
Because t he company name in t he input f il e might consist of mor e t han one wor d (such as
JOHN H. SMITH), t he while l oop in l ines 4-7 is needed t o get r id of ever yt hing t hat isn't a
quant it y f iel d or a t ot al cost f iel d. Af t er t hese f iel ds have been el iminat ed, l ine 8 can
pr int t he usef ul f iel ds.
Not e t hat t his pr ogr am just skips over any nonst andar d input l ines.
The -F Option: Specifying the Split Pattern
The -F opt ion, def ined onl y in Per l 5, is designed t o be used in conjunct ion wit h t he -a
opt ion, and specif ies t he pat t er n t o use when you spl it input l ines int o wor ds. For
exampl e, suppose List ing 16.5 is cal l ed as f ol l ows:
$ perl -a -n -F:: program16_5
In t his case, t he wor ds in t he input f il e ar e assumed t o be separ at ed by a pair of col ons,
which means t hat t he pr ogr am is expect ing t o r ead l ines such as t he f ol l owing:
JOHN H. SMITH::10::47.32
NOTE
The -F opt ion ignor es opening and cl osing sl ashes if t hey
ar e pr esent because it int er pr et s t hem as pat t er n
del imit er s. This means t hat t he f ol l owing pr ogr am
invocat ions ar e ident ical :
$ perl -a -n -F:: program16_5
$ perl -a -n -F/::/ program16_
The -0 Option: Specifying Input End-of-Line
In al l t he pr ogr ams you have seen so f ar , when t he Per l int er pr et er r eads a l ine f r om an
input f il e or f r om t he keyboar d, it r eads unt il it sees a newl ine char act er . You can t el l
Per l t hat you want t he "end-of -l ine" input char act er t o be somet hing ot her t han t he
newl ine char act er by specif ying t he -0 opt ion. (The 0 her e is t he digit zer o, not t he
l et t er O.)
Wit h t he -0 opt ion, you specif y which char act er is t o be t he end-of -l ine char act er f or
your input f il e by pr oviding it s ASCII r epr esent at ion in base 8 (oct al ). For exampl e, t he
command
$ perl -0 040 prog1 infile
cal l s t he Per l pr ogr am named prog1 and specif ies t hat it is t o use t he space char act er
(ASCII 32, or 40 oct al ) as t he end-of -l ine char act er when it r eads t he input f il e infile
(or any ot her input f il e).
This means, f or exampl e, t hat if t his pr ogr am r eads an input f il e cont aining t he
f ol l owing:
Test input.
Here's another line.
it wil l r ead a t ot al of f our input l ines:
G The f ir st input l ine consist s of t he wor d Test.
G The second input l ine consist s of input., f ol l owed by a newl ine char act er ,
f ol l owed by Here's.
G The t hir d input l ine consist s of t he wor d another.
G The f our t h input l ine consist s of t he wor d line., f ol l owed by a newl ine
char act er .
The -0 opt ion pr ovides a quick way t o r ead an input f il e one wor d at a t ime, assuming
t hat each l ine ends wit h at l east one bl ank char act er . (If it doesn't , you can quickl y
wr it e a Per l pr ogr am t hat uses t he -i and -p opt ions t o add a space t o t he end of each
l ine in each f il e.) List ing 16.6 is an exampl e of a pr ogr am t hat uses -0 t o r ead an input
f il e one wor d at a t ime.

List ing 16.6. A pr ogr am t hat uses t he -0 opt ion.
1: #!/usr/local/bin/perl -0040
2:
3: while ($line = <>) {
4: $line =~ s/\n//g;
5: next if ($line eq "");
6: print ("$line\n");
7: }

$ program16_6 file1
This
line
contains
five
words.
$
The header comment (l ine 1) specif ies t hat t he -0 opt ion is t o be used and t hat
t he space char act er is t o become t he end-of -l ine char act er . (Recal l t hat you do not
need a space bet ween an opt ion and t he val ue associat ed wit h an opt ion.) This means
t hat l ine 3 r eads f r om t he input f il e unt il it sees a bl ank space.
Not ever yt hing r ead by l ine 3 is a wor d, of cour se. Ther e ar e t wo t ypes of l ines t hat ar e
not par t icul ar l y usef ul t hat t he pr ogr am must check f or :
G Empt y l ines, which ar e gener at ed when t he input f il e cont ains t wo consecut ive
spaces
G Lines cont aining t he newl ine char act er (r emember , t he newl ine char act er is no
l onger an end-of -l ine char act er , so now it act ual l y appear s in input l ines)
Line 4 checks whet her any newl ine char act er s ar e cont ained in t he cur r ent input l ine.
The subst it ut ion in t his l ine is a gl obal subst it ut ion, because an input l ine can cont ain
t wo or mor e newl ine char act er s. (This occur s when an input f il e cont ains a bl ank l ine.)
Af t er al l t he newl ine char act er s have been el iminat ed, l ine 5 checks whet her t he
r esul t ing input l ine is empt y. If it is, t he pr ogr am cont inues wit h t he next input l ine. If
t he r esul t ing input l ine is not empt y, t he input l ine must be a usef ul wor d, and l ine 6
pr int s it .
NOTE
If you specif y t he val ue 00 (oct al zer o) wit h t he -0
opt ion, t he Per l int er pr et er r eads unt il it sees t wo
newl ine char act er s. This enabl es you t o r ead an ent ir e
par agr aph at a t ime.
If you specif y no val ue wit h t he -0 opt ion, t he nul l
char act er (ASCII 0) is assumed
The -l Option: Specifying Output End-of-Line
The -l opt ion enabl es you t o specif y an out put end-of -l ine char act er f or use in print
st at ement s.
Like t he -0 opt ion, t he -l opt ion accept s a base-8 (oct al ) int eger t hat indicat es t he ASCII
r epr esent at ion of t he char act er you want t o use.
When t he -l opt ion is specif ied, t he Per l int er pr et er does t wo t hings:
G If t he -n or -p opt ion is specif ied, each input l ine r ead in f r om t he st andar d input
f il e has it s l ast char act er (t he l ine t er minat or ) r emoved. (The Per l int er pr et er
t akes t his act ion because it assumes t hat you want t o r epl ace t he ol d end-of -l ine
char act er wit h t he one specif ied by t he -l opt ion.)
G When you cal l t he print f unct ion, t he out put wr it t en by print wil l be
immediat el y f ol l owed by t he char act er specif ied by t he -l opt ion.
If you do not specif y a val ue wit h t he -l opt ion, t he Per l int er pr et er uses t he char act er
specif ied by t he -0 opt ion, if it is def ined. If -0 has not been specif ied, t he end-of -l ine
char act er is def ined t o be t he newl ine char act er .
If you ar e using bot h t he -l and t he -0 opt ion and you do
not pr ovide a val ue wit h t he -l opt ion, t he or der of t he
opt ions becomes signif icant because t he opt ions ar e
pr ocessed f r om l ef t t o r ight .
If t he -l opt ion appear s f ir st , t he out put end-of -l ine
char act er is set t o t he newl ine char act er . If t he -0
opt ion appear s f ir st , t he out put end-of -l ine char act er
(set by -l) becomes t he same as t he input end-of -l ine
char act er (set by -0)
List ing 16.7 is a simpl e exampl e of a pr ogr am t hat uses -l.

List ing 16.7. A pr ogr am t hat uses t he -l opt ion.
1: #!/usr/local/bin/perl -l014
2:
3: print ("Hello!");
4: print ("This is a very simple test program!");

$ program16_7
Hello!
This is a very simple test program!
$
The -l014 opt ion in t he header comment in l ine 1 set s t he out put l ine
char act er t o t he newl ine char act er . This means t hat ever y print st at ement in t he
pr ogr am wil l have a newl ine char act er added t o it . As a consequence, t he out put f r om
l ines 3 and 4 appear on separ at e l ines.
NOTE
You can cont r ol t he input and out put end-of -l ine
char act er s al so by using t he syst em var iabl es $/ and $\.
For a descr ipt ion of t hese syst em var iabl es, r ef er t o Day
17
The -x Option: Extracting a Program from a Message
The -x opt ion enabl es you t o pr ocess a Per l pr ogr am t hat appear s in t he middl e of a f il e
(such as a f il e cont aining an el ect r onic mail message, which usual l y cont ains some mail
r out ing inf or mat ion). When t he -x opt ion is specif ied, t he Per l int er pr et er ignor es ever y
l ine in t he pr ogr am unt il it sees a header comment (a comment beginning wit h t he #!
char act er s).
If you ar e using Per l 5, t he header comment must al so
cont ain t he wor d "per l .
Af t er t he Per l int er pr et er sees t he header comment , it t hen pr ocesses t he pr ogr am as
usual unt il one of t he f ol l owing t hr ee condit ions occur s:
G The bot t om of t he pr ogr am f il e is r eached.
G The pr ogr am f il e cont ains a l ine consist ing of just t he Ct r l +D or Ct r l +Z
char act er .
G The pr ogr am f il e cont ains a l ine consist ing of t he f ol l owing st at ement (by it sel f ):
_ _END_ _
If t he Per l int er pr et er r eads one of t he end-of -pr ogr am l ines (t he second and t hir d
condit ions l ist ed pr eviousl y), it ignor es ever yt hing appear ing af t er t hat l ine in t he f il e.
List ing 16.8 is a simpl e exampl e of a pr ogr am t hat wor ks if r un wit h t he -x opt ion.

List ing 16.8. A Per l pr ogr am cont ained in a f il e.
1: Here is a Perl program that appears in the middle
2: of a file.
3: The stuff up here is junk, and the Perl interpreter
4: will ignore it.
5: The next line is the start of the actual program.
6: #!/usr/local/bin/perl
7:
8: print ("Hello, world!\n");
9: _ _END_ _
10: This line is also ignored, because it is not part
11: of the program.

$ program16_8
Hello, world!
$
If t his pr ogr am is st ar t ed wit h t he -x opt ion, t he Per l int er pr et er skips over
ever yt hing unt il it sees l ine 6. (Needl ess t o say, if you t r y t o r un t his pr ogr am wit hout
specif ying t he -x opt ion, t he Per l int er pr et er wil l compl ain.) Line 8 t hen pr int s t he
message Hello, world.
Line 9 is t he special end-of -pr ogr am l ine. When t he Per l int er pr et er sees t his l ine, it skips
t he r est of t he pr ogr am.
NOTE
Of cour se, you can't specif y t he -x opt ion in t he header
comment it sel f because t he Per l int er pr et er has t o know
in advance t hat t he pr ogr am cont ains l ines t hat must be
skipped
Miscellaneous Options
The f ol l owing sect ions descr ibe some of t he mor e exot ic opt ions you can pass t o t he Per l
int er pr et er . You ar e not l ikel y t o need any of t hese opt ions unl ess you ar e doing
somet hing unusual (and you r eal l y know what you ar e doing).
The -u Option
The -u opt ion t el l s t he Per l int er pr et er t o gener at e a cor e dump f il e. This f il e can t hen
be examined and manipul at ed.
The -U Option
The -U opt ion t el l s t he Per l int er pr et er t o enabl e you t o per f or m "unsaf e" oper at ions in
your pr ogr am. (Basical l y, you'l l know t hat an oper at ion is consider ed unsaf e when t he
Per l int er pr et er doesn't l et you per f or m it wit hout specif ying t he -U opt ion!)
The -S Option
The -S opt ion t el l s t he Per l int er pr et er t hat your pr ogr am might be cont ained in any of
t he dir ect or ies specif ied by your PATH envir onment var iabl e. The Per l int er pr et er checks
each of t hese dir ect or ies in t ur n, in t he or der in which t hey ar e specif ied, t o see whet her
your pr ogr am is l ocat ed t her e. (This is t he nor mal behavior of t he shel l f or commands in
t he UNIX envir onment .)
NOTE
You need t o use -S onl y if you ar e r unning your Per l
pr ogr am using t he perl command, as in
$ perl myprog
If you ar e r unning t he pr ogr am using a command such as
$ myprog
your shel l (nor mal l y) t r eat s it l ike any ot her command
and sear ches t he dir ect or ies specif ied in your PATH
envir onment var iabl e even if you don't specif y t he -S
opt ion
The -D Option
The -D opt ion set s t he Per l int er pr et er 's int er nal debugging f l ags. This opt ion is specif ied
wit h an int eger val ue (f or exampl e, -D 256).
For det ail s on t his opt ion, r ef er t o t he onl ine manual page f or Per l .
NOTE
The int er nal debugging f l ags specif ied by -D have
not hing t o do wit h t he Per l debugger , which is specif ied
by t he -d opt ion.
The debugging f l ags specif ied by -D pr ovide inf or mat ion
on how Per l it sel f wor ks, not on how your pr ogr am
wor ks
The -T Option: Writing Secure Programs
The -T opt ion specif ies t hat dat a obt ained f r om t he out side wor l d cannot be used in any
command t hat modif ies your f il e syst em. This f eat ur e enabl es you t o wr it e secur e
pr ogr ams f or syst em administ r at ion t asks.
This opt ion is onl y avail abl e in Per l 5. If you ar e r unning Per l 4, use a special ver sion of
Per l named taintperl. For det ail s on taintperl, see t he onl ine document at ion suppl ied
wit h your Per l dist r ibut ion.
The -d Option: Using the Perl Debugger
One f inal opt ion t hat is quit e usef ul is -d. This opt ion t el l s t he Per l int er pr et er t o r un
your pr ogr am using t he Per l debugger . For a compl et e descr ipt ion of t he Per l debugger
and how t o use it , r ef er t o Day 21, "The Per l Debugger ."
NOTE
If you ar e specif ying t he -d opt ion, you st il l can use
ot her opt ions
Summary
Today you l ear ned how t o specif y opt ions when you r un your Per l pr ogr ams. An opt ion is
a dash f ol l owed by a singl e l et t er , and opt ional l y f ol l owed by a val ue t o be associat ed
wit h t he opt ion. Opt ions l acking associat ed val ues can be gr ouped t oget her .
You can specif y opt ions in t wo ways: on t he command l ine and in t he header comment .
Onl y one opt ion or gr oup of opt ions can be suppl ied in t he header comment .
Avail abl e opt ions incl ude t hose t hat l ist t he Per l ver sion number , check your synt ax,
displ ay war nings, al l ow singl e-l ine pr ogr ams on t he command l ine, invoke t he C
pr epr ocessor , aut omat ical l y r ead f r om t he input f il es, and edit f il es in pl ace.
Q&A
Q: Why can you specif y onl y one opt ion in t he header comment ?
A: This is a r est r ict ion imposed by t he UNIX oper at ing syst em.
Q: Why does v displ ay t he Per l ver sion number wit hout r unning t he pr ogr am?
A: This opt ion enabl es you t o check whet her t he ver sion of Per l you ar e r unning is
capabl e of r unning your pr ogr am. If an ol d copy of Per l is r unning on your
machine, your pr ogr am might not wor k pr oper l y.
Q: What opt ions enabl e me t o wr it e a pr ogr am t hat edit s ever y l ine of a f il e?
A: Use t he -i (edit in pl ace) and -p (pr int each l ine) opt ions. (These opt ions ar e of t en
used wit h t he -e opt ion t o per f or m an edit ing command simil ar t o t hose used by
t he UNIX sed command.)
Q: I have a pr ogr am t hat needs t o r un on t wo or mor e dif f er ent machines. Is
t her e a way of wr it ing t he pr ogr am t hat ensur es t hat I don' t have t o
change t he pr ogr am each t ime I change machines?
A: Her e's how t o car r y out t his t ask:
1. On each machine, def ine a f il e t hat is t o be used t o st or e syst em-dependent
const ant s. Give t he f il e t he same name on each machine. For exampl e, you
coul d cal l t he f il e perldef.h. The l ocat ion of t he f il e doesn't mat t er as
l ong as it 's a dif f er ent dir ect or y name on each t ype of machine.
2. In each perldef.h, use #define t o def ine one const ant f or each t ype of
machine you r un. For exampl e, if you ar e r unning t his pr ogr am on UNIX
4.3BSD and Syst em V machines, you coul d def ine const ant s named M_BSD
and M_SYSV.
3. Af t er you have def ined t he const ant s, set t he val ue of each const ant t o 0,
except f or t he one cor r esponding t o t he machine on which you ar e
r unning. For exampl e, on your 4.3BSD machines, set M_BSD t o 1, and set al l
t he ot her const ant s t o 0.
4. Add t he f ol l owing st at ement t o your pr ogr am:
#include <perldef.h>
5. In your pr ogr am, use #if and #endif t o encl ose any syst em-dependent
inf or mat ion. For exampl e, if a gr oup of st at ement s is t o be execut ed onl y
on 4.3BSD machines, encl ose t he st at ement s wit h t he st at ement s
#if BSD
#endif
6. When you r un your pr ogr am, use t he -P opt ion t o specif y C pr epr ocessing,
and use t he -I opt ion t o t el l t he Per l int er pr et er t o sear ch f or t he
dir ect or y cor r esponding t o t he perldef.h f il e f or t his machine. For
exampl e, if you ar e r unning your pr ogr am on a 4.3BSD machine and t he
perldef.h f il e f or 4.3BSD machines is in t he /usr/local/include/bsdperl
dir ect or y, incl ude t he f ol l owing opt ion when you st ar t your pr ogr am:
-I /usr/local/include/bsdperl
Q: Why does t he -p opt ion over r ide t he -n opt ion?
A: The -p opt ion t el l s t he Per l int er pr et er t hat you want t o pr int each input l ine
t hat you r ead, and t he -n opt ion t el l s it t hat you don't want t o do so. These
opt ions basical l y cont r adict one anot her . -p over r ides -n because -p is saf er ; if
you r eal l y want -n, you can t hr ow away t he out put f r om -p. If you r eal l y want -
p and get -n, you won't get t he out put you want .
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. What do t he f ol l owing opt ions do?
a. -0
b. -s
c. -w
d. -x
e. -n
2. What happens when -l and -0 ar e bot h specif ied, and
a. -l appear s f ir st ?
b. -0 appear s f ir st ?
3. Why do t he -i and -n opt ions dest r oy input f il es when incl uded t oget her ?
4. How does t he C pr epr ocessor dist inguish bet ween pr epr ocessor commands and Per l
comment s?
5. How does t he Per l int er pr et er dist inguish opt ions f or t he int er pr et er f r om opt ions
f or t he pr ogr am it sel f ?
Exercises
1. Wr it e a pr ogr am t hat r epl aces al l t he newl ine char act er s in t he f il e testfile
wit h col ons. Use onl y command-l ine opt ions t o do t his.
2. Wr it e a one-l ine pr ogr am t hat pr int s onl y t he l ines cont aining t he wor d the.
3. Wr it e a one-l ine pr ogr am t hat pr int s t he second wor d of each input l ine.
4. Wr it e a pr ogr am t hat pr int s Hello! if you pass t he -H swit ch t o it and t hat pr int s
Goodbye! if you pass t he -G swit ch.
5. Wr it e a one-l ine pr ogr am t hat conver t s al l l ower case l et t er s t o upper case.
6. BUG BUSTER: What is wr ong wit h t his command l ine?
$ perl -i -n -e "s/abc/def/g";
7. BUG BUSTER: What is wr ong wit h t his command l ine?
$ perl -ipe "s/abc/def/g";

Chapter 17
System Variables
CONTENTS
G Gl obal Scal ar Var iabl es
H The Def aul t Scal ar Var iabl e: $_
H The Pr ogr am Name: $0
H The User ID: $< and $>
H The Gr oup ID: $( and $)
H The Ver sion Number : $]
H The Input Line Separ at or : $/
H The Out put Line Separ at or : $
H The Out put Fiel d Separ at or : $,
H The Ar r ay El ement Separ at or : $"
H The Number Out put For mat : $#
H The eval Er r or Message: $@
H The Syst em Er r or Code: $?
H The Syst em Er r or Message: $!
H The Cur r ent Line Number : $.
H Mul t il ine Mat ching: $*
H The Fir st Ar r ay Subscr ipt : $[
H Mul t idimensional Associat ive Ar r ays and t he $; Var iabl e
H The Wor d-Br eak Specif ier : $:
H The Per l Pr ocess ID: $$
H The Cur r ent Fil ename: $ARGV
H The Wr it e Accumul at or : $^A
H The Int er nal Debugging Val ue: $^D
H The Syst em Fil e Fl ag: $^F
H Cont r ol l ing Fil e Edit ing Using $^I
H The For mat For m-Feed Char act er : $^L
H Cont r ol l ing Debugging: $^P
H The Pr ogr am St ar t Time: $^T
H Suppr essing War ning Messages: $^W
H The $^X Var iabl e
G Pat t er n Syst em Var iabl es
H Ret r ieving Mat ched Subpat t er ns
H Ret r ieving t he Ent ir e Pat t er n: $&
H Ret r ieving t he Unmat ched Text : t he $` and $' Var iabl es
H The $+ Var iabl e
G Fil e Syst em Var iabl es
H The Def aul t Pr int For mat : $~
H Specif ying Page Lengt h: $=
H Lines Remaining on t he Page: $-
H The Page Header Pr int For mat : $^
H Buf f er ing Out put : $|
H The Cur r ent Page Number : $%
G Ar r ay Syst em Var iabl es
H The @_ Var iabl e
H The @ARGV Var iabl e
H The @F Var iabl e
H The @INC Var iabl e
H The %INC Var iabl e
H The %ENV Var iabl e
H The %SIG Var iabl e
G Buil t -In Fil e Var iabl es
H STDIN, STDOUT, and STDERR
H ARGV
H DATA
H The Under scor e Fil e Var iabl e
G Specif ying Syst em Var iabl e Names as Wor ds
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson descr ibes t he buil t -in syst em var iabl es t hat can be r ef er enced f r om ever y
Per l pr ogr am. These syst em var iabl es ar e divided int o f ive gr oups:
G Gl obal scal ar var iabl es
G Pat t er n syst em var iabl es
G Fil e syst em var iabl es
G Ar r ay syst em var iabl es
G Buil t -in f il e var iabl es
The f ol l owing sect ions descr ibe t hese gr oups of syst em var iabl es, and al so descr ibe how
t o pr ovide Engl ish-l anguage equival ent s of t heir var iabl e names.
Global Scalar Variables
The global scalar variables ar e buil t -in syst em var iabl es t hat behave just l ike t he scal ar
var iabl es you cr eat e in t he main body of your pr ogr am. This means t hat t hese var iabl es
have t he f ol l owing pr oper t ies:
G Each buil t -in gl obal scal ar var iabl e st or es onl y one scal ar val ue.
G Onl y one copy of a gl obal scal ar var iabl e is def ined in a pr ogr am.
Ot her kinds of buil t -in scal ar var iabl es, which you wil l see l at er in t his l esson, do not
behave in t his way.
The f ol l owing sect ions descr ibe t he gl obal scal ar var iabl es your Per l pr ogr ams can use.
The Default Scalar Variable: $_
The most commonl y used gl obal scal ar var iabl e is t he $_ var iabl e. Many Per l f unct ions
and oper at or s modif y t he cont ent s of $_ if you do not expl icit l y specif y t he scal ar
var iabl e on which t hey ar e t o oper at e.
The f ol l owing f unct ions and oper at or s wor k wit h t he $_ var iabl e by def aul t :
G The pat t er n-mat ching oper at or
G The subst it ut ion oper at or
G The t r ansl at ion oper at or
G The <> oper at or , if it appear s in a while or for condit ional expr ession
G The chop f unct ion
G The print f unct ion
G The study f unct ion
The Pattern-Matching Operator and $_
Nor mal l y, t he pat t er n-mat ching oper at or examines t he val ue st or ed in t he var iabl e
specif ied by a cor r esponding =~ or !~ oper at or . For exampl e, t he f ol l owing st at ement
pr int s hi if t he st r ing abc is cont ained in t he val ue st or ed in $val:
print ("hi") if ($val =~ /abc/);
By def aul t , t he pat t er n-mat ching oper at or examines t he val ue st or ed in $_. This means
t hat you can l eave out t he =~ oper at or if you ar e sear ching $_:
print ("hi") if ($_ =~ /abc/);
print ("hi") if (/abc/); # these two are the same
NOTE
If you want t o use t he !~ (t r ue-if -pat t er n-not -mat ched)
oper at or , you wil l al ways need t o specif y it expl icit l y,
even if you ar e examining $_:
print ("hi") if ($_ !~ /abc/);
If t he Per l int er pr et er sees just a pat t er n encl osed in /
char act er s, it assumes t he exist ence of a =~ oper at or
$_ enabl es you t o use pat t er n-sequence memor y t o ext r act subpat t er ns f r om a st r ing and
assign t hem t o an ar r ay var iabl e:
$_ = "This string contains the number 25.11.";
@array = /-?(\d+)\.?(\d+)/;
In t he second st at ement shown, each subpat t er n encl osed in par ent heses becomes an
el ement of t he l ist assigned t o @array. As a consequence, @array is assigned (25,11).
In Per l 5, a st at ement such as
@array = /-?(\d+)\.?(\d+)/;
al so assigns t he ext r act ed subpat t er ns t o t he pat t er n-sequence scal ar var iabl es $1, $2,
and so on. This means t hat t he st at ement assigns 25 t o $1 and 11 t o $2. Per l 4 suppor t s
assignment of subpat t er ns t o ar r ays, but does not assign t he subpat t er ns t o t he pat t er n-
sequence var iabl es.
The Substitution Operator and $_
The subst it ut ion oper at or , l ike t he pat t er n-mat ching oper at or , nor mal l y modif ies t he
cont ent s of t he var iabl e specif ied by t he =~ or !~ oper at or . For exampl e, t he f ol l owing
st at ement sear ches f or abc in t he val ue st or ed in $val and r epl aces it wit h def:
$val =~ s/abc/def/;
The subst it ut ion oper at or uses t he $_ var iabl e if you do not specif y a var iabl e using =~.
For exampl e, t he f ol l owing st at ement r epl aces t he f ir st occur r ence of abc in $_ wit h
def:
s/abc/def/;
Simil ar l y, t he f ol l owing st at ement r epl aces al l whit e space (spaces, t abs, and newl ine
char act er s) in $_ wit h a singl e space:
/\s+/ /g;
When you subst it ut e inside $_, t he subst it ut ion oper at or r et ur ns t he number of
subst it ut ions per f or med:
$subcount = s/abc/def/g;
Her e, $subcount cont ains t he number of occur r ences of abc t hat have been r epl aced by
def. If abc is not cont ained in t he val ue st or ed in $_, $subcount is assigned 0.
The Translation Operator and $_
The behavior of t he t r ansl at ion oper at or is simil ar t o t hat of t he pat t er n-mat ching and
subst it ut ion oper at or s: it nor mal l y oper at es on t he var iabl e specif ied by =~, and it
oper at es on $_ if no =~ oper at or is incl uded. For exampl e, t he f ol l owing st at ement
t r ansl at es al l l ower case l et t er s in t he val ue st or ed in $_ t o t heir upper case
equival ent s:
tr/a-z/A-Z/;
Like t he subst it ut ion oper at or , if t he t r ansl at ion oper at or is wor king wit h $_, it r et ur ns
t he number of oper at ions per f or med. For exampl e:
$conversions = tr/a-z/A-Z/;
Her e, $conversions cont ains t he number of l ower case l et t er s conver t ed t o upper case.
You can use t his f eat ur e of tr t o count t he number of occur r ences of par t icul ar
char act er s in a f il e. List ing 17.1 is an exampl e of a pr ogr am t hat per f or ms t his oper at ion.

List ing 17.1. A pr ogr am t hat count s using tr.
1: #!/usr/local/bin/perl
2:
3: print ("Specify the nonblank characters you want to count:\n");
4: $countstring = <STDIN>;
5: chop ($countstring);
6: @chars = split (/\s*/, $countstring);
7: while ($input = <>) {
8: $_ = $input;
9: foreach $char (@chars) {
10: eval ("\$count = tr/$char/$char/;");
11: $count{$char} += $count;
12: }
13: }
14: foreach $char (sort (@chars)) {
15: print ("$char appears $count{$char} times\n");
16: }

$ program17_1 file1
Specify the nonblank characters you want to count:
abc
a appears 8 times
c appears 3 times
b appears 2 times
$
This pr ogr am f ir st asks t he user f or a l ine of input cont aining t he char act er s
t o be count ed. These char act er s can be separ at ed by spaces or jammed int o a singl e wor d.
Line 5 t akes t he l ine of input cont aining t he char act er s t o be count ed and r emoves t he
t r ail ing newl ine char act er . Line 6 t hen spl it s t he l ine of input int o separ at e char act er s,
each of which is st or ed in an el ement of t he ar r ay @chars. The pat t er n /\s*/ spl it s on
zer o or mor e occur r ences of a whit espace char act er ; t his spl it s on ever y nonbl ank
char act er and skips over t he bl ank char act er s.
Line 7 r eads a l ine of input f r om a f il e whose name is specif ied on t he command l ine. Line
8 t akes t his l ine and st or es it in t he syst em var iabl e $_. (In most cases, syst em var iabl es
can be assigned t o, just l ike ot her var iabl es.)
Lines 9-12 count t he number of occur r ences of each char act er in t he input st r ing r ead in
l ine 4. Each char act er , in t ur n, is st or ed in $char, and t he val ue of $char is subst it ut ed
int o t he st r ing in l ine 10. This st r ing is t hen passed t o eval, which execut es t he
t r ansl at e oper at ion cont ained in t he st r ing.
The t r ansl at e oper at ion doesn't act ual l y do anyt hing because it is "t r ansl at ing" a
char act er t o it sel f . However , it r et ur ns t he number of t r ansl at ions per f or med, which
means t hat it r et ur ns t he number of occur r ences of t he char act er . This count is assigned
t o $count.
For exampl e, suppose t hat t he var iabl e $char cont ains t he char act er e and t hat $_
cont ains Hi there!. In t his case, t he st r ing in l ine 10 becomes t he f ol l owing because e is
subst it ut ed f or $char in t he st r ing:
$count = tr/e/e/;
The cal l t o eval execut es t his st at ement , which count s t he number of e's in Hi there!.
Because t her e ar e t wo e's in Hi there!, $count is assigned 2.
An associat ive ar r ay, %count, keeps t r ack of t he number of occur r ences of each of t he
char act er s being count ed. Line 11 adds t he count r et ur ned by l ine 10 t o t he associat ive
ar r ay el ement whose subscr ipt is t he char act er cur r ent l y being count ed. For exampl e, if
t he pr ogr am is cur r ent l y count ing t he number of e's, t his number is added t o t he el ement
$count{"e"}.
Af t er al l input l ines have been r ead and t heir char act er s count ed, l ines 14-16 pr int t he
t ot al number of occur r ences of each char act er by examining t he el ement s of %count.
The <> Operator and $_
In List ing 17.1, which you've just seen, t he pr ogr am r eads a l ine of input int o a scal ar
var iabl e named $input and t hen assigns it t o $_. Ther e is a quicker way t o car r y out t his
t ask, however . You can r epl ace
while ($input = <>) {
$_ = $input;
# more stuff here
}
wit h t he f ol l owing code:
while (<>) {
# more stuff here
}
If t he <> oper at or appear s in a condit ional expr ession t hat is par t of a l oop (an expr ession
t hat is par t of a condit ional st at ement such as while or for) and it is not t o t he r ight of
an assignment oper at or , t he Per l int er pr et er aut omat ical l y assigns t he r esul t ing input
l ine t o t he scal ar var iabl e $_.
For exampl e, List ing 17.2 shows a simpl e way t o pr int t he f ir st char act er of ever y input
l ine r ead f r om t he st andar d input f il e.

List ing 17.2. A simpl e pr ogr am t hat assigns t o $_ using <STDIN>.
1: #!/usr/local/bin/perl
2:
3: while (<STDIN>) {
4: ($first) = split (//, $_);
5: print ("$first\n");
6: }

$ program17_2
This is a test.
T
Here is another line.
H
^D
$
Because <STDIN> is inside a condit ional expr ession and is not assigned t o a
scal ar var iabl e, t he Per l int er pr et er assigns t he input l ine t o $_. The pr ogr am t hen
r et r ieves t he f ir st char act er by passing $_ t o split.
NOTE
The <> oper at or assigns t o $_ onl y if it is cont ained in a
condit ional expr ession in a l oop. The st at ement
<STDIN>;
r eads a l ine of input f r om t he st andar d input f il e and
t hr ows it away wit hout changing t he cont ent s of $_.
Simil ar l y, t he f ol l owing st at ement does not change t he
val ue of $_:
if (<>) {
print ("The input files are not all empty.\n");
}
The chop Function and $_
By def aul t , t he chop f unct ion oper at es on t he val ue st or ed in t he $_ var iabl e. For
exampl e:
while (<>) {
chop;
# you can do things with $_ here
}
Her e, t he cal l t o chop r emoves t he l ast char act er f r om t he val ue st or ed in $_. Because
t he condit ional expr ession in t he while st at ement has just assigned a l ine of input t o $_,
chop get s r id of t he newl ine char act er t hat t er minat es each input l ine.
The print Function and $_
The print f unct ion al so oper at es on $_ by def aul t . The f ol l owing st at ement wr it es t he
cont ent s of $_ t o t he st andar d out put f il e:
print;
List ing 17.3 is an exampl e of a pr ogr am t hat simpl y wr it es out it s input , which it assumes
is st or ed in $_. This pr ogr am is an impl ement at ion of t he UNIX cat command, which r eads
input f il es and displ ays t heir cont ent s.

List ing 17.3. A simpl e ver sion of t he cat command using $_.
1: #!/usr/local/bin/perl
2:
3: print while (<>);

$ program17_3 file1
This is the only line in file "file1".
$
This pr ogr am uses t he <> oper at or t o r ead a l ine of input at a t ime and st or e it
in $_. If t he l ine is nonempt y, t he print f unct ion is cal l ed; because no var iabl e is
specif ied wit h print, it wr it es out t he cont ent s of $_.
NOTE
You can use t his def aul t ver sion of print onl y if you ar e
wr it ing t o t he def aul t out put f il e (which is usual l y
STDOUT but can be changed using t he select f unct ion). If
you ar e specif ying a f il e var iabl e when you cal l print,
you al so must specif y t he val ue you ar e pr int ing.
For exampl e, t o send t he cont ent s of $_ t o t he out put
f il e MYFILE, use t he f ol l owing command:
print MYFILE ($_)
The study Function and $_
If you do not specif y a var iabl e when you cal l study, t his f unct ion uses $_ by def aul t :
study;
The study f unct ion incr eases t he ef f iciency of pr ogr ams t hat r epeat edl y sear ch t he same
var iabl e. It is descr ibed on Day 13, "Pr ocess, St r ing, and Mat hemat ical Funct ions."
Benefits of the $_ Variable
The def aul t behavior of t he f unct ions l ist ed pr eviousl y is usef ul t o r emember when you
ar e wr it ing one-l ine Per l pr ogr ams f or use wit h t he -e opt ion. For exampl e, t he
f ol l owing command is a quick way t o displ ay t he cont ent s of t he f il es file1, file2, and
file3:
$ perl -e "print while <>;" file1 file2 file3
Simil ar l y, t he f ol l owing command changes al l occur r ences of abc in file1, file2, and
file3 t o def:
$ perl -ipe "s/abc/def/g" file1 file2 file3
TIP
Al t hough $_ is usef ul in cases such as t he pr eceding one,
don't over use it . Many Per l pr ogr ammer s wr it e pr ogr ams
t hat have r ef er ences t o $_ r unning l ike an invisibl e
t hr ead t hr ough t heir pr ogr ams.
Pr ogr ams t hat over use $_ ar e har d t o r ead and ar e easier
t o br eak t han pr ogr ams t hat expl icit l y r ef er ence scal ar
var iabl es you have named your sel f
The Program Name: $0
The $0 var iabl e cont ains t he name of t he pr ogr am you ar e r unning. For exampl e, if your
pr ogr am is named perl1, t he st at ement
print ("Now executing $0...\n");
displ ays t he f ol l owing on your scr een:
Now executing perl1...
The $0 var iabl e is usef ul if you ar e wr it ing pr ogr ams t hat cal l ot her pr ogr ams. If an
er r or occur s, you can det er mine which pr ogr am det ect ed t he er r or :
die ("$0: can't open input file\n");
Her e, incl uding $0 in t he st r ing passed t o die enabl es you t o specif y t he f il ename in your
er r or message. (Of cour se, you can al ways l eave of f t he t r ail ing newl ine, which t el l s
Per l t o pr int t he f il ename and t he l ine number when pr int ing t he er r or message.
However , $0 enabl es you t o pr int t he f il ename wit hout t he l ine number , if t hat 's what
you want .)
NOTE
You can change your pr ogr am name whil e it is r unning
by modif ying t he val ue st or ed in $0
The User ID: $< and $>
The $< and $> var iabl es cont ain, r espect ivel y, t he r eal user ID and ef f ect ive user ID f or
t he pr ogr am. The r eal user ID is t he ID under which t he user of t he pr ogr am l ogged in.
The ef f ect ive user ID is t he ID associat ed wit h t his par t icul ar pr ogr am (which is not
al ways t he same as t he r eal user ID).
NOTE
If you ar e not r unning your Per l pr ogr am on t he UNIX
oper at ing syst em, t he $< and $> var iabl es might have no
meaning. Consul t your l ocal document at ion f or mor e
det ail s
List ing 17.4 uses t he r eal user ID t o det er mine t he user name of t he per son r unning t he
pr ogr am.

List ing 17.4. A pr ogr am t hat uses t he $< var iabl e.
1: #!/usr/local/bin/perl
2:
3: ($username) = getpwuid($<);
4: print ("Hello, $username!\n");

$ program17_4
Hello, dave!
$
The $< var iabl e cont ains t he r eal user ID, which is t he l ogin ID of t he per son
r unning t his pr ogr am. Line 3 passes t his user ID t o getpwuid, which r et r ieves t he
passwor d f il e ent r y cor r esponding t o t his user ID. The user name is t he f ir st el ement in
t his passwor d f il e, and it is st or ed in t he scal ar var iabl e $username. Line 4 t hen pr int s
t his user name.
NOTE
On cer t ain UNIX machines, you can assign $< t o $> (set
t he ef f ect ive user ID t o be t he r eal user ID) or vice
ver sa. If you have super user pr ivil eges, you can set $< or
$> t o any def ined user ID
The Group ID: $( and $)
The $( and $) var iabl es def ine t he r eal gr oup ID and t he ef f ect ive gr oup ID f or t his
pr ogr am. The r eal gr oup ID is t he gr oup t o which t he r eal user ID (st or ed in t he var iabl e
$<) bel ongs; t he ef f ect ive gr oup ID is t he gr oup t o which t he ef f ect ive user ID (st or ed in
t he var iabl e $>) bel ongs.
If your syst em enabl es user s t o be in mor e t han one gr oup at a t ime, $( and $) cont ain a
l ist of gr oup IDs, wit h each pair of gr oup IDs being separ at ed by spaces. You can conver t
t his int o an ar r ay by cal l ing split.
Nor mal l y, you can onl y assign $( t o $), and vice ver sa. If you ar e t he super user , you can
set $( or $) t o any def ined gr oup ID.
NOTE
$( and $) might not have any usef ul meaning if you ar e
r unning Per l on a machine r unning an oper at ing syst em
ot her t han UNIX
The Version Number: $]
The $] syst em var iabl e cont ains t he cur r ent ver sion number . You can use t his var iabl e
t o ensur e t hat t he Per l on which you ar e r unning t his pr ogr am is t he r ight ver sion of
Per l (or is a ver sion t hat can r un your pr ogr am).
Nor mal l y, $] cont ains a char act er st r ing simil ar t o t his:
$RCSfile: perl.c,v $$Revision: 4.0.1.8 $$Date: 1993/02/05 19:39:30 $
Patch level: 36
The usef ul par t s of t his st r ing ar e t he r evision number and t he pat ch l evel . The f ir st
par t of t he r evision number indicat es t hat t his is ver sion 4 of Per l . The ver sion number
and t he pat ch l evel ar e of t en combined; in t his not at ion, t his is ver sion 4.036 of Per l .
You can use t he pat t er n-mat ching oper at or t o ext r act t he usef ul inf or mat ion f r om $].
List ing 17.5 shows one way t o do it .

List ing 17.5. A pr ogr am t hat ext r act s inf or mat ion f r om t he $] var iabl e.
1: #!/usr/local/bin/perl
2:
3: $] =~ /Revision: ([0-9.]+)/;
4: $revision = $1;
5: $] =~ /Patch level: ([0-9]+)/;
6: $patchlevel = $1;
7: print ("revision $revision, patch level $patchlevel\n");

$ program17_5
revision 4.0.1.8, patch level 36
$
This pr ogr am just ext r act s t he r evision and pat ch l evel f r om $] using t he
pat t er n-mat ching oper at or . The buil t -in syst em var iabl e $1, descr ibed l at er t oday, is
def ined when a pat t er n is mat ched. It cont ains t he subst r ing t hat appear s in t he f ir st
subpat t er n encl osed in par ent heses. In l ine 3, t he f ir st subpat t er n encl osed in
par ent heses is [0-9.]+. This subpat t er n mat ches one or mor e digit s mixed wit h decimal
point s, and so it mat ches 4.0.1.8. This means t hat 4.0.1.8 is assigned t o $1 by l ine 3 and
is assigned t o $revision by l ine 4.
Simil ar l y, l ine 5 assigns 36 t o $1 (because t he subpat t er n [0-9]+, which mat ches one or
mor e digit s, is t he f ir st subpat t er n encl osed in par ent heses). Line 6 t hen assigns 36 t o
$patchlevel.
On some machines, t he val ue cont ained in $] might be
compl et el y dif f er ent f r om t he val ue used in t his
exampl e. If you ar e not sur e whet her $] has a usef ul
val ue, wr it e a l it t l e pr ogr am t hat just pr int s $]. If t his
pr ogr am pr int s somet hing usef ul , you'l l know t hat you
can r un pr ogr ams t hat compar e $] wit h an expect ed
val ue
The Input Line Separator: $/
When t he Per l int er pr et er is t ol d t o r ead a l ine of input f r om a f il e, it usual l y r eads
char act er s unt il it r eads a newl ine char act er . The newl ine char act er can be t hought
of as an input l ine separ at or ; it indicat es t he end of a par t icul ar l ine.
The syst em var iabl e $/ cont ains t he cur r ent input l ine separ at or . To change t he input
l ine separ at or , change t he val ue of $/. The $/ var iabl e can be mor e t han one char act er
l ong t o handl e t he case in which l ines ar e separ at ed by mor e t han one char act er . If you
set $/ t o t he nul l char act er , t he Per l int er pr et er assumes t hat t he input l ine separ at or
is t wo newl ine char act er s.
List ing 17.6 shows how changing $/ can af f ect your pr ogr am.

List ing 17.6. A pr ogr am t hat changes t he val ue of $/.
1: #!/usr/local/bin/perl
2:
3: $/ = ":";
4: $line = <STDIN>;
5: print ("$line\n");

$ program17_6
Here is some test input: here is the end.
Here is some test input:
$
Line 3 set s t he val ue of $/ t o a col on. This means t hat when l ine 4 r eads f r om
t he st andar d input f il e, it r eads unt il it sees a col on. As a consequence, $line cont ains
t he f ol l owing char act er st r ing:
Here is some test input:
Not e t hat t he col on is incl uded as par t of t he input l ine (just as, in t he nor mal case, t he
t r ail ing newl ine char act er is incl uded as par t of t he l ine).
The -0 (zer o, not t he l et t er O) swit ch set s t he val ue of
$/. If you change t he val ue of $/ in your pr ogr am, t he
val ue specif ied by -0 wil l be t hr own away.
To t empor ar il y change t he val ue of $/ and t hen r est or e
it t o t he val ue specif ied by -0, save t he cur r ent val ue of
$/ in anot her var iabl e bef or e changing it .
For mor e inf or mat ion on -0, r ef er t o Day 16, "Command-
Line Opt ions.
The Output Line Separator: $
The syst em var iabl e $\ cont ains t he cur r ent out put l ine separ at or . This is a char act er
or sequence of char act er s t hat is aut omat ical l y pr int ed af t er ever y cal l t o print.
By def aul t , $\ is t he nul l char act er , which indicat es t hat no out put l ine separ at or is t o
be pr int ed. List ing 17.7 shows how you can set an out put l ine separ at or .

List ing 17.7. A pr ogr am t hat uses t he $\ var iabl e.
1: #!/usr/local/bin/perl
2:
3: $\ = "\n";
4: print ("Here is one line.");
5: print ("Here is another line.");

$ program17_7
Here is one line.
Here is another line.
$
Line 3 set s t he out put l ine separ at or t o t he newl ine char act er . This means
t hat a l ist passed t o a subsequent print st at ement al ways appear s on it s own out put
l ine. Lines 4 and 5 now no l onger need t o incl ude a newl ine char act er as t he l ast
char act er in t he l ine.
The -l opt ion set s t he val ue of $\. If you change $\ in
your pr ogr am wit hout saving it f ir st , t he val ue suppl ied
wit h -l wil l be l ost . See Day 16 f or mor e inf or mat ion on
t he -l opt ion
The Output Field Separator: $,
The $, var iabl e cont ains t he char act er or sequence of char act er s t o be pr int ed bet ween
el ement s when print is cal l ed. For exampl e, in t he f ol l owing st at ement t he Per l
int er pr et er f ir st wr it es t he cont ent s of $a:
print ($a, $b);
It t hen wr it es t he cont ent s of $, and t hen f inal l y, t he cont ent s of $b.
Nor mal l y, t he $, var iabl e is init ial ized t o t he nul l char act er , which means t hat t he
el ement s of a print st at ement ar e pr int ed next t o one anot her . List ing 17.8 is a pr ogr am
t hat set s $, bef or e cal l ing print.

List ing 17.8. A pr ogr am t hat uses t he $, var iabl e.
1: #!/usr/local/bin/perl
2:
3: $a = "hello";
4: $b = "there";
5: $, = " ";
6: $\ = "\n";
7: print ($a, $b);

$ program17_8
hello there
$
Line 5 set s t he val ue of $, t o a space. Consequent l y, l ine 7 pr int s a space af t er
pr int ing $a and bef or e pr int ing $b.
Not e t hat $\, t he def aul t out put separ at or , is set t o t he newl ine char act er . This set t ing
ensur es t hat t he t er minat ing newl ine char act er immediat el y f ol l ows $b. By cont r ast ,
t he f ol l owing st at ement pr int s a space bef or e pr int ing t he t r ail ing newl ine char act er :
print ($a, $b, "\n");
NOTE
Her e's anot her way t o pr int t he newl ine immediat el y
af t er t he f inal el ement t hat doesn't invol ve set t ing $\:
print ($a, $b . "\n");
Her e, t he t r ail ing newl ine char act er is par t of t he
second el ement being pr int ed. Because $b and \n ar e par t
of t he same el ement , no space is pr int ed bet ween t hem
The Array Element Separator: $"
Nor mal l y, if an ar r ay is pr int ed inside a st r ing, t he el ement s of t he ar r ay ar e separ at ed
by a singl e space. For exampl e:
@array = ("This", "is", "a", "list");
print ("@array\n");
Her e, t he print st at ement pr int s
This is a list
A space is pr int ed bet ween each pair of ar r ay el ement s.
The buil t -in syst em var iabl e t hat cont r ol s t his sit uat ion is t he $" var iabl e. By def aul t ,
$" cont ains a space. List ing 17.9 shows how you can cont r ol your ar r ay out put by
changing t he val ue of $".

List ing 17.9. A pr ogr am t hat uses t he $" var iabl e.
1: #!/usr/local/bin/perl
2:
3: $" = "::";
4: @array = ("This", "is", "a", "list");
5: print ("@array\n");

$ program17_9
This::is::a::list
$
Line 3 set s t he ar r ay el ement separ at or t o :: (t wo col ons). Ar r ay el ement
separ at or s, l ike ot her separ at or s you can def ine, can be mor e t han one char act er l ong.
Line 5 pr int s t he cont ent s of @array. Each pair of el ement s is separ at ed by t he val ue
st or ed in $", which is t wo col ons.
NOTE
The $" var iabl e af f ect s onl y ent ir e ar r ays pr int ed inside
st r ings. If you pr int t wo var iabl es t oget her in a st r ing,
as in
print ("$a$b\n");
t he cont ent s of t he t wo var iabl es ar e pr int ed wit h
not hing separ at ing t hem r egar dl ess of t he val ue of $".
To change how ar r ays ar e pr int ed out side st r ings, use $\,
descr ibed ear l ier t oday
The Number Output Format: $#
By def aul t , when t he print f unct ion pr int s a number , it pr int s it as a 20-digit f l oat ing
point number in compact f or mat . This means t hat t he f ol l owing st at ement s ar e ident ical
if t he val ue st or ed in $x is a number :
print ($x);
printf ("%.20g", $x);
To change t he def aul t f or mat t hat print uses t o pr int number s, change t he val ue of t he
$# var iabl e. For exampl e, t o specif y onl y 15 digit s of pr ecision, use t his st at ement :
$# = "%.15g";
This val ue must be a f l oat ing-point f iel d specif ier , as used in printf and sprintf.
NOTE
The $# var iabl e does not af f ect val ues t hat ar e not
number s and has no ef f ect on t he printf, write, and
sprintf f unct ions
For mor e inf or mat ion on t he f iel d specif ier s you can use as t he def aul t val ue in $#, see
"For mat t ing Out put Using printf" on Day 11, "For mat t ing Your Out put ."
NOTE
The $# var iabl e is depr ecat ed in Per l 5. This means t hat
al t hough $# is suppor t ed, it is not r ecommended f or use
and might be r emoved f r om f ut ur e ver sions of Per l
The eval Error Message: $@
If a st at ement execut ed by t he eval f unct ion cont ains an er r or , or an er r or occur s
dur ing t he execut ion of t he st at ement , t he er r or message is st or ed in t he syst em
var iabl e $@. The pr ogr am t hat cal l ed eval can decide eit her t o pr int t he er r or message
or t o per f or m some ot her act ion.
For exampl e, t he st at ement
eval ("This is not a perl statement");
assigns t he f ol l owing st r ing t o $@:
syntax error in file (eval) at line 1, next 2 tokens "This is"
The $@ var iabl e al so r et ur ns t he er r or gener at ed by a cal l t o die inside an eval. The
f ol l owing st at ement assigns t his st r ing t o $@:
eval ("die (\"nothing happened\")");
nothing happened at (eval) line 1.
NOTE
The $@ var iabl e al so r et ur ns er r or messages gener at ed
by t he require f unct ion. See Day 19, "Object -Or ient ed
Pr ogr amming in Per l ," f or mor e inf or mat ion on require
The System Error Code: $?
The $? var iabl e r et ur ns t he er r or st at us gener at ed by cal l s t o t he system f unct ion or
by cal l s t o f unct ions encl osed in back quot es, as in t he f ol l owing:
$username = 'hostname';
The er r or st at us st or ed in $? consist s of t wo par t s:
G The exit val ue (r et ur n code) of t he pr ocess cal l ed by system or specif ied in back
quot es
G A st at us f iel d t hat indicat es how t he pr ocess was t er minat ed, if it t er minat ed
abnor mal l y
The val ue st or ed in $? is a 16-bit int eger . The upper eight bit s ar e t he exit val ue, and t he
l ower eight bit s ar e t he st at us f iel d. To r et r ieve t he exit val ue, use t he >> oper at or t o
shif t t he eight bit s t o t he r ight :
$retcode = $? >> 8;
For mor e inf or mat ion on t he st at us f iel d, r ef er t o t he onl ine manual page f or t he wait
f unct ion or t o t he f il e /usr/include/sys/wait.h. For mor e inf or mat ion on commands in
back quot es, r ef er t o Day 20, "Miscel l aneous Feat ur es of Per l ."
The System Error Message: $!
Some Per l l ibr ar y f unct ions cal l syst em l ibr ar y f unct ions. If a syst em l ibr ar y f unct ion
gener at es an er r or , t he er r or code gener at ed by t he f unct ion is assigned t o t he $!
var iabl e. The Per l l ibr ar y f unct ions t hat cal l syst em l ibr ar y f unct ions var y f r om
machine t o machine.
NOTE
The $! var iabl e in Per l is equival ent t o t he errno
var iabl e in t he C pr ogr amming l anguage
The Current Line Number: $.
The $. var iabl e cont ains t he l ine number of t he l ast l ine r ead f r om an input f il e. If mor e
t han one input f il e is being r ead, $. cont ains t he l ine number of t he l ast input f il e r ead.
List ing 17.10 shows how $. wor ks.

List ing 17.10. A pr ogr am t hat uses t he $. var iabl e.
1: #!/usr/local/bin/perl
2:
3: open (FILE1, "file1") ||
4: die ("Can't open file1\n");
5: open (FILE2, "file2") ||
6: die ("Can't open file2\n");
7: $input = <FILE1>;
8: $input = <FILE1>;
9: print ("line number is $.\n");
10: $input = <FILE2>;
11: print ("line number is $.\n");
12: $input = <FILE1>;
13: print ("line number is $.\n");

$ program17_10
line number is 2
line number is 1
line number is 3
$
When l ine 9 is execut ed, t he input f il e FILE1 has had t wo l ines r ead f r om it .
This means t hat $. cont ains t he val ue 2. Line 10 t hen r eads f r om FILE2. Because it r eads
t he f ir st l ine f r om t his f il e, $. now has t he val ue 1. When l ine 12 r eads a t hir d l ine f r om
FILE1, $. is set t o t he val ue 3. The Per l int er pr et er r emember s t hat t wo l ines have
al r eady been r ead f r om FILE1.
NOTE
If t he pr ogr am is r eading using <>, which r eads f r om t he
f il es l ist ed on t he command l ine, $. t r eat s t he input f il es
as if t hey ar e one cont inuous f il e. The l ine number is not
r eset when a new input f il e is opened
You can use eof t o t est whet her a par t icul ar f il e has
ended, and t hen r eset $. your sel f (by assigning zer o t o
it ) bef or e r eading f r om t he next f il e.
Multiline Matching: $*
Nor mal l y, t he oper at or s t hat mat ch pat t er ns (t he pat t er n-mat ching oper at or and t he
subst it ut ion oper at or ) assume t hat t he char act er st r ing being sear ched is a singl e l ine
of t ext . If t he char act er st r ing being sear ched consist s of mor e t han one l ine of t ext (in
ot her wor ds, it cont ains newl ine char act er s), set t he syst em var iabl e $* t o 1.
NOTE
By def aul t , $* is set t o 0, which indicat es t hat mul t il ine
pat t er n mat ches ar e not r equir ed
The $* var iabl e is depr ecat ed in Per l 5. If you ar e
r unning Per l 5, use t he m pat t er n-mat ching opt ion when
mat ching in a mul t ipl e-l ine st r ing. See Day 7, "Pat t er n
Mat ching," f or mor e det ail s on t his opt ion
The First Array Subscript: $[
Nor mal l y, when a pr ogr am r ef er ences t he f ir st el ement of an ar r ay, it does so by
specif ying t he subscr ipt 0. For exampl e:
@myarray = ("Here", "is", "a", "list");
$here = $myarray[0];
The ar r ay el ement $myarray[0] cont ains t he st r ing Here, which is assigned t o $here.
If you ar e not comf or t abl e wit h using 0 as t he subscr ipt f or t he f ir st el ement of an
ar r ay, you can change t his set t ing by changing t he val ue of t he $[ var iabl e. This
var iabl e indicat es which val ue is t o be used as t he subscr ipt f or t he f ir st ar r ay el ement .
Her e is t he pr eceding exampl e, modif ied t o use 1 as t he f ir st ar r ay el ement subscr ipt :
$[ = 1;
@myarray = ("Here", "is", "a", "list");
$here = $myarray[1];
In t his case, t he subscr ipt 1 now r ef er ences t he f ir st ar r ay el ement . This means t hat
$here is assigned Here, as bef or e.
TIP
Don't change t he val ue of $[. It is t oo easy f or a casual
r eader of your pr ogr am t o f or get t hat t he subscr ipt 0 no
l onger r ef er ences t he f ir st el ement of t he ar r ay.
Besides, using 0 as t he subscr ipt f or t he f ir st el ement is
st andar d pr act ice in many pr ogr amming l anguages,
incl uding C and C++
NOTE
$[ is depr ecat ed in Per l 5
Multidimensional Associative Arrays and the $; Variable
So f ar , al l t he ar r ays you've seen have been one-dimensional ar r ays, which ar e ar r ays in
which each ar r ay el ement is r ef er enced by onl y one subscr ipt . For exampl e, t he
f ol l owing st at ement uses t he subscr ipt foo t o access an el ement of t he associat ive ar r ay
named %array:
$myvar = $array{"foo"};
Per l does not suppor t mul t idimensional ar r ays dir ect l y. The f ol l owing st at ement is not
a l egal Per l st at ement :
$myvar = $array{"foo"}{"bar"};
However , Per l enabl es you t o simul at e a mul t idimensional associat ive ar r ay using t he
buil t -in syst em var iabl e $;.
Her e is an exampl e of a st at ement t hat accesses a (simul at ed) mul t idimensional ar r ay:
$myvar = $array{"foo","bar"};
When t he Per l int er pr et er sees t his st at ement , it conver t s it t o t his:
$myvar = $array{"foo" . $; . "bar"};
The syst em var iabl e $; ser ves as a subscr ipt separ at or . It aut omat ical l y r epl aces any
comma t hat is separ at ing t wo ar r ay subscr ipt s.
Her e is anot her exampl e of t wo equival ent st at ement s:
$myvar = $array{"s1", 4, "hi there"};
$myvar = $array{"s1".$;.4.$;."hi there"};
The second st at ement shows how t he val ue of t he $; var iabl e is inser t ed int o t he ar r ay
subscr ipt .
By def aul t , t he val ue of $; is \034 (t he Ct r l +\ char act er ). You can def ine $; t o be any
val ue you want . List ing 17.11 is an exampl e of a pr ogr am t hat set s $;.

List ing 17.11. A pr ogr am t hat uses t he $; var iabl e.
1: #!/usr/local/bin/perl
2:
3: $; = "::";
4: $array{"hello","there"} = 46;
5: $test1 = $array{"hello","there"};
6: $test2 = $array{"hello::there"};
7: print ("$test1 $test2\n");

$ program17_11
46 46
$
Line 3 set s $; t o t he st r ing ::. As a consequence, t he subscr ipt
"hello","there" in l ines 4 and 5 is r eal l y hello::there because t he Per l int er pr et er
r epl aces t he comma wit h t he val ue of $;.
Line 7 shows t hat bot h "hello","there" and hello::there r ef er t o t he same el ement of
t he associat ive ar r ay.
If you set $;, be car ef ul not t o set it t o a char act er t hat
you ar e act ual l y using in a subscr ipt . For exampl e, if you
set $; t o ::, t he f ol l owing st at ement s r ef er ence t he
same el ement of t he ar r ay:
$array{"a::b", "c"} = 1;
$array{"a", "b::c"} = 2;
In each case, t he Per l int er pr et er r epl aces t he comma
wit h ::, pr oducing t he subscr ipt a::b::c
The Word-Break Specifier: $:
On Day 11 you l ear ned how t o f or mat your out put using pr int f or mat s and t he write
st at ement . Each pr int f or mat cont ains one or mor e val ue f iel ds t hat specif y how out put
is t o appear on t he page.
If a val ue f iel d in a pr int f or mat begins wit h t he ^ char act er , t he Per l int er pr et er put s a
wor d in t he val ue f iel d onl y if t her e is r oom enough f or t he ent ir e wor d. For exampl e, in
t he f ol l owing pr ogr am (a dupl icat e of List ing 11.9),
1: #!/usr/local/bin/perl
2:
3: $string = "Here\nis an unbalanced line of\ntext.\n";
4: $~ = "OUTLINE";
5: write;
6:
7: format OUTLINE =
8: ^<<<<<<<<<<<<<<<<<<<<<<<<<<<
9: $string
10: .
t he cal l t o write uses t he OUTLINE pr int f or mat t o wr it e t he f ol l owing t o t he scr een:
Here is an unbalanced line
Not e t hat t he wor d of is not pr int ed because it cannot f it int o t he OUTLINE val ue f iel d.
To det er mine whet her a wor d can f it in a val ue f iel d, t he Per l int er pr et er count s t he
number of char act er s bet ween t he next char act er t o be f or mat t ed and t he next wor d-
br eak char act er . A word-break character is one t hat denot es eit her t he end of a wor d or a
pl ace wher e a wor d can be spl it int o t wo par t s.
By def aul t , t he l egal wor d-br eak char act er s in Per l ar e t he space char act er , t he
newl ine char act er , and t he - (hyphen) char act er . The accept abl e wor d br eak char act er s
ar e st or ed in t he syst em var iabl e $:.
To change t he l ist of accept abl e wor d-br eak char act er s, change t he val ue of $:. For
exampl e, t o ensur e t hat al l hyphenat ed wor ds ar e in t he same l ine of f or mat t ed out put ,
def ine $: as shown her e:
$: = " \n";
Now onl y t he space and newl ine char act er s ar e l egal wor d-br eak char act er s.
NOTE
Nor mal l y, t he t ab char act er is not a wor d-br eak
char act er . To al l ow l ines t o be br oken on t abs, add t he
t ab char act er t o t he l ist specif ied by t he $: var iabl e:
$: = " \t\n-"
The Perl Process ID: $$
The $$ syst em var iabl e cont ains t he pr ocess ID f or t he Per l int er pr et er it sel f . This is
al so t he pr ocess ID f or your pr ogr am.
The Current Filename: $ARGV
When you use t he <> oper at or , t he Per l int er pr et er r eads input f r om each f il e named on
t he command l ine. For exampl e, suppose t hat you ar e execut ing t he pr ogr am myprog as
shown her e:
$ myprog test1 test2 test3
In myprog, t he f ir st occur r ence of t he <> oper at or r eads f r om test1. Subsequent
occur r ences of <> cont inue r eading f r om test1 unt il it is exhaust ed; at t his point , <>
r eads f r om test2. This pr ocess cont inues unt il al l t he input f il es have been r ead.
On Day 6, "Reading f r om and Wr it ing t o Fil es," you l ear ned t hat t he @ARGV ar r ay l ist s
t he el ement s of t he command l ine and t hat t he f ir st el ement of @ARGV is r emoved when
t he <> oper at or r eads a l ine. (@ARGV al so is discussed l at er t oday.)
When t he <> oper at or r eads f r om a f il e f or t he f ir st t ime, it assigns t he name of t he f il e
t o t he $ARGV syst em var iabl e. This enabl es you t o keep t r ack of what f il e is cur r ent l y
being r ead. List ing 17.12 shows how you can use $ARGV.

List ing 17.12. A simpl e f il e-sear ching pr ogr am using $ARGV.
1: #!/usr/local/bin/perl
2:
3: print ("Enter the search pattern:\n");
4: $string = <STDIN>;
5: chop ($string);
6: while ($line = <>) {
7: if ($line =~ /$string/) {
8: print ("$ARGV:$line");
9: }
10: }

$ program17_12 file1 file2 file3
Enter the string to search:
the
file1:This line contains the word "the".
$
This pr ogr am r eads each l ine of t he input f il es suppl ied on t he command l ine.
If a l ine cont ains t he pat t er n specif ied by $string, l ine 8 pr int s t he name of t he f il e and
t hen t he l ine it sel f . Not e t hat t he pat t er n in $string can cont ain special pat t er n
char act er s.
NOTE
If <> is r eading f r om t he st andar d input f il e (which
occur s when you have not specif ied any input f il es on
t he command l ine), $ARGV cont ains t he st r ing - (a singl e
hyphen)
The Write Accumulator: $^A
The $^A var iabl e is used by write t o st or e f or mat t ed l ines t o be pr int ed. The cont ent s of
$^A ar e er ased af t er t he l ine is pr int ed.
This var iabl e is def ined onl y in Per l 5.
The Internal Debugging Value: $^D
The $^D var iabl e displ ays t he cur r ent int er nal debugging val ue. This var iabl e is def ined
onl y when t he -D swit ch has been specif ied and when your Per l int er pr et er has been
compil ed wit h debugging incl uded.
See your onl ine Per l document at ion f or mor e det ail s on debugging Per l . (Unl ess you ar e
using an exper iment al ver sion of Per l , you ar e not l ikel y t o need t o debug it .)
The System File Flag: $^F
The $^F var iabl e cont r ol s whet her f il es ar e t o be t r eat ed as syst em f il es. It s val ue is t he
l ar gest UNIX f il e descr ipt or t hat is t r eat ed as a syst em f il e.
Nor mal l y, onl y STDIN, STDOUT, and STDERR ar e t r eat ed as syst em f il es, and t he val ue
assigned t o $^F is 2. Unl ess you ar e on a UNIX machine, ar e f amil iar wit h f il e descr ipt or s,
and want t o do somet hing exot ic wit h t hem, you ar e not l ikel y t o need t o use t he $^F
syst em var iabl e.
Controlling File Editing Using $^I
The $^I var iabl e is set t o a nonzer o val ue by t he Per l int er pr et er when you specif y t he -
i opt ion (which edit s f il es as t hey ar e r ead by t he <> oper at or ).
The f ol l owing st at ement t ur ns of f t he edit ing of f il es being r ead by <>:
undef ($^I);
When $^I is undef ined, t he next input f il e is opened f or r eading, and t he st andar d
out put f il e is no l onger changed.
DO open t he f il es f or input and out put your sel f if your
pr ogr am want s t o edit some of it s input f il es and not
ot her s; t his pr ocess is easier t o f ol l ow.
DON' T use $^I if you ar e r eading f il es using t he -n or -p
opt ion unl ess you r eal l y know what you ar e doing,
because you ar e not l ikel y t o get t he behavior you
expect . If -i has modif ied t he def aul t out put f il e,
undef ining $^I does not aut omat ical l y set t he def aul t
out put f il e t o STDOUT
The Format Form-Feed Character: $^L
The $^L var iabl e cont ains t he char act er or char act er s wr it t en out whenever a pr int
f or mat want s t o st ar t a new page. The def aul t val ue is \f, t he f or m-f eed char act er .
Controlling Debugging: $^P
The $^P var iabl e is used by t he Per l debugger . When t his var iabl e is set t o zer o,
debugging is t ur ned of f .
You nor mal l y won't need t o use $^P your sel f , unl ess you want t o specif y t hat a cer t ain
chunk of code does not need t o be debugged.
The Program Start Time: $^T
The $^T var iabl e cont ains t he t ime at which your pr ogr am began r unning. This t ime is in
t he same f or mat as is r et ur ned by t he time f unct ion: t he number of seconds since Januar y
1, 1970.
The f ol l owing st at ement set s t he f il e-access and -modif icat ion t imes of t he f il e test1 t o
t he t ime st or ed in $^T:
utime ($^T, $^T, "test1");
For mor e inf or mat ion on t he time and utime f unct ions, r ef er t o Day 12, "Wor king wit h
t he Fil e Syst em."
NOTE
The t ime f or mat used by $^T is al so t he same as t hat used
by t he f il e t est oper at or s -A, -C, and -M
Suppressing Warning Messages: $^W
The $^W syst em var iabl e cont r ol s whet her war ning messages ar e t o be displ ayed.
Nor mal l y, $^W is set t o a nonzer o val ue onl y when t he -w opt ion is specif ied.
You can set $^W t o zer o t o t ur n of f war nings inside your pr ogr am. This capabil it y is
usef ul if your pr ogr am cont ains st at ement s t hat gener at e war nings you want t o ignor e
(because you know t hat your st at ement s ar e cor r ect ). For exampl e:
$^W = 0; # turn off warning messages
# code that generates warnings goes here
$^W = 1; # turn warning messages back on
Some war nings ar e pr int ed bef or e pr ogr am execut ion
st ar t s (f or exampl e, war nings of possibl e t ypos). You
cannot t ur n of f t hese war nings by set t ing $^W t o zer o
The $^X Variable
The $^X var iabl e displ ays t he f ir st wor d of t he command l ine you used t o st ar t t his
pr ogr am. If you st ar t ed t his pr ogr am by ent er ing it s name, t he name of t he pr ogr am
appear s in $^X. If you used t he perl command t o st ar t t his pr ogr am, $^X cont ains perl.
The f ol l owing st at ement checks t o see whet her you st ar t ed t his pr ogr am wit h t he
command perl:
if ($^X ne "perl") {
print ("You did not use the 'perl' command ");
print ("to start this program.\n");
}
Pattern System Variables
The syst em var iabl es you have seen so f ar ar e al l def ined t hr oughout your pr ogr am. The
f ol l owing syst em var iabl es ar e def ined onl y in t he cur r ent bl ock of st at ement s you ar e
r unning. (A block of st at ement s is any gr oup of st at ement s encl osed in t he br ace
char act er s { and }.) These pattern system variables ar e set by t he pat t er n-mat ching
oper at or and t he ot her oper at or s t hat use pat t er ns (such as, f or exampl e, t he
subst it ut ion oper at or ). Many of t hese pat t er n syst em var iabl es wer e f ir st int r oduced on
Day 7.
TIP
Even t hough t he pat t er n syst em var iabl es ar e def ined
onl y inside a par t icul ar bl ock of st at ement s, your
pr ogr ams shoul d not t ake advant age of t hat f act . The
saf est way t o use t he pat t er n-mat ching var iabl es is t o
assign any var iabl e t hat you might need t o a scal ar
var iabl e of your own
Retrieving Matched Subpatterns
When you specif y a pat t er n f or t he pat t er n-mat ching or subst it ut ion oper at or , you can
encl ose par t s of t he pat t er n in par ent heses. For exampl e, t he f ol l owing pat t er n
encl oses t he subpat t er n \d+ in par ent heses. (The par ent heses t hemsel ves ar e not par t of
t he pat t er n.)
/(\d+)\./
This subpat t er n mat ches one or mor e digit s.
Af t er a pat t er n has been mat ched, t he syst em var iabl es $1, $2, and so on mat ch t he
subpat t er ns encl osed in par ent heses. For exampl e, suppose t hat t he f ol l owing pat t er n is
successf ul l y mat ched:
/(\d+)([a-z]+)/
In t his case, t he mat ch f ound must consist of one or mor e digit s f ol l owed by one or mor e
l ower case l et t er s. Af t er t he mat ch has been f ound, $1 cont ains t he sequence of one or
mor e digit s, and $2 cont ains t he sequence of one or mor e l ower case l et t er s.
List ing 17.13 is an exampl e of a pr ogr am t hat uses $1, $2, and $3 t o mat ch subpat t er ns.

List ing 17.13. A pr ogr am t hat uses var iabl es cont aining mat ched
subpat t er ns.
1: #!/usr/local/bin/perl
2:
3: while (<>) {
4: while (/(-?\d+)\.(\d+)([eE][+-]?\d+)?/g) {
5: print ("integer part $1, decimal part $2");
6: if ($3 ne "") {
7: print (", exponent $3");
8: }
9: print ("\n");
10: }
11: }

$ program17_13 file1
integer part 26, decimal part 147, exponent e-02
integer part -8, decimal part 997
$
This pr ogr am r eads each input l ine and sear ches f or f l oat ing-point number s.
Line 4 mat ches if a f l oat ing-point number is f ound. (Line 4 is a while st at ement , not an
if, t o enabl e t he pr ogr am t o det ect l ines cont aining mor e t han one f l oat ing-point
number . The l oop st ar t ing in l ine 4 it er at es unt il no mor e mat ches ar e f ound on t he
l ine.)
When a mat ch is f ound, t he f ir st set of par ent heses mat ches t he digit s bef or e t he decimal
point ; t hese digit s ar e copied int o $1. The second set of par ent heses mat ches t he digit s
af t er t he decimal point ; t hese mat ched digit s ar e st or ed in $2. The t hir d set of
par ent heses mat ches an opt ional exponent ; if t he exponent exist s, it is st or ed in $3.
Line 5 pr int s t he val ues of $1 and $2 f or each mat ch. If $3 is def ined, it s val ue is pr int ed
by l ine 7.
DO use $1, not $0, t o r et r ieve t he f ir st mat ched
subpat t er n. $0 cont ains t he name of t he pr ogr am you ar e
r unning.
DON' T conf use $1 wit h \1. \1, \2, and so on ar e def ined
onl y inside a pat t er n. See Day 7 f or mor e inf or mat ion on
\1
In pat t er ns, par ent heses ar e count ed st ar t ing f r om t he l ef t . This r ul e t el l s t he Per l
int er pr et er how t o handl e nest ed par ent heses:
/(\d+(\.)?\d+)/
This pat t er n mat ches one or mor e digit s opt ional l y cont aining a decimal point . When
t his pat t er n is mat ched, t he out er set of par ent heses is consider ed t o be t he f ir st set of
par ent heses; t hese par ent heses cont ain t he ent ir e mat ched number , which is st or ed in $1.
The inner set of par ent heses is t r eat ed as t he second set of par ent heses because it
incl udes t he second l ef t par ent hesis seen by t he pat t er n mat cher . The var iabl e $2, which
cont ains t he subpat t er n mat ched by t he second set of par ent heses, cont ains . (a per iod)
if a decimal point is mat ched and t he empt y st r ing if it is not .
Retrieving the Entire Pattern: $&
When a pat t er n is mat ched successf ul l y, t he mat ched t ext st r ing is st or ed in t he syst em
var iabl e $&. This is t he onl y way t o r et r ieve t he mat ched pat t er n because t he pat t er n
mat cher r et ur ns a t r ue or f al se val ue indicat ing whet her t he pat t er n mat ch is
successf ul . (This is not st r ict l y t r ue, because you coul d encl ose t he ent ir e pat t er n in
par ent heses and t hen check t he val ue of $1; however , $& is easier t o use in t his case.)
List ing 17.14 is a pr ogr am t hat uses $& t o count al l t he digit s in a set of input f il es.

List ing 17.14. A pr ogr am t hat uses $&.
1: #!/usr/local/bin/perl
2:
3: while ($line = <>) {
4: while ($line =~ /\d/g) {
5: $digitcount[$&]++;
6: }
7: }
8: print ("Totals for each digit:\n");
9: for ($i = 0; $i <= 9; $i++) {
10: print ("$i: $digitcount[$i]\n");
11: }

$ program17_14 file1
Totals for each digit:
0: 11
1: 6
2: 3
3: 1
4: 2
5:
6: 1
7:
8:
9: 1
$
This pr ogr am r eads one l ine at a t ime f r om t he f il es specif ied on t he command
l ine. Line 4 mat ches each digit in t he input l ine in t ur n; t he mat ched digit is st or ed in $&.
Line 5 t akes t he val ue of $& and uses it as t he subscr ipt f or t he ar r ay @digitcount. This
ar r ay keeps a count of t he number of occur r ences of each digit .
When t he input f il es have al l been r ead, l ines 9-11 pr int t he t ot al s f or each digit .
NOTE
If you need t he val ue of $&, be sur e t o get it bef or e
exit ing t he while l oop or ot her st at ement bl ock in which
t he pat t er n is mat ched. (A st at ement bl ock is exit ed
when t he Per l int er pr et er sees a } char act er .)
For exampl e, t he pat t er n mat ched in l ine 4 cannot be
accessed out side of l ines 4-6 because t his copy of $& is
def ined onl y in t hese l ines. (This r ul e al so hol ds t r ue
f or al l t he ot her pat t er n syst em var iabl es def ined in
t oday's l esson.)
The best r ul e t o f ol l ow is t o eit her use or assign a
pat t er n syst em var iabl e immediat el y f ol l owing t he
st at ement t hat mat ches t he pat t er n
Retrieving the Unmatched Text: the $` and $' Variables
When a pat t er n is mat ched, t he t ext of t he mat ch is st or ed in t he syst em var iabl e $&. The
r est of t he st r ing is st or ed in t wo ot her syst em var iabl es:
G The unmat ched t ext pr eceding t he mat ch is st or ed in t he $` var iabl e.
G The unmat ched t ext f ol l owing t he mat ch is st or ed in t he $' var iabl e.
For exampl e, if t he Per l int er pr et er sear ches f or t he /\d+/ pat t er n in t he st r ing
qwerty1234uiop, it mat ches 1234, which is st or ed in $&. The subst r ing qwerty, which
pr ecedes t he mat ch, is st or ed in $`. The r est of t he st r ing, uiop, is st or ed in $'.
If t he beginning of a t ext st r ing is mat ched, $` is set t o t he empt y st r ing. Simil ar l y, if t he
l ast char act er in t he st r ing is par t of t he mat ch, $' is set t o t he empt y st r ing.
The $+ Variable
The $+ var iabl e mat ches t he l ast subpat t er n encl osed in par ent heses. For exampl e, when
t he f ol l owing pat t er n is mat ched, $+ mat ches t he digit s af t er t he decimal point :
/(\d+)\.(\d+)/
This var iabl e is usef ul when t he l ast par t of a pat t er n is t he onl y par t you r eal l y need
t o l ook at .
File System Variables
Sever al syst em var iabl es ar e associat ed wit h f il e var iabl es. One copy of each f il e syst em
var iabl e is def ined f or each f il e t hat is r ef er enced in your Per l pr ogr am. Many of t hese
syst em var iabl es wer e f ir st int r oduced on Day 11. The var iabl es ment ioned t her e ar e
r edef ined her e f or your convenience.
The Default Print Format: $~
When t he write st at ement sends f or mat t ed out put t o a f il e, it uses t he val ue of t he $~
syst em var iabl e f or t hat f il e t o det er mine t he pr int f or mat t o use.
When a pr ogr am st ar t s r unning, t he def aul t val ue of $~ f or each f il e is t he same as t he
name of t he f il e var iabl e t hat r epr esent s t he f il e. For exampl e, when you wr it e t o t he
f il e r epr esent ed by t he f il e var iabl e MYFILE, t he def aul t val ue of $~ is MYFILE. This
means t hat write nor mal l y uses t he MYFILE pr int f or mat . (For t he st andar d out put f il e,
t his def aul t pr int f or mat is named STDOUT.)
If you want t o specif y a dif f er ent pr int f or mat , change t he val ue of $~ bef or e cal l ing
t he write f unct ion. For exampl e, t o use t he pr int f or mat MYFORMAT when wr it ing t o t he
st andar d out put f il e, use t he f ol l owing code:
select (STDOUT); # making sure you are writing to STDOUT
$~ = "MYFORMAT";
write;
This cal l t o write uses MYFORMAT t o f or mat it s out put .
Remember t hat one copy of $~ is def ined f or each f il e
var iabl e. Ther ef or e, t he f ol l owing code is incor r ect :
$~ = "MYFORMAT";
select (MYFILE);
write;
In t his exampl e, t he assignment t o $~ changes t he
def aul t pr int f or mat f or what ever t he cur r ent out put
f il e happens t o be. This assignment does not af f ect t he
def aul t pr int f or mat f or MYFILE because MYFILE is
sel ect ed af t er $~ is assigned. To change t he def aul t
pr int f or mat f or MYFILE, sel ect it f ir st :
select (MYFILE);
$~ = "MYFORMAT";
write;
This cal l t o write now uses MYFORMAT t o wr it e t o MYFILE
Specifying Page Length: $=
The $= var iabl e def ines t he page l engt h (number of l ines per page) f or a par t icul ar
out put f il e. $= is nor mal l y init ial ized t o 60, which is t he val ue t hat t he Per l int er pr et er
assumes is t he page l engt h f or ever y out put f il e. This page l engt h incl udes t he l ines l ef t
f or page header s, and it is t he l engt h t hat wor ks f or most pr int er s.
If you ar e dir ect ing a par t icul ar out put f il e t o a pr int er wit h a nonst andar d page
l engt h, change t he val ue of $= f or t his f il e bef or e wr it ing t o it :
select ("WEIRDLENGTH");
$= = 72;
This code set s t he page l engt h f or t he WEIRDLENGTH f il e t o 72.
$= is set t o 60 by def aul t onl y if a page header f or mat is
def ined f or t he page. If no page header is def ined, $= is set
t o 9999999 because Per l assumes t hat you want your
out put t o be a cont inuous st r eam.
If you want paged out put wit hout a page header , def ine
an empt y page header f or t he out put f il e
Lines Remaining on the Page: $-
The $- var iabl e associat ed wit h a par t icul ar f il e var iabl e l ist s t he number of l ines l ef t
on t he cur r ent page of t hat f il e. Each cal l t o write subt r act s t he number of l ines
pr int ed f r om $-. If write is cal l ed when $- is zer o, a new page is st ar t ed. (If $- is gr eat er
t han zer o, but write is pr int ing mor e l ines t han t he val ue of $-, write st ar t s a new page
in t he middl e of it s pr int ing oper at ion.)
When a new page is st ar t ed, t he init ial val ue of $- is t he val ue st or ed in $=, which is t he
number of l ines on t he page.
The pr ogr am in List ing 17.15 displ ays t he val ue of $-.

List ing 17.15. A pr ogr am t hat displ ays $-.
1: #!/usr/local/bin/perl
2:
3: open (OUTFILE, ">outfile");
4: select ("OUTFILE");
5: write;
6: print STDOUT ("lines to go before write: $-\n");
7: write;
8: print STDOUT ("lines to go after write: $-\n");
9: format OUTFILE =
10: This is a test.
11: .
12: format OUTFILE_TOP =
13: This is a test.
14: .

$ program17_15
lines to go before write: 58
lines to go after write: 57
$
Line 3 opens t he out put f il e outfile and associat es t he f il e var iabl e OUTFILE
wit h t his f il e. Line 4 t hen cal l s select, which set s t he def aul t out put f il e t o OUTFILE.
Line 5 cal l s write, which st ar t s a new page. Line 6 t hen sends t he val ue of $- t o t he
st andar d out put f il e, STDOUT, by specif ying STDOUT in t he cal l t o print. Not e t hat t he
copy of $- pr int ed is t he copy associat ed wit h OUTFILE, not STDOUT, because OUTFILE is
cur r ent l y t he def aul t out put f il e.
Line 7 cal l s write, which sends a l ine of out put t o OUTFILE and decr eases t he val ue of $-
by one. Line 8 pr int s t his new val ue of $-.
NOTE
If you want t o f or ce your next out put t o appear at t he
beginning of a new page, you can set $- t o zer o your sel f
bef or e cal l ing write.
When a f il e is opened, t he copy of $- f or t his f il e is given
t he init ial val ue of zer o. This t echnique ensur es t hat
t he f ir st cal l t o write al ways st ar t s a page (and
gener at es t he header f or t he page)
The Page Header Print Format: $^
When write st ar t s a new page, you can specif y t he page header t hat is t o appear on t he
page. To do t his, def ine a page header pr int f or mat f or t he out put f il e t o which t he page
is t o be sent .
The syst em var iabl e $^ cont ains t he name of t he pr int f or mat t o be used f or pr int ing page
header s. If t his f or mat is def ined, page header s ar e pr int ed; if it does not exist , no page
header s ar e pr int ed.
By def aul t , t he copy of $^ f or a par t icul ar f il e is set equal t o t he name of t he f il e
var iabl e pl us t he st r ing _TOP. For exampl e, f or t he f il e r epr esent ed by t he f il e var iabl e
MYFILE, $^ is given an init ial val ue of MYFILE_TOP.
To change t he page header pr int f or mat f or a par t icul ar f il e, set t he def aul t out put
f il e by cal l ing select, and t hen set $^ t o t he pr int f or mat you want t o use. For exampl e:
select (MYFILE);
$^ = "MYHEADER";
This code changes t he def aul t out put f il e t o MYFILE and t hen changes t he page header
pr int f or mat f or MYFILE t o MYHEADER. As al ways, you must r emember t o select t he f il e
bef or e changing $^ because each f il e has it s own copy of $^.
Buffering Output: $|
When you send out put t o a f il e using print or write, t he oper at ing syst em might not
wr it e it r ight away. Some syst ems f ir st send t he out put t o a special ar r ay known as a
buffer; when t he buf f er becomes f ul l , it is wr it t en al l at once. This pr ocess of out put
buf f er ing is usual l y a mor e ef f icient way t o wr it e dat a.
In some cir cumst ances, you might want t o send out put st r aight t o your out put f il e
wit hout using an int er vening buf f er . (For exampl e, t wo pr ocesses might be sending
out put t o t he st andar d out put f il e at t he same t ime.)
The $| syst em var iabl e indicat es whet her a par t icul ar f il e is buf f er ed. By def aul t , t he
Per l int er pr et er def ines a buf f er f or each out put f il e, and $| is set t o 0. To el iminat e
buf f er ing f or a par t icul ar f il e, sel ect t he f il e and t hen set t he $| var iabl e t o a nonzer o
val ue. For exampl e, t he f ol l owing code el iminat es buf f er ing f or t he MYFILE out put f il e:
select ("MYFILE");
$| = 1;
These st at ement s set MYFILE as t he def aul t out put f il e and t hen t ur n of f buf f er ing f or
it .
If you want t o el iminat e buf f er ing f or a par t icul ar f il e,
you must set $| bef or e wr it ing t o t he f il e f or t he f ir st
t ime because t he oper at ing syst em cr eat es t he buf f er
when it per f or ms t he f ir st wr it e oper at ion
The Current Page Number: $%
Each out put f il e opened by a Per l pr ogr am has a copy of t he $% var iabl e associat ed wit h
it . This var iabl e st or es t he cur r ent page number . When write st ar t s a new page, it adds
one t o t he val ue of $%. Each copy of $% is init ial ized t o 0, which ensur es t hat $% is set t o
1 when t he f ir st page is pr int ed. $% of t en is displ ayed by page header pr int f or mat s.
Array System Variables
The syst em var iabl es you've seen so f ar have al l been scal ar var iabl es. The f ol l owing
sect ions descr ibe t he ar r ay var iabl es t hat ar e aut omat ical l y def ined f or use in Per l
pr ogr ams. Al l of t hese var iabl es, except f or t he @_ var iabl e, ar e gl obal var iabl es: t heir
val ue is t he same t hr oughout a pr ogr am.
The @_ Variable
The @_ var iabl e, which is def ined inside each subr out ine, is a l ist of al l t he ar gument s
passed t o t he subr out ine.
For exampl e, suppose t hat t he subr out ine my_sub is cal l ed as shown her e:
&my_sub("hello", 46, $var);
The val ues hello and 46, pl us t he val ue st or ed in $var, ar e combined int o a t hr ee-
el ement l ist . Inside my_sub, t his l ist is st or ed in @_.
In a subr out ine, t he @_ ar r ay can be r ef er enced or modif ied, just as wit h any ot her ar r ay
var iabl e. Most subr out ines, however , assign @_ t o l ocal l y def ined scal ar var iabl es using
t he local f unct ion:
sub my_sub {
local ($arg1, $arg2, $arg3) = @_;
# more stuff goes here
}
Her e, t he local st at ement def ines t hr ee l ocal var iabl es, $arg1, $arg2, and $arg3. $arg1 is
assigned t he f ir st el ement of t he l ist st or ed in @_, $arg2 is assigned t he second, and $arg3
is assigned t he t hir d.
For mor e inf or mat ion on subr out ines, r ef er t o Day 9, "Using Subr out ines."
NOTE
If t he shift f unct ion is cal l ed inside a subr out ine wit h
no ar gument specif ied, t he @_ var iabl e is assumed, and it s
f ir st el ement is r emoved
The @ARGV Variable
When you r un a Per l pr ogr am, you can specif y val ues t hat ar e t o be passed t o t he
pr ogr am by incl uding t hem on t he command l ine. For exampl e, t he f ol l owing command
cal l s t he Per l pr ogr am myprog and passes it t he val ues hello and 46:
$ myprog "hello" 46
Inside t he Per l pr ogr am, t hese val ues ar e st or ed in a special buil t -in ar r ay named @ARGV.
In t his exampl e, @ARGV cont ains t he l ist ("hello", 46).
Her e is a simpl e st at ement t hat pr int s t he val ues passed on t he command l ine:
print ("@ARGV\n");
The @ARGV ar r ay al so is associat ed wit h t he <> oper at or . This oper at or t r eat s t he
el ement s in @ARGV as f il enames; each f il e named in @ARGV is opened and r ead in t ur n. Ref er
t o Day 6 f or a descr ipt ion of t he <> oper at or .
NOTE
If t he shift f unct ion is cal l ed in t he main body of a
pr ogr am (out side a subr out ine) and no ar gument s ar e
passed wit h it , t he Per l int er pr et er assumes t hat t he
@ARGV ar r ay is t o have it s f ir st el ement r emoved.
The f ol l owing l oop assigns each el ement of @ARGV, in
t ur n, t o t he var iabl e $var:
while ($var = shift) {
# stuff
}
The @F Variable
In Per l , if you specif y t he -n or -p opt ion, you can al so suppl y t he -a opt ion. This opt ion
t el l s t he Per l int er pr et er t o br eak each input l ine int o individual wor ds (t hr owing
away al l t abs and spaces). These wor ds ar e st or ed in t he buil t -in ar r ay var iabl e @F.
Af t er an input l ine has been (aut omat ical l y) r ead, t he @F ar r ay var iabl e behaves l ike
any ot her ar r ay var iabl e.
For mor e inf or mat ion on t he -a, -n, or -p opt ions, r ef er t o Day 16, "Command-Line
Opt ions."
NOTE
When t he -a opt ion is specif ied and an input l ine is
br oken int o wor ds, t he or iginal input l ine can st il l be
accessed because it is st or ed in t he $_ syst em var iabl e
The @INC Variable
The @INC ar r ay var iabl e cont ains a l ist of dir ect or ies t o be sear ched f or f il es r equest ed
by t he require f unct ion. This l ist consist s of t he f ol l owing it ems, in or der f r om f ir st t o
l ast :
G The dir ect or ies specif ied by t he -I opt ion
G The Per l l ibr ar y dir ect or y, which is nor mal l y /usr/local/bin/perl
G The cur r ent wor king dir ect or y (r epr esent ed by t he . char act er )
Like any ar r ay var iabl e, @INC can be added t o or modif ied.
For mor e inf or mat ion on t he require f unct ion, r ef er t o Day 19.
The %INC Variable
The buil t -in associat ive ar r ay %INC l ist s t he f il es r equest ed by t he require f unct ion
t hat have al r eady been f ound.
When require f inds a f il e, t he associat ive ar r ay el ement $INC{file} is def ined, in which
file is t he name of t he f il e. The val ue of t his associat ive ar r ay el ement is t he l ocat ion
of t he act ual f il e.
When require r equest s a f il e, t he Per l int er pr et er f ir st l ooks t o see whet her an
associat ive ar r ay el ement has al r eady been cr eat ed f or t his f il e. This act ion ensur es
t hat t he int er pr et er does not t r y t o incl ude t he same code t wice.
The %ENV Variable
The %ENV associat ive ar r ay l ist s t he envir onment var iabl es def ined f or t his pr ogr am and
t heir val ues. The envir onment var iabl es ar e t he ar r ay subscr ipt s, and t he val ues of t he
var iabl es ar e t he val ues of t he ar r ay el ement s.
For exampl e, t he f ol l owing st at ement assigns t he val ue of t he envir onment var iabl e
TERM t o t he scal ar var iabl e $term:
$term = $ENV{"TERM"};
The %SIG Variable
In t he UNIX envir onment , pr ocesses can send signal s t o ot her pr ocesses. These signal s
can, f or exampl e, int er r upt a r unning pr ogr am, t r igger an al ar m in t he pr ogr am, or kil l
of f t he pr ogr am.
You can cont r ol how your pr ogr am r esponds t o signal s it r eceives. To do t his, modif y t he
%SIG associat ive ar r ay. This ar r ay cont ains one el ement f or each avail abl e signal , wit h
t he signal name ser ving as t he subscr ipt f or t he el ement . For exampl e, t he INT
(int er r upt ) signal is r epr esent ed by t he $SIG{"INT"} el ement .
The val ue of a par t icul ar el ement of %SIG is t he act ion t hat is t o be per f or med when t he
signal is r eceived. By def aul t , t he val ue of an ar r ay el ement is DEFAULT, which t el l s t he
pr ogr am t o do what it nor mal l y does when it r eceives t his signal .
You can over r ide t he def aul t act ion f or some of t he signal s in t wo ways: you can t el l
t he pr ogr am t o ignor e t he signal , or you can def ine your own signal handl er . (Some
signal s, such as KILL, cannot be over r idden.)
To t el l t he pr ogr am t o ignor e a par t icul ar t ype of signal , set t he val ue of t he
associat ive ar r ay el ement f or t his signal t o IGNORE. For exampl e, t he f ol l owing
st at ement indicat es t hat t he pr ogr am is t o ignor e any INT signal s it r eceives:
$SIG{"INT"} = "IGNORE";
If you assign any val ue ot her t han DEFAULT or IGNORE t o a signal ar r ay el ement , t his
val ue is assumed t o be t he name of a f unct ion t hat is t o be execut ed when t his signal is
r eceived. For exampl e, t he f ol l owing st at ement t el l s t he pr ogr am t o jump t o t he
subr out ine named interrupt when it r eceives an INT signal :
$SIG{"INT"} = "interrupt";
Subr out ines t hat can be jumped t o when a signal is r eceived ar e cal l ed interrupt handlers,
because signal s int er r upt nor mal pr ogr am execut ion. List ing 17.16 is an exampl e of a
pr ogr am t hat def ines an int er r upt handl er .

List ing 17.16. A pr ogr am cont aining an int er r upt handl er .
1: #!/usr/local/bin/perl
2:
3: $SIG{"INT"} = "wakeup";
4: sleep();
5:
6: sub wakeup {
7: print ("I have woken up!\n");
8: exit();
9: }

$ program17_16
I have woken up!
$
Line 3 t el l s t he Per l int er pr et er t hat t he pr ogr am is t o jump t o t he wakeup
subr out ine when it r eceives t he INT signal . Line 4 t el l s t he pr ogr am t o go t o sl eep.
Because no ar gument is passed t o sleep, t he pr ogr am wil l sl eep unt il a signal wakes it
up.
To wake up t he pr ocess, get t he pr ocess ID using t he ps command, and t hen send an INT
signal t o t he pr ocess using t he kill command. (See t he manual page f or kill, and t he
r el at ed document at ion f or signal handl ing, t o see how t o per f or m t his t ask in your
envir onment .)
When t he pr ogr am r eceives t he INT signal , it execut es t he wakeup subr out ine. This
subr out ine pr int s t he f ol l owing message and t hen exit s:
I have woken up!
If desir ed, you can use t he same subr out ine t o handl e mor e t han one signal . The signal
act ual l y sent is passed as an ar gument t o t he cal l ed subr out ine, which ensur es t hat
your subr out ine can det er mine which signal t r igger ed it :
sub interrupt {
local ($signal) = @_;
print ("Interrupted by the $signal signal.\n");
}
If a subr out ine exit s nor mal l y, t he pr ogr am r et ur ns t o wher e it was execut ing when it
was int er r upt ed. If a subr out ine cal l s exit or die, t he pr ogr am execut ion is t er minat ed.
NOTE
When a pr ogr am cont inues execut ing af t er being
int er r upt ed, t he el ement of %SIG cor r esponding t o t he
r eceived signal is r eset t o DEFAULT. To ensur e t hat
r epeat ed signal s ar e t r apped by your int er r upt handl er ,
r edef ine t he appr opr iat e el ement of %SIG
Built-In File Variables
Per l pr ovides sever al buil t -in f il e var iabl es, most of which you have pr eviousl y seen. The
onl y f il e var iabl es t hat have not yet been discussed ar e DATA and _ (under scor e). The
ot her s ar e br ief l y descr ibed her e f or t he sake of compl et eness.
STDIN, STDOUT, and STDERR
The f il e var iabl e STDIN is, by def aul t , associat ed wit h t he st andar d input f il e. Using
STDIN wit h t he <> oper at or , as in <STDIN>, nor mal l y r eads dat a f r om your keyboar d. If
your shel l has used < or some equival ent r edir ect ion oper at or t o specif y input f r om a
f il e, <STDIN> r eads f r om t hat f il e.
The f il e var iabl e STDOUT nor mal l y wr it es t o t he st andar d out put f il e, which is usual l y
dir ect ed t o your scr een. If your shel l has used > or t he equival ent t o r edir ect st andar d
out put t o a f il e, wr it ing t o STDOUT sends out put t o t hat f il e.
STDERR r epr esent s t he st andar d er r or f il e, which is al most al ways dir ect ed t o your
scr een. Wr it ing t o STDERR ensur es t hat you see er r or messages even when you have
r edir ect ed t he st andar d out put f il e.
You can associat e STDIN, STDOUT, or STDERR wit h some ot her f il e using open:
open (STDIN, "myinputfile");
open (STDOUT, "myoutputfile");
open (STDERR, "myerrorfile");
Opening a f il e and associat ing it wit h STDIN over r ides t he def aul t val ue of STDIN, which
means t hat you can no l onger r ead f r om t he st andar d input f il e. Simil ar l y, opening a
f il e and associat ing it wit h STDOUT or STDERR means t hat wr it ing t o t hat par t icul ar f il e
var iabl e no l onger sends out put t o t he scr een.
To associat e a f il e var iabl e wit h t he st andar d input f il e af t er you have r edir ect ed
STDIN, specif y a f il ename of -:
open (MYSTDIN, "-");
To associat e a f il e var iabl e wit h t he st andar d out put f il e, specif y a f il ename of >-:
open (MYSTDOUT, ">-");
You can, of cour se, specif y STDIN wit h - or STDOUT wit h >- t o r est or e t he or iginal val ues
of t hese f il e var iabl es.
ARGV
ARGV is a special f il e var iabl e t hat is associat ed wit h t he cur r ent input f il e being r ead by
t he <> oper at or . For exampl e, consider t he f ol l owing st at ement :
$line = <>;
This st at ement r eads f r om t he cur r ent input f il e. Because ARGV r epr esent s t he cur r ent
input f il e, t he pr eceding st at ement is equival ent t o t his:
$line = <ARGV>;
You nor mal l y wil l not need t o access ARGV your sel f except via t he <> oper at or .
DATA
The DATA f il e var iabl e is used wit h t he __END__ special val ue, which can be used t o
indicat e t he end of a pr ogr am. Reading f r om DATA r eads t he l ine af t er __END__, which
enabl es you t o incl ude a pr ogr am and it s dat a in t he same f il e.
List ing 17.17 is an exampl e of a pr ogr am t hat r eads f r om DATA.

List ing 17.17. An exampl e of t he DATA f il e var iabl e.
1: #!/usr/local/bin/perl
2:
3: $line = <DATA>;
4: print ("$line");
5: __END__
6: This is my line of data.

$ program17_17
This is my line of data.
$
The __END__ val ue in l ine 5 indicat es t he end of t he pr ogr am. When l ine 3
r eads f r om t he DATA f il e var iabl e, t he f ir st l ine af t er __END__ is r ead in and is assigned t o
$line. (Subsequent r equest s f or input f r om DATA r ead successive l ines, if any exist .) Line 6
t hen pr int s t his input l ine.
NOTE
For mor e inf or mat ion on __END__ and met hods of
indicat ing t he end of t he pr ogr am, r ef er t o Day 20,
"Miscel l aneous Feat ur es of Per l .
The Underscore File Variable
The _ (under scor e) f il e var iabl e r epr esent s t he f il e specif ied by t he l ast cal l t o eit her
t he stat f unct ion or a f il e t est oper at or . For exampl e:
$readable = -r "/u/jqpublic/myfile";
$writeable = -w _;
Her e, t he _ f il e var iabl e used in t he second st at ement r ef er s t o /u/jqpublic/myfile
because t his is t he f il ename t hat was passed t o -r.
You can use _ anywher e t hat a f il e var iabl e can be used, pr ovided t hat t he f il e has been
opened appr opr iat el y:
if (-T $myoutfile) {
print _ ("here is my output\n");
}
Her e, t he f il e whose name is st or ed in $myoutfile is associat ed wit h _ because t his name
was passed t o -T (which t est s whet her t he f il e is a t ext f il e). The cal l t o print wr it es
out put t o t his f il e.
The main benef it of _ is t hat it saves t ime when you ar e using sever al f il e-t est oper at or s
at once:
if (-r "myfile" || -w _ || -x _) {
print ("I can read, write, or execute myfile.\n");
}
Using _ r at her t han myfile saves t ime because f il e t est oper at or s nor mal l y cal l t he
UNIX syst em f unct ion stat. If you specif y _, t he Per l int er pr et er is t ol d t o use t he
r esul t s of t he pr eceding cal l t o t he UNIX stat f unct ion and t o not bot her cal l ing it
again.
Specifying System Variable Names as Words
As you have seen, t he syst em var iabl es def ined by Per l nor mal l y consist of a $, @ or %
f ol l owed by a singl e non-al phanumer ic char act er . This ensur es t hat you cannot def ine
a var iabl e whose name is ident ical t o t hat of a Per l syst em var iabl e.
If you f ind Per l syst em var iabl e names dif f icul t t o r emember or t ype, Per l 5 pr ovides an
al t er nat ive f or most of t hem. If you add t he st at ement
use English;
at t he t op of your pr ogr am, Per l def ines al t er nat ive var iabl e names t hat mor e cl osel y
r esembl e Engl ish wor ds. This makes it easier t o under st and what your pr ogr am is doing.
Tabl e 17.1 l ist s t hese al t er nat ive var iabl e names.
Tabl e 17.1. Al t er nat ive names f or Per l syst em var iabl es.
Var iabl e Al t er nat ive name(s)
$_
$ARG
$0
$PROGRAM_NAME
$<
$REAL_USER_ID or $UID
$>
$EFFECTIVE_USER_ID or $EUID
$(
$REAL_GROUP_ID or $GID
$)
$EFFECTIVE_GROUP_ID or $EGID
$]
$PERL_VERSION
$/
$INPUT_RECORD_SEPARATOR or $RS
$\
$OUTPUT_RECORD_SEPARATOR or
$ORS
$,
$OUTPUT_FIELD_SEPARATOR or
$OFS
$"
$LIST_SEPARATOR
$#
$OFMT
$@
$EVAL_ERROR
$?
$CHILD_ERROR
$!
$OS_ERROR or $ERRNO
$.
$INPUT_LINE_NUMBER or $NR
$*
$MULTILINE_MATCHING
$[
none (depr ecat ed in Per l 5)
$;
$SUBSCRIPT_SEPARATOR or
$SUBSEP
$:
$FORMAT_LINE_BREAK_CHARACTERS
$$
$PROCESS_ID or $PID
$^A
$ACCUMULATOR
$^D
$DEBUGGING
$^F
$SYSTEM_FD_MAX
$^I
$INPLACE_EDIT
$^L
$FORMAT_FORMFEED
$^P
$PERLDB
$^T
$BASETIME
$^W
$WARNING
$^X
$EXECUTABLE_NAME
$&
$MATCH
$'
$PREMATCH
$'
$POSTMATCH
$+
$LAST_PAREN_MATCH
$~
$FORMAT_NAME
$=
$FORMAT_LINES_PER_PAGE
$-
$FORMAT_LINES_LEFT
$^
$FORMAT_TOP_NAME
$|
$OUTPUT_AUTOFLUSH
$%
$FORMAT_PAGE_NUMBER
Summary
Today you l ear ned about t he buil t -in syst em var iabl es avail abl e wit hin ever y Per l
pr ogr am. These syst em var iabl es ar e divided int o f ive gr oups:
G Gl obal scal ar var iabl es, which ar e def ined ever ywher e in t he pr ogr am and
cont ain a singl e scal ar val ue
G Pat t er n syst em var iabl es, which ar e def ined immediat el y af t er a pat t er n-mat ching
or subst it ut ion oper at ion has been per f or med
G Fil e syst em var iabl es, which ar e def ined f or each input or out put f il e accessibl e
f r om t he pr ogr am
G Ar r ay syst em var iabl es, each of which cont ains a l ist
G Buil t -in f il e var iabl es, which ar e associat ed wit h f il es t hat ar e aut omat ical l y
open or aut omat ical l y avail abl e
You al so l ear ned how t o specif y Engl ish-l anguage equival ent s f or Per l syst em
var iabl es.
Q&A
Q: Why do some syst em var iabl es use special char act er s r at her t han l et t er s in
t heir names?
A: To dist inguish t hem f r om var iabl es t hat you def ine and t o ensur e t hat t he reset
f unct ion (descr ibed in t he next chapt er ) cannot af f ect t hem.
Q: Why do some f unct ions use $_ as t he def aul t , wher eas ot her s do not ?
A: The f unct ions t hat use $_ as t he def aul t ar e t hose t hat ar e l ikel y t o appear in
Per l pr ogr ams specif ied on t he command l ine using t he -e opt ion.
Q: What is t he cur r ent l ine number when $. is used wit h t he <> oper at or ?
A: Ef f ect ivel y, t he <> oper at or t r eat s it s input f il es as if t hey ar e a singl e f il e. This
means t hat $. cont ains t he t ot al number of l ines seen, not t he l ine number of
t he cur r ent input f il e. (If you want $. t o cont ain t he l ine number of t he cur r ent
f il e, set $. t o zer o each t ime eof r et ur ns t r ue.)
Q: Ar e pat t er n syst em var iabl es l ocal or gl obal ?
A: Each pat t er n syst em var iabl e is def ined onl y in t he cur r ent subr out ine or bl ock
of st at ement s.
Q: Why does Per l def ine bot h t he $" and t he $, syst em var iabl es?
A: Some pr ogr ams l ike t o t r eat t he f ol l owing st at ement s dif f er ent l y:
print ("@array");
print (@array);
(In f act , by def aul t , t he f ir st st at ement put s a space bet ween each pair of
el ement s in t he ar r ay, and t he second does not .) The $" and $, var iabl es handl e
t hese t wo separ at e cases.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed, and exer cises t o pr ovide you wit h exper ience in using what you've
l ear ned.
Quiz
1. List t he f unct ions and oper at or s t hat use $_ by def aul t .
2. What do t he f ol l owing var iabl es cont ain?
a. $=
b. $/
c.$ ?
d. $!
d. @_
3. Expl ain t he dif f er ences bet ween ARGV, $ARGV, and @ARGV.
4. Expl ain t he dif f er ence bet ween @INC and %INC.
5. Expl ain t he dif f er ence bet ween $0 and $1.
Exercises
1. Wr it e a pr ogr am t hat r eads l ines of input , r epl aces mul t ipl e bl anks and t abs wit h
a singl e space, conver t s al l upper case l et t er s t o l ower case, and pr int s t he
r esul t ing l ines. Use no expl icit var iabl e names in t his pr ogr am.
2. Wr it e a pr ogr am t hat uses $' and $_ t o r emove al l ext r a spaces f r om input l ines.
3. Wr it e a pr ogr am t hat pr int s t he dir ect or ies in your PATH envir onment var iabl e,
one per l ine.
4. Wr it e a pr ogr am t hat pr int s number s, st ar t ing wit h 1 and cont inuing unt il
int er r upt ed by an INT signal .
5. Wr it e a pr ogr am whose dat a consist s of one or mor e number s per input l ine. Put
t he input l ines in t he pr ogr am f il e it sel f . Add t he number s and pr int t heir t ot al .
6. BUG BUSTER: What is wr ong wit h t he f ol l owing st at ement ?
if ($line =~ /abc/) {
$' =~ s/ +/ /;
}

Chapter 18
References in Perl 5
by Kamran Husain
CONTENTS
G Int r oduct ion t o Ref er ences
G Using Ref er ences
G Using t he Backsl ash Oper at or
G Ref er ences and Ar r ays
G Mul t idimensional Ar r ays
G Ref er ences t o Subr out ines
H Using Subr out ine Templ at es
G Using Subr out ines t o Wor k wit h Mul t ipl e Ar r ays
H Pass By Val ue or By Ref er ence?
G Ref er ences t o Fil e Handl es
H What Does t he *variable Oper at or Do?
G Using Symbol ic Ref er ences Again
H Decl ar ing Var iabl es wit h Cur l y Br aces
G Mor e on Har d Ver sus Symbol ic Ref er ences
G For Mor e Inf or mat ion
G Summar y
G Q&A
G Wor kshop
H Quiz
G Exer cises
Today's l esson descr ibes t he use of Per l r ef er ences and t he concept of point er s. Today's
l esson al so shows you how t o use r ef er ences t o cr eat e compl ex dat a st r uct ur es, pass
point er s ar ound, and wor k wit h subr out ines. You l ear n t he f ol l owing t opics:
G Har d and symbol ic r ef er ences
G Using r ef er ences t o ar r ays and scal ar s
G Passing ar r ays t o subr out ines by r ef er ence
G Ref er ences t o subr out ines
Introduction to References
A reference is simpl y a point er t o somet hing, such as a Per l var iabl e, ar r ay, hash (al so
known as an associat ive ar r ay), or even a subr out ine. The concept of a r ef er ence is
pr obabl y f amil iar t o Pascal or C pr ogr ammer s. A r ef er ence is simpl y an addr ess t o a
val ue. How you use t hat val ue is up t o you as t he pr ogr ammer and what t he l anguage
l et s you get away wit h. In Per l , you can r ef er t o a point er as a r ef er ence; in f act , you
can use t he t er ms point er and r ef er ence int er changeabl y wit hout any l oss of meaning.
Ref er ences ar e usef ul in cr eat ing compl ex dat a st r uct ur es in Per l . In f act , you cannot
r eal l y def ine any compl icat ed st r uct ur es in Per l wit hout using r ef er ences.
The t wo t ypes of r ef er ences in Per l 5 ar e hard and symbolic. A symbol ic r ef er ence
cont ains t he name of a var iabl e. Symbol ic r ef er ences ar e usef ul f or cr eat ing var iabl e
names and addr essing t hem at r unt ime. Basical l y, a symbol ic l ink is l ike t he name of a
f il e or a sof t l ink on a UNIX syst em. Har d r ef er ences ar e mor e l ike har d l inks in t he f il e
syst em (t hat is, mer el y anot her pat h t o t he same under l ying it em).
Per l 4 per mit s onl y symbol ic r ef er ences, which ar e dif f icul t t o use. For exampl e, in Per l
4, you have t o use names t o index t o an associat ive ar r ay cal l ed _main{} of symbol names
f or a package. Per l 5 now l et s you have har d r ef er ences t o dat a.
Har d r ef er ences keep t r ack of r ef er ence count s. When t he r ef er ence count becomes
zer o, Per l aut omat ical l y f r ees t he it em r ef er r ed t o. If t hat it em happens t o be a Per l
object , t he object is destructed-f r eed t o t he memor y pool . Per l is object -or ient ed in it sel f
because ever yt hing in Per l is an object . Packages and modul es make it much easier t o use
object s in Per l .
Har d r ef er ences ar e easy t o use in Per l as l ong as you use t hem as scal ar s. To use har d
r ef er ences as anyt hing but scal ar s, you have t o expl icit l y de-r ef er ence t he var iabl e
and t el l it how you want it t o behave. If t his sounds conf using, don't wor r y; r ef er ences
ar e cover ed on Day 19, "Object -Or ient ed Pr ogr amming in Per l ," t o hel p make t his concept
cl ear er .
Using References
In t oday's l esson, a scal ar val ue r ef er s t o a var iabl e such as $pointer. The var iabl e
$pointer cont ains one dat a it em; whet her t he it em is a number , st r ing, or an addr ess is
det er mined by how you use it .
Any scal ar can hol d a har d r ef er ence, and because ar r ays and hashes do cont ain
scal ar s, it f ol l ows t hat you can now easil y buil d compl ex dat a st r uct ur es of dif f er ent
combinat ions of ar r ays of ar r ays, ar r ays of hashes, hashes of f unct ions, and so on. As
l ong as you under st and t hat you ar e wor king onl y wit h scal ar s, you shoul d be abl e t o
navigat e t hr ough t he most compl ex st r uct ur es wit h pr oper der ef er encing.
Let 's cover some of t he basics f ir st bef or e we get t oo deep int o t he chapt er .
To use t he val ue of $pointer as t he point er t o an ar r ay, you r ef er ence t he it ems in t he
ar r ay as @$pointer. This not at ion of "@$pointer" r oughl y t r ansl at es t o "t ake t he
addr ess in $pointer and t hen use it as an ar r ay." Simil ar l y f or hashes, you woul d use
%$pointer as t he r ef er ence t o t he f ir st el ement in t he hash.
Because t her e ar e sever al ways t o const r uct r ef er ences, you can have r ef er ences t o
just about anyt hing, such as ar r ays, scal ar var iabl es, subr out ines, f il e handl es, and, yes-
t o t he del ight of C pr ogr ammer s-even ot her r ef er ences. Per l gives you t he power t o
wr it e enough compl icat ed code t o hang your sel f .
Now l ook at some of t he ways t hat you can cr eat e and use r ef er ences in Per l .
Using the Backslash Operator
Using t he backsl ash oper at or is anal ogous t o using t he amper sand (&) oper at or in C t o
pass t he addr ess of an oper at or . Usual l y, you use t he backsl ash oper at or t o cr eat e a
second, new r ef er ence t o a var iabl e. The f ol l owing code shows how t o cr eat e a
r ef er ence t o a scal ar var iabl e:
$variable = 22;
$pointer = \$variable;
$ice = "jello"
$iceptr = \$ice;
$pointer point s t o t he l ocat ion t hat cont ains t he val ue of $variable. The point er
$iceptr point s t o "jello". Even if t he or iginal r ef er ence $variable get s dest r oyed, you
can st il l access t he val ue f r om t he $pointer r ef er ence. Ther e is a har d r ef er ence at
wor k her e, so you wil l have t o get r id of bot h $pointer and $variable f or t he space in
which 22 is al l ocat ed t o be f r eed back t o t he memor y pool .
In t he pr eceding code, t he var iabl e $pointer cont ains t he addr ess of $variable, not t he
val ue it sel f . To get t he val ue, you have t o de-r ef er ence $pointer wit h t wo $$. The
f ol l owing sampl e scr ipt shows how t his wor ks:
#!/usr/bin/perl
$value = 10;
$pointer = \$value;
printf "\n Pointer Address $pointer of $value \n";
printf "\n What Pointer *($pointer) points to $$pointer\n";
The $value in t he scr ipt is set t o 10. The $pointer is set t o point t o t he addr ess of $value.
The t wo printf st at ement s show how t he val ue of t he var iabl e is r ef er enced. If you r un
t he scr ipt shown, you see somet hing ver y cl ose t o t he f ol l owing out put :
Pointer Address SCALAR(0x806c520) of 10
What Pointer *(SCALAR(0x806c520)) points to 10
The addr ess in t he out put f r om your scr ipt wil l pr obabl y be dif f er ent f r om what 's
shown. However , you can see t hat $pointer gave t he addr ess and $$pointer gave t he
val ue of t he scal ar t hat $variable point s t o.
Pay at t ent ion t o how t he addr ess is shown in t he point er var iabl e. The wor d SCALAR is
f ol l owed by a l ong hexadecimal number . The wor d SCALAR t el l s you t hat t he addr ess
point s t o a scal ar var iabl e. The number f ol l owing SCALAR is t he addr ess wher e t he
act ual val ue of t he scal ar var iabl e is kept .
NOTE
A point er is an addr ess. The dat a at t hat addr ess is
r ef er r ed t o by a point er . If t he point er happens t o point
t o an inval id addr ess, you can get bad dat a. Gener al l y,
Per l wil l simpl y r et ur n a NULL val ue, but you shoul d not
r el y on t his, and shoul d pr ogr am t o init ial ize al l your
point er s t o r ef er t o val id dat a it ems
References and Arrays
Per haps t he most impor t ant point you must r emember about Per l is t hat al l Per l @ARRAYs
and %HASHes ar e al ways one-dimensional . As such, t he ar r ays and hashes hol d scal ar
val ues onl y and do not dir ect l y cont ain ot her ar r ays or compl ex dat a st r uct ur es. A
member of an ar r ay is eit her a number or a r ef er ence (incl uding st r ings).
You can use t he backsl ash oper at or on ar r ays and hashes just as you woul d f or scal ar
var iabl es. You woul d use somet hing l ike List ing 18.1 f or ar r ays.

List ing 18.1. Using t he backsl ash oper at or on ar r ays.
1 #!/usr/bin/perl
2 #
3 # Using Array references
4 #
5 $pointer = \@ARGV;
6 printf "\n Pointer Address of ARGV = $pointer\n";
7 $i = scalar(@$pointer);
8 printf "\n Number of arguments : $i \n";
9 $i = 0;
10 foreach (@$pointer) {
11 printf "$i : $$pointer[$i++]; \n";
12 }

$ test 1 2 3 4
Pointer Address of ARGV = ARRAY(0x806c378)
Number of arguments : 4
0 : 1;
1 : 2;
2 : 3;
3 : 4;
Examine t he l ines t hat per t ain t o r ef er ences in t he shel l scr ipt shown, which pr int s t he
cont ent s of t he input ar gument ar r ay @ARGV. Line 5 is wher e t he r ef er ence $pointer is
set t o point t o t he ar r ay @ARGV. Line 6 simpl y pr int s t he addr ess of ARGV. You pr obabl y
wil l never have t o use t he addr ess of ARGV, but had you been using anot her ar r ay, t his is
a quick way t o get t o t he addr ess of t he f ir st el ement of t he ar r ay.
NOTE
Point er s ar e r ef er r ed t o as r ef er ences, and vice ver sa
The $pointer r et ur ns t he addr ess of t he f ir st el ement of an ar r ay. In List ing 18.1, t he
ar r ay happened t o be @ARGV. A point er t o an ar r ay shoul d sound f amil iar t o C
pr ogr ammer s because a r ef er ence t o a one-dimensional ar r ay is simpl y a point er t o t he
f ir st el ement of t he ar r ay.
Line 7 cal l s t he f unct ion scalar() (not t o be conf used wit h t he t ype of var iabl e scalar)
t o get t he count of t he number of el ement s in an ar r ay. The par amet er passed in coul d
be @ARGV, but wit h t he point er $pointer, you must specif y t he t ype of par amet er t hat is
expect ed by t he scalar() f unct ion. Ther ef or e, you specif y t he t ype of par amet er as an
ar r ay by using @$pointer.
The t ype of $pointer in t his case is a point er t o t he ar r ay whose number of el ement s you
must r et ur n f r om t he scalar() f unct ion. The cal l t o t he f unct ion has @$pointer as t he
passed par amet er . The $pointer gives t he addr ess of t he f ir st el ement , and t he @ sign
f or ces t he passing of t he addr ess of t he f ir st el ement as an ar r ay r ef er ence.
Line 10 cont ains t he same r ef er ence t o t he ar r ay t hat l ine 7 cont ains. Line 11 l ist s al l
t he el ement s of t he ar r ay using t he $$pointer[$i] it em. How do you int er pr et t his? The
$pointer point s t o t he f ir st el ement in t he ar r ay. The pr ogr am t hen get s t he ($i - 1)-t h
it em in t he ar r ay ($pointer[$i++]) and incr ement s $i. Final l y, t he val ue at
$$pointer[$i] is r et ur ned as a scal ar . Because t he aut oincr ement oper at or is l ow on
t he oper at or pr ecedence pr ior it y l ist , $i is incr ement ed l ast of al l .
You can al so use t he backsl ash oper at or wit h associat ive ar r ays. The idea is t he same-
you ar e subst it ut ing t he $pointer f or al l r ef er ences t o t he name of t he associat ive
ar r ay. The number f ol l owing t he wor d ARRAY in t he point er addr ess of ARGV in t he
pr evious exampl e is t he addr ess of ARGV. The addr ess it sel f won't do you any good,
because most pr ogr ams do not need t his inf or mat ion, but just r eal ize t hat r ef er ences t o
ar r ays and scal ar s ar e displ ayed wit h t he t ype t hat t hey happen t o be point ing t o.
For point er s t o f unct ions, t he addr ess is pr int ed wit h t he wor d CODE, and f or a hash, it is
pr int ed as HASH. See List ing 18.2 f or an exampl e of how t o pr int out an addr ess t o a hash.

List ing 18.2. Using r ef er ences t o a hash.
#!/usr/bin/perl
1#
2 # Using Associative Array references
3 #
4 %month = (
5 '01', 'Jan',
6 '02', 'Feb',
7 '03', 'Mar',
8 '04', 'Apr',
9 '05', 'May',
10 '06', 'Jun',
11 '07', 'Jul',
12 '08', 'Aug',
13 '09', 'Sep',
14 '10', 'Oct',
15 '11', 'Nov',
16 '12', 'Dec',
17 );
18
19 $pointer = \%month;
20
21 printf "\n Address of hash = $pointer\n ";
22
23 #
24 # The following lines would be used to print out the
25 # contents of the associative array if %month was used.
26 #
27 # foreach $i (sort keys %month) {
28 # printf "\n $i $$pointer{$i} ";
29 # }
30
31 #
32 # The reference to the associative array via $pointer
33 #
34 foreach $i (sort keys %$pointer) {
35 printf "$i is $$pointer{$i} \n";
36 }

$ mth
Address of hash = HASH(0x806c52c)
01 is Jan
02 is Feb
03 is Mar
04 is Apr
05 is May
06 is Jun
07 is Jul
08 is Aug
09 is Sep
10 is Oct
11 is Nov
12 is Dec
The r ef er ence t o t he associat ive ar r ay is made wit h t he code in l ine 19,
$pointer = \%month;. As wit h or dinar y ar r ays, t he r ef er ences t o t he el ement s of t he
ar r ay ar e made wit h t he $$pointer{$index} const r uct . Of cour se, because t he ar r ay is
r eal l y a hash, t he $index is t he key int o t he hash and not a number . See l ines 34 and 35
t o see how el ement s in t he ar r ay ar e being r ef er enced.
You don't have t o const r uct associat ive ar r ays using t he comma oper at or . You can use
t he => oper at or inst ead. In t he l at er Per l modul e and sampl e code in t his chapt er , you
wil l see t he => oper at or , which is t he same as t he comma oper at or . Using => makes t he
code a bit easier t o r ead. See List ing 18.3 f or a sampl e usage of t he => oper at or .

List ing 18.3. Using t he => oper at or .
1 #!/usr/bin/perl
2 #
3 # Using Array references
4 #
5 %weekday = (
6 '01' => 'Mon',
7 '02' => 'Tue',
8 '03' => 'Wed',
9 '04' => 'Thu',
10 '05' => 'Fri',
11 '06' => 'Sat',
12 '07' => 'Sun',
13 );
14 $pointer = \%weekday;
15 $i = '05';
16 printf "\n ================== start test ================= \n";
17 #
18 # These next two lines should show an output
19 #
20 printf '$$pointer{$i} is ';
21 printf "$$pointer{$i} \n";
22 printf '${$pointer}{$i} is ';
23 printf "${$pointer}{$i} \n";
24 printf '$pointer->{$i} is ';
25
26 printf "$pointer->{$i}\n";
27 #
28 # These next two lines should not show anything
29 #
30 printf '${$pointer{$i}} is ';
31 printf "${$pointer{$i}} \n";
32 printf '${$pointer->{$i}} is ';
33 printf "${$pointer->{$i}}";
34 printf "\n ================== end of test ================= \n";
35
================== start test =================

$$pointer{$i} is Fri
${$pointer}{$i} is Fri
$pointer->{$i} is Fri
${$pointer{$i}} is
${$pointer->{$i}} is
================== end of test =================
As you can see, t he f ir st t wo l ines pr ovided t he expect ed out put . The f ir st
r ef er ence is used in t he same way as r ef er ences t o r egul ar ar r ays. The second l ine uses
t he ${pointer} and t hen indexes using {$i}, and t he l ef t most $ de-r ef er ences (get s) t he
val ue at t he l ocat ion r eached af t er t he indexing. See Lines 20 t hr ough 23.
NOTE
When in doubt , pr int it out . Al ways use t he pr int
st at ement s in Per l t o pr int out val ues of suspect code.
This way you can be sur e of how Per l is int er pr et ing
your code. Pr int st at ement s ar e a cheap t ool t o use f or
l ear ning how t he Per l int er pr et er wor ks
Then, t wo l ines of t he out put didn't wor k as expect ed. In t he t hir d l ine, $pointer{$i}
t r ies t o r ef er ence an ar r ay wher e t her e is no f ir st el ement . Because t he f ir st el ement
does not point t o a val id st r ing, not hing is pr int ed. Not hing is pr int ed in t he f our t h l ine
of t he out put f or t he same r eason. See l ines 30 t hr ough 33.
Multidimensional Arrays
You cr eat e a r ef er ence t o an ar r ay t hr ough t he st at ement @array = list. You use
squar e br acket s t o cr eat e a r ef er ence t o a compl ex anonymous ar r ay. Consider t he
f ol l owing st at ement , which set s t he par amet er s f or a t hr ee-dimensional dr awing
pr ogr am:
$line = ['solid', 'black', ['1','2','3'] , ['4', '5', '6']];
The pr eceding st at ement const r uct s an ar r ay of f our el ement s. The ar r ay is r ef er r ed t o
by t he scal ar $line. The f ir st t wo el ement s ar e scal ar s, indicat ing t he t ype and col or of
t he l ine t o dr aw. The next t wo el ement s ar e r ef er ences t o anonymous ar r ays and
cont ain t he st ar t ing and ending point s of t he l ine.
To get t o t he el ement s of t he inner ar r ay el ement s, you can use t he f ol l owing
mul t idimensional synt ax:
$arrayReference->[$index]
singl e-dimensional ar r ay
$arrayReference->[$index1][$index2] t wo-dimensional ar r ay
$arrayReference->[$index1][$index2][$index3] t hr ee-dimensional ar r ay
You can cr eat e as compl ex a st r uct ur e as your sanit y, design pr act ices, and comput er
memor y al l ow. Be kind t o t he per son who might have t o manage your code-pl ease keep it
as simpl e as possibl e. On t he ot her hand, if you ar e just t r ying t o impr ess someone wit h
your coding abil it y, Per l gives you a l ot of oppor t unit y t o myst if y your sel f and impr ove
your social l if e.
TIP
When you have mor e t han t hr ee dimensions f or any
ar r ay, consider using a dif f er ent dat a st r uct ur e t o
simpl if y t he code.
Let 's see how cr eat ing ar r ays wit hin ar r ays wor ks in pr act ice. See List ing 18.4 t o see how
t o pr int out t he inf or mat ion point ed at by t he $list r ef er ence.

List ing 18.4. Using mul t i-dimensional ar r ay r ef er ences.
1 #!/usr/bin/perl
2 #
3 # Using Multi-dimensional Array references
4 #
5 $line = ['solid', 'black', ['1','2','3'] , ['4', '5', '6']];
6 print "\$line->[0] = $line->[0] \n";
7 print "\$line->[1] = $line->[1] \n";
8 print "\$line->[2][0] = $line->[2][0] \n";
9 print "\$line->[2][1] = $line->[2][1] \n";
10 print "\$line->[2][2] = $line->[2][2] \n";
11 print "\$line->[3][0] = $line->[3][0] \n";
12 print "\$line->[3][1] = $line->[3][1] \n";
13 print "\$line->[3][2] = $line->[3][2] \n";
14 print "\n"; # The obligatory output beautifier.

$line->[0] = solid
$line->[1] = black
$line->[2][0] = 1
$line->[2][1] = 2
$line->[2][2] = 3
$line->[3][0] = 4
$line->[3][1] = 5
$line->[3][2] = 6
What about t he t hir d dimension f or an ar r ay? Look at a modif ied ver sion of t he same
pr ogr am but add a new t wist t o t he l ist just cr eat ed. See List ing 18.5.

List ing 18.5. Using mul t i-dimensional ar r ay r ef er ences again.
1 #!/usr/bin/perl
2 #
3 # Using Multi-dimensional Array references again
4 #
5 $line = ['solid', 'black', ['1','2','3', ['4', '5', '6']]];
6 print "\$line->[0] = $line->[0] \n";
7 print "\$line->[1] = $line->[1] \n";
8 print "\$line->[2][0] = $line->[2][0] \n";
9 print "\$line->[2][1] = $line->[2][1] \n";
10 print "\$line->[2][2] = $line->[2][2] \n";
11 print "\$line->[2][3][0] = $line->[2][3][0] \n";
12 print "\$line->[2][3][1] = $line->[2][3][1] \n";
13 print "\$line->[2][3][2] = $line->[2][3][2] \n";
14 print "\n";

Ther e is no out put f or t his l ist ing.
In t his exampl e of an ar r ay t hat 's t hr ee deep, you must use a r ef er ence such as
$line ->[2][3][0]. For a C pr ogr ammer , t his is akin t o t he st at ement
Array_pointer[2][3][0], wher e t he point er is point ing t o what 's decl ar ed as an ar r ay
wit h t hr ee indices.
Can you see how easy it is t o set up compl ex st r uct ur es of ar r ays wit hin ar r ays? The
exampl es shown t hus f ar have used onl y har d-coded number s as t he indices. Ther e is
not hing pr event ing you f r om using var iabl es inst ead.
As wit h ar r ay const r uct or s, you can mix and mat ch hashes and ar r ays t o cr eat e as
compl ex a st r uct ur e as you want .
Let 's see how t hese t wo hashes and ar r ays can be combined. List ing 18.6 uses t he point
number s and coor dinat es t o def ine a cube.

List ing 18.6. Def ining a cube.
1 #!/usr/bin/perl
2 #
3 # Using Multi-dimensional Array and Hash references
4 #
5 %cube = (
6 '0', ['0', '0', '0'],
7 '1', ['0', '0', '1'],
8 '2', ['0', '1', '0'],
9 '3', ['0', '1', '1'],
10 '4', ['1', '0', '0'],
11 '5', ['1', '0', '1'],
12 '6', ['1', '1', '0'],
13 '7', ['1', '1', '1']
14 );
15 $pointer = \%cube;
16 print "\n Da Cube \n";
17 foreach $i (sort keys %$pointer) {
18 $list = $$pointer{$i};
19 $x = $list->[0];
20 $y = $list->[1];
21 $z = $list->[2];
22 printf " Point $i = $x,$y,$z \n";
23 }

Ther e is no out put f or t his l ist ing.
In List ing 18.6, %cube cont ains point number s and coor dinat es in a hash. Each
coor dinat e it sel f is an ar r ay of t hr ee number s. The $list var iabl e is used t o get a
r ef er ence t o each coor dinat e def init ion wit h t he f ol l owing st at ement :
$list = $$pointer{$i};
Af t er you get t he l ist , you can r ef er ence of f of it t o get t o each el ement in t he l ist
wit h t he f ol l owing st at ement :
$x = $list->[0];
$y = $list->[1];
The same r esul t -assigning val ues t o $x, $y, and $z-coul d be achieved wit h t he f ol l owing
t wo l ines of code:
($x,$y,$z) = @$list;
$x = $list->[0];
This wor ks because you ar e de-r ef er encing what $list point s t o and using it as an ar r ay,
which in t ur n is assigned t o t he l ist ($x,$y,$z). The $x is st il l assigned wit h t he ->
oper at or .
When you'r e wor king wit h hashes or ar r ays, de-r ef er encing by -> is simil ar t o de-
r ef er encing by $. When you ar e accessing individual ar r ay el ement s, you ar e of t en f aced
wit h wr it ing st at ement s such as t he f ol l owing:
$$names[0] = "Kamran";
$names->[0] = "Kamran";
Bot h l ines ar e equival ent . The $names in t he f ir st l ine has been r epl aced wit h t he ->
oper at or in t he second l ine. In t he case of hashes, t he t wo st at ement s t hat do t he same
t ype of r ef er encing ar e l ist ed as shown in t he f ol l owing code:
$$lastnames{"Kamran"} = "Husain";
$lastnames->{"Kamran"} = "Husain";
Ar r ay r ef er ences ar e cr eat ed aut omat ical l y when t hey ar e f ir st r ef er enced in t he l ef t
side of an equat ion. Using a r ef er ence such as $array[$i] cr eat es an ar r ay int o which
you can index wit h $I. Scal ar s and even mul t idimensional ar r ays ar e cr eat ed t he same
way. The f ol l owing st at ement cr eat es t he contours ar r ay if it did not al r eady exist :
$contours[$x][$y][$z] = &xlate($mouseX,$mouseY);
Ar r ays in Per l can be cr eat ed and gr own on demand. Ref er encing t hem f or t he f ir st t ime
cr eat es t he ar r ay. Ref er encing t hem again at dif f er ent indices cr eat es t he r ef er enced
el ement s f or you.
References to Subroutines
In t he same way you r ef er ence individual it ems such as ar r ays and scal ar var iabl es, you
can al so point t o subr out ines. This is simil ar t o point ing t o a f unct ion in C. To const r uct
such a r ef er ence, you use t he f ol l owing t ype of st at ement :
$pointer_to_sub = sub { ... declaration of sub ... } ;
Not ice t he use of t he semicol on at t he end of t he sub decl ar at ion. The subr out ine
point ed t o by $pointer_to_sub point s t o t he same f unct ion r ef er ence even if t his
st at ement is pl aced in a l oop. This f eat ur e of Per l enabl es you t o decl ar e anonymous
sub() f unct ions in a l oop wit hout wor r ying about whet her you ar e chewing up memor y
by decl ar ing t he same f unct ion over and over .
To cal l a subr out ine by r ef er ence, you must use t he f ol l owing t ype of r ef er ence:
&$pointer_to_sub( parameters );
This code wor ks because you ar e de-r ef er encing t he $pointer_to_sub and using it wit h
t he amper sand (&) as a point er t o a f unct ion. The parameters por t ion might or might not
be empt y depending on how your f unct ion is def ined.
The code wit hin a sub is simpl y a decl ar at ion cr eat ed t hr ough a pr evious st at ement . The
code wit hin t he sub is not execut ed immediat el y, however . It is compil ed and set f or each
use. Consider List ing 18.7.

List ing 18.7. Ref er ences t o subr out ines.
1 #!/usr/bin/perl
2 sub print_coor{
3 my ($x,$y,$z) = @_;
4 print "$x $y $z \n";
5 return $x;};
6 $k = 1;
7 $j = 2;
8 $m = 4;
9 $this = print_coor($k,$j,$m);
10 $that = print_coor(4,5,6);

$ test
1 2 3
4 5 6
This out put r ef l ect s t hat t he assignment of $x, $y, and $z was done when t he
f ir st decl ar at ion of print_coor was encount er ed as a cal l . In List ing 18.7, each
r ef er ence $this and $that point s t o a dif f er ent subr out ine, t he ar gument s t o which
wer e passed at r un- t ime.
Using Subroutine Templates
Subr out ines ar e not l imit ed t o r et ur ning dat a t ypes onl y; t hey can al so r et ur n
r ef er ences t o ot her subr out ines. The r et ur ned subr out ines r un in t he cont ext of t he
cal l ing r out ine but ar e set up in t he or iginal cal l t hat cr eat ed t hem. This behavior is
due t o t he way cl osur e is handl ed in Per l . Closure means t hat if you def ine a f unct ion in
one cont ext , it r uns in t hat par t icul ar cont ext wher e it was f ir st def ined. (See a book
on object -or ient ed pr ogr amming t o get mor e inf or mat ion on cl osur e.)
For an exampl e of how cl osur e wor ks, List ing 18.8 shows code t hat you coul d use t o set
up dif f er ent t ypes of er r or messages. Such subr out ines ar e usef ul in cr eat ing t empl at es
of al l er r or messages.

List ing 18.8. Using cl osur es.
#!/usr/bin/perl
sub errorMsg {
my $lvl = shift;
#
# define the subroutine to run when called.
#
return sub {
my $msg = shift; # Define the error type now.
print "Err Level $lvl:$msg\n"; }; # print later.
}
$severe = errorMsg("Severe");
$fatal = errorMsg("Fatal");
$annoy = errorMsg("Annoying");
&$severe("Divide by zero");
&$fatal("Did you forget to use a semi-colon?");
&$annoy("Uninitialized variable in use");

$severe = errorMsg("Severe");
$fatal = errorMsg("Fatal");
$annoy = errorMsg("Annoying");
The subr out ine errorMsg decl ar ed her e uses a l ocal var iabl e cal l ed lvl.
Af t er t his decl ar at ion, errorMsg uses $lvl in t he subr out ine it r et ur ns t o t he cal l er .
The val ue of $lvl is t her ef or e set in t he cont ext when t he subr out ine errorMsg is f ir st
cal l ed, even t hough t he keywor d my is used. The t hr ee cal l s t hat f ol l ow set up t hr ee
dif f er ent $lvl var iabl e val ues, each in t heir own cont ext :
$severe = errorMsg("Severe");
$fatal = errorMsg("Fatal");
$annoy = errorMsg("Annoying");
When t he subr out ine, errorMsg, r et ur ns, t he val ue of $lvl is r et ained f or each cont ext
in which $lvl was decl ar ed. The $msg val ue f r om t he r ef er enced cal l is used, but t he
val ue of $lvl r emains what was f ir st set in t he act ual cr eat ion of t he f unct ion.
Sounds conf using? It is. This is pr imar il y t he r eason you do not see such code in most Per l
pr ogr ams.
Using Subroutines to Work with Multiple Arrays
Using ar r ays is gr eat f or col l ect ing r el evant inf or mat ion in one pl ace. Now l et 's see
how we can wor k wit h mul t ipl e ar r ays t hr ough subr out ines. You pass one or mor e
ar r ays int o Per l subr out ines by r ef er ence. However , you have t o keep in mind a f ew
subt l e t hings about using t he @_ symbol when you pr ocess t hese ar r ays in t he
subr out ine. Look at List ing 18.9, which is an exampl e of a subr out ine t hat expect s a l ist
of names and a l ist of phone number s.

List ing 18.9. Passing mul t ipl e ar r ays.
1 #!/usr/bin/perl
2 @names = (mickey, goofy, daffy );
3 @phones = (5551234, 5554321, 666 );
4 $i = 0;
5 sub listem {
6 my (@a,@b) = @_;
7 foreach (@a) {
8 print "a[$i] = ". $a[$i] . " " . "\tb[$i] = " . $b[$i]
."\n";
9 $i++;
10 }
11 }
12 &listem(@names, @phones);

a[0] = mickey b[0] =
a[1] = goofy b[1] =
a[2] = daffy b[2] =
a[3] = 5551234 b[3] =
a[4] = 5554321 b[4] =
a[5] = 666 b[5] =
Whoa! What happened t o t he @b ar r ay, and why is t he r est of @a just l ike t he
ar r ay @b? This r esul t occur s because t he ar r ay @_ of par amet er s in a subr out ine is one-I
r epeat , onl y one-l ong l ist of par amet er s. If you pass in f if t y ar r ays, t he @_ is one ar r ay
of al l t he el ement s of t he f if t y ar r ays concat enat ed t oget her .
In t he subr out ine in List ing 18.9, t he assignment my (@a, @b) = @_ get s l oosel y
int er pr et ed by your Per l int er pr et er as, "Let 's see, @a is an ar r ay, so assign one ar r ay
f r om @_ t o @a and t hen assign ever yt hing el se t o @b." Never mind t hat t he @_ is it sel f an
ar r ay and wil l t her ef or e get assigned t o @a, l eaving not hing t o assign t o @b.
To il l ust r at e t his point , l et 's change t he scr ipt t o how it appear s in List ing 18.10.

List ing 18.10. Passing a scal ar and an ar r ay.
#!/usr/bin/perl
@names = (mickey, goofy, daffy );
@phones = (5551234, 5554321, 666 );
$i = 0;
sub listem {
my ($a,@b) = @_;
print " \$a is " . $a . "\n";
foreach (@b) {
print "b[$i] = $b[$i] \n";
$i++;
}
# --------------------------------------------------
# Actually, you could write the for loop as
# foreach (@b) {
# print $_ . "\n" ;
# }
# This your secret answer to Quiz question 18.4.
# ----------------------------------------------------
}
&listem(@names, @phones);

$ testArray
$a is mickey
b[0] = goofy
b[1] = daffy
b[2] = 5551234
b[3] = 5554321
b[4] = 666
Do you see how $a was assigned t he f ir st val ue and t hen @b was assigned t he
r est of t he val ues? In or der get ar ound t his @_ int er pr et at ion f eat ur e and pass ar r ays
int o subr out ines, you have t o pass ar r ays in by r ef er ence, which you do by modif ying t he
scr ipt t o l ook l ike t he f ol l owing:
#!/usr/bin/perl
@names = (mickey, goofy, daffy );
@phones = (5551234, 5554321, 666 );
$i = 0;
sub listem {
my ($a,$b) = @_;
foreach (@$a) {
print "a[$i] = " . @$a[$i] . " " . "\tb[$i] = " . @$b[$i]
."\n";
$i++;
}
}
&listem(\@names, \@phones);
The f ol l owing major changes wer e necessar y t o br ing t he or iginal scr ipt t o t his point :
G The l ocal var iabl es f or t he sub listem ar e now scal ar s, not ar r ay r ef er ences. As a
r esul t , $a is t he f ir st it em on t he @_ l ist , and $b is t he second it em.
G The l ocal par amet er s ($a and $b) ar e used as ar r ay r ef er ences wit h t he st at ement s
@$a and @$b, r espect ivel y.
G The cal l t o t he subr out ine passes t he r ef er ences t o t he ar r ays wit h t he backsl ash,
\@names and \@phones, t hus passing onl y t wo it ems t o t he subr out ine.
The f ol l owing out put mat ches what we expect ed:
$ testArray2
a[0] = mickey b[0] = 5551234
a[1] = goofy b[1] = 5554321
a[2] = daffy b[2] = 666
DO pass by r ef er ence whenever possibl e.
DO pass ar r ays by r ef er ence when you ar e passing mor e
t han one ar r ay t o a subr out ine.
DON' T use (@variable)=@_ in a subr out ine unl ess you
want t o concat enat e al l t he passed par amet er s int o one
l ong ar r ay
Pass By Value or By Reference?
When used in a subr out ine ar gument l ist , scal ar var iabl es ar e al ways passed by
r ef er ence. You do not have a choice her e. You can, however , modif y t he val ues of t hese
var iabl es if you r eal l y want t o. To access t hese var iabl es, you can use t he @_ ar r ay and
index each individual el ement in it using $_[$index], wher e $index count s f r om zer o up.
Ar r ays and hashes ar e dif f er ent beast s al t oget her . You can eit her pass t hem as
r ef er ences once or pass r ef er ences t o each el ement in t he ar r ay. For l ong ar r ays, t he
choice shoul d be f air l y obvious-pass t he r ef er ence t o t he ar r ay onl y. In eit her case, you
can use t he r ef er ences t o modif y what you want in t he or iginal ar r ay.
The @_ mechanism concat enat es al l t he input ar r ays in a subr out ine int o one l ong
ar r ay. This f eat ur e is nice if you do want t o pr ocess t he incoming ar r ays as one l ong
ar r ay. Usual l y, you want t o keep t he ar r ays separ at e when you pr ocess t hem in a
subr out ine, and passing by r ef er ence is t he best way t o do t hat . Hol d t hat t hought :
Don't use gl obal s.
In shor t , pass by r ef er ence and r espect t he val ue of any gl obal var iabl e unl ess t her e is a
st r ong compel l ing r eason not t o.
References to File Handles
Somet imes, you have t o wr it e t he same out put t o dif f er ent out put f il es. For exampl e, an
appl icat ion pr ogr ammer might want t he out put t o go t o t he scr een in one inst ance, t he
pr int er in anot her , and a f il e in anot her -or even al l t hr ee at t he same t ime. Rat her
t han make separ at e st at ement s f or each handl e, it woul d be nice t o wr it e somet hing l ike
t he f ol l owing:
spitOut(\*STDIN);
spitOut(\*LPHANDLE);
spitOut(\*LOGHANDLE);
Not ice t hat t he f il e handl e r ef er ence is sent wit h t he \*FILEHANDLE synt ax because you
r ef er t o t he symbol t abl e in t he cur r ent package. In t he subr out ine t hat handl es t he
out put t o t he f il e handl e, you woul d have code t hat l ooks somet hing l ike t he
f ol l owing:
sub spitOut {
my $fh = shift;
print $fh "Gee Wilbur, I like this lettuce\n";
}
What Does the *variable Operator Do?
In UNIX (and ot her oper at ing syst ems), t he ast er isk is a sor t of wil dcar d oper at or . In
Per l , you can r ef er t o ot her var iabl es and so on by using t he ast er isk oper at or :
*iceCream;
When used in t his manner , t he ast er isk is al so known as a typeglob. The ast er isk at t he
beginning of a t er m can be t hought of as a wil dcar d mat ch f or al l t he mangl ed names
gener at ed int er nal l y by Per l .
You can use a t ypegl ob in t he same way you use a r ef er ence because t he de-r ef er ence
synt ax al ways indicat es t he kind of r ef er ence you want . ${*iceCream} and
${\$iceCream} bot h indicat e t he same scal ar var iabl e. Basical l y, *iceCream r ef er s t o t he
ent r y in t he int er nal _main associat ive ar r ay of al l symbol names f or t he _main package.
*kamran r eal l y t r ansl at es t o $_main{'kamran'} if you ar e in t he _main package cont ext .
If you ar e in anot her package, t he _packageName{} hash is used.
When eval uat ed, a t ypegl ob pr oduces a scal ar val ue t hat r epr esent s t he f ir st object s of
t hat name. This incl udes f il e handl es, f or mat specif ier s, and subr out ines.
Using Symbolic References Again
Using br acket s ar ound r ef er ences makes const r uct ing st r ings easier :
$road = ($w) ? "free":"high";
print "${road}way";
The pr eceding l ine pr int s highway or freeway depending on t he val ue of $w. This synt ax
wil l be f amil iar t o you if you wr it e make f il es or shel l scr ipt s. In f act , you can use t his
${variable} const r uct out side of doubl e quot es, as in t he f ol l owing exampl e:
print ${road};
print ${road} . "way";
print ${ road } . "way";
You can al so use r eser ved wor ds in t he ${ } br acket s. Check out t he f ol l owing l ines:
$if = "road";
print "\n ${if} way \n";
Using r eser ved wor ds f or anyt hing ot her t han t heir int ended pur pose, however , is
pl aying wit h f ir e. Be imaginat ive and make up your own var iabl es. You can use r eser ved
wor ds but wil l have t o r emember t o f or ce int er pr et at ion as a r eser ved wor d by adding
anyt hing t hat makes it mor e t han a r ef er ence. It 's gener al l y not a good idea t o use a
var iabl e cal l ed ${while}, because it is conf using t o r ead.
When you wor k wit h hashes, you have t o cr eat e an ext r a r ef er ence t o t he index. In
ot her wor ds, you cannot use somet hing l ike t his:
$clients { \$credit } = "despicable" ;
The \$credit var iabl e wil l be conver t ed t o a st r ing and won't be used cor r ect l y as an
index in t he hash. You have t o use a t wo-st ep pr ocedur e such as t his:
$chist = \@credit;
$x{ $chist } = "despicable";
Declaring Variables with Curly Braces
The pr eceding sect ion br ings up an int er est ing point about cur l y br aces f or a use ot her
t han indexing int o hashes. In Per l , cur l y br aces ar e usual l y r eser ved f or del imit ing
bl ocks of code. Assume you wer e r et ur ning t he passed l ist by sor t ing it in r ever se or der .
The passed l ist is in @_ of t he cal l ed subr out ine, so t he f ol l owing t wo st at ement s ar e
equival ent :
sub backward {
{ reverse sort @_ ; }
};
sub backward {
reverse sort @_ ;
};
When pr eceded by t he @ oper at or , cur l y br aces enabl e you t o set up smal l bl ocks of
eval uat ed code.
#!/usr/bin/perl
sub average {
($a,$b,$c) = @_;
$x = $a + $b + $c;
$x2 = $a*$a + $b*$b + $c*$c;
return ($x/3, $x2/3 ); }
$x = 1;
$y = 34;
$x = 47;
print "The midpt is @{[&average($x,$y,$z)]} \n";
This scr ipt pr int s 27 and 1121.6666. In t he l ast l ine of code wit h t he @{} in t he doubl e-
quot ed st r ing, t he cont ent s of t he @{} ar e eval uat ed as a bl ock of code. The bl ock
cr eat es a r ef er ence t o an anonymous ar r ay t hat cont ains t he r esul t s of t he cal l t o t he
subr out ine average($x,$y,$z). The ar r ay is const r uct ed because of t he br acket s ar ound
t he cal l . As a r esul t , t he [] const r uct r et ur ns a r ef er ence t o an ar r ay, which in t ur n is
conver t ed by @{} int o a st r ing and inser t ed int o t he doubl e-quot ed st r ing.
More on Hard Versus Symbolic References
By now, you shoul d be abl e t o see t he dif f er ence bet ween har d and symbol ic l inks. Let 's
l ook at some of t he minor det ail s of t he t wo t ypes of l inks and how t hese l inks ar e
handl ed in Per l .
When you use a symbol ic r ef er ence t hat does not exist , Per l cr eat es t he var iabl e f or
you and uses it . For var iabl es t hat al r eady exist , t he val ue of t he var iabl e is
subst it ut ed f or t he $variable st r ing. This subst it ut ion is a power f ul f eat ur e of Per l
because you can const r uct var iabl e names f r om var iabl e names.
Consider t he f ol l owing exampl e:
1 $lang = "java";
2 $java = "coffee";
3 print "${lang}\n";
4 print "hot${lang}\n";
5 print "$$lang \n"
Look at l ine 5. The $$lang is f ir st r educed t o $java. Then r ecognizing t hat $java can
al so be r e-par sed, t he val ue of $java ("coffee") is used.
The val ue of t he scal ar pr oduced by $$lang is t aken t o be t he name of a new var iabl e,
and t he var iabl e at $name is used. The f ol l owing is t he out put f r om t his exampl e:
java
hotjava
coffee
The dif f er ence bet ween a har d r ef er ence ($lang) and a symbol ic r ef er ence ($$lang) is
how t he var iabl e name is der ived. Wit h a har d r ef er ence, you ar e r ef er r ing t o a
var iabl e's val ue dir ect l y. Eit her t he var iabl e exist s in t he symbol t abl e f or t he package
you ar e in (t hat is, which l exical cont ext you ar e in), or t he var iabl e does not exist .
Wit h a symbol ic r ef er ence, you ar e using anot her l evel of indir ect ion by const r uct ing
or der iving a symbol name f r om an exist ing var iabl e.
To f or ce onl y har d r ef er ences in a pr ogr am and pr ot ect your sel f f r om accident al l y
cr eat ing symbol ic r ef er ences, you can use t he modul e cal l ed strict, which f or ces Per l
t o do st r ict t ype checking. To use t his modul e, pl ace t he f ol l owing st at ement at t he t op
of your Per l scr ipt :
use strict 'refs';
Fr om t his point on, onl y har d r ef er ences ar e al l owed f or t he r est of t he scr ipt . You
pl ace t his use strict ... st at ement wit hin cur l y br aces t o l imit t he t ype checking t o
t he code bl ock wit hin t he br aces. For exampl e, in t he f ol l owing code, t he t ype checking
woul d be l imit ed t o t he code in t he subr out ine java():
sub java {
use strict "refs";
#
# type checking here.
}
...
# no type checking here.
To t ur n of f t he st r ict t ype checking at any t ime wit hin a code bl ock, use t his st at ement :
no strict 'refs';
One l ast point : Symbol ic r ef er ences cannot be used on var iabl es decl ar ed wit h t he my
const r uct because t hese var iabl es ar e not kept in any symbol t abl e. Var iabl es decl ar ed
wit h t he my const r uct ar e val id onl y f or t he bl ock in which t hey ar e cr eat ed. Var iabl es
decl ar ed wit h t he local wor d ar e visibl e t o al l ensuing l ower code bl ocks because t hey
ar e in a symbol t abl e.
For More Information
In addit ion t o consul t ing t he obvious document s such as t he Per l man pages, l ook at t he
Per l sour ce code f or mor e inf or mat ion. The 't/op' dir ect or y in t he Per l sour ce t r ee has
some r egr ession t est r out ines t hat shoul d def init el y get you t hinking. A l ot of
document s and r ef er ences ar e avail abl e at t he Web sit es www.perl.com and
www.metronet.com.
Summary
The t wo t ypes of r ef er ences in Per l 5 ar e har d and symbol ic. Har d l inks wor k l ike har d
l inks in UNIX f il e syst ems. You can have mor e t han one har d l ink t o t he same it em; Per l
keeps a r ef er ence count f or you. This r ef er ence count is incr ement ed or decr ement ed as
r ef er ences t o t he it em ar e cr eat ed or dest r oyed. When t he count goes t o zer o, t he l ink
and t he object it is point ing t o ar e bot h dest r oyed. Symbol ic l inks, which ar e cr eat ed
t hr ough t he ${} const r uct , ar e usef ul in pr oviding mul t ipl e st ages of r ef er ences t o
object s.
You can have r ef er ences t o scal ar s, ar r ays, hashes, subr out ines, and even ot her
r ef er ences. Ref er ences t hemsel ves ar e scal ar s and have t o be de-r ef er enced t o t he
cont ext bef or e being used. Use @$pointer f or an ar r ay, %$pointer f or a hash, &$pointer
f or a subr out ine, and so on f or der ef er encing.
Mul t idimensional ar r ays ar e possibl e using r ef er ences in ar r ays and hashes.
Par amet er s ar e passed int o a subr out ine t hr ough r ef er ences. The @_ ar r ay is r eal l y al l
t he passed par amet er s concat enat ed in one l ong ar r ay. To send separ at e ar r ays, use t he
r ef er ences t o t he individual it ems.
Tomor r ow's l esson cover s Per l object s and r ef er ences t o object s. We have del iber at el y
not cover ed Per l object s in t his chapt er because it r equir es some knowl edge of
r ef er ences. Ref er ences ar e used t o cr eat e and r ef er t o object s, const r uct or s, and
packages.
Q&A
Q: How do I know what t ype of addr ess a point er is point ing t o?
A: The addr ess pr int ed out wit h t he print st at ement on a r ef er ence has a qual if ier
wor d in f r ont of it . For exampl e, a r ef er ence t o a hash has t he wor d HASH
f ol l owed by an addr ess val ue, an ar r ay has t he wor d ARRAY, and so on.
Q: How ar e mul t idimensional ar r ays possibl e using Per l ?
A: Ref er ences in Per l point t o scal ar s onl y. Ref er ences t o ar r ays point t o t he
beginning of t he ar r ay. Ar r ays can cont ain r ef er ences t o ot her ar r ays, hashes,
and so on. The way t o cr eat e mul t idimensional ar r ays in Per l is by using
r ef er ences t o r ef er ences.
Q: What ' s t he best way t o pass mor e t han one ar r ay int o a subr out ine?
A: Pass r ef er ences t o t he ar r ays, using t he \@arrayname f or each ar r ay passed-as in
t he f ol l owing cal l :
mysub(\@one, \@two);
Wit hin t he subr out ine, t ake each r ef er ence of f one at a t ime.
my ($a, $b) = @_;
Now use @$a and @$b t o get t o t he ar r ays passed int o t he subr out ines.
Q: Why is *moo mor e ef f icient t o use t han $_main{'moo'}? Is t her e a dif f er ence
in usage?
A: Bot h *moo and $_main{'moo'} mean t he same var iabl e (as l ong as you ar en't using
a package). *moo is mor e ef f icient because t he r ef er ence is l ooked up once at
compil e t ime, wher eas $_main{'moo'} is eval uat ed at r unt ime and eval uat ed each
t ime it is r un.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed and exer cises t o give you exper ience in using what you've l ear ned. Tr y
and under st and t he quiz and exer cise answer s bef or e you go on t o t omor r ow's l esson.
Quiz
1. Given t hat $pointer is a point er t o a hash, what 's wr ong wit h t he f ol l owing l ine
of code?
$x= ${$pointer->{$i}};
2. Why is $b not being set in t he f ol l owing l ine of code? What do you have t o do t o
make it okay?
sub xxx {
my ($a, $b) = @_;
}
3. What 's t he dif f er ence bet ween t hese t wo l ines of code?
printf "$i : $$pointer[$i++]; ";
printf " and $i : $pointer->[$i++]; \n";
4. What do t he f ol l owing l ines of code pr int out ?
$HelpHelpHelp = \\\"Help";
print $$$$HelpHelpHelp;
5. What 's t he use of t he ${variable} const r uct ? How coul d t he f ol l owing t hr ee
l ines of code be r ewr it t en?
$name = ${$scalarref};
draw(@{$coordinates}, $display);
${$months}[0] = "March";
Exercises
1. Wr it e a Per l scr ipt t o pr int out addr ess t ypes of dif f er ent var iabl es and compl ex
st r uct ur es.
2. Wr it e a Per l code f r agment t hat const r uct s an ar r ay of point er s t o f unct ions.
How woul d you use it ?
St r ong Hint :
$foo = sub foo { print "foo\n"; }
$bar = sub bar { print "bar\n"; }
$yuk = sub yuk { print "yuk\n"; }
$huh = sub huh { print "huh\n"; }
@list = ($foo, $bar, $yuk, $huh);
3. Expl ain t he dif f er ence bet ween har d and symbol ic r ef er ences.
4. Wr it e a Per l subr out ine t hat t akes t wo ar r ays as ar gument s and r et ur ns t he
r ever se-sor t ed copy of each ar r ay.
5. Modif y t he f ol l owing scr ipt t o pr int t he val ue of $this and $that. Ar e t hey t he
same? If not , why not ?
#!/usr/bin/perl
sub print_coor{
my ($x,$y,$z) = @_;
print "$x $y $z \n";
return $x;};
$k = 1;
$j = 2;
$m = 4;
$this = print_coor($k,$j,$m);
$that = print_coor(4,5,6);

Chapter 19
Object-Oriented Programming in Perl
by Kamran Husain
CONTENTS
G An Int r oduct ion t o Modul es
H The Thr ee Impor t ant Rul es
G Cl asses in Per l
G Cr eat ing a Cl ass
G Bl essing a Const r uct or
H Inst ance Var iabl es
G Met hods
G Expor t ing Met hods
G Invoking Met hods
G Over r ides
G Dest r uct or s
G Inher it ance
G Over r iding Met hods
G A Few Comment s About Cl asses and Object s in Per l
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson t eaches you how t o use t he object -or ient ed pr ogr amming (OOP) f eat ur es
of Per l as wel l as how t o const r uct object s in Per l . The discussion al so incl udes
inher it ance, over r iding met hods, and dat a encapsul at ion.
An Introduction to Modules
A module is a Per l package. Object s in Per l ar e based on r ef er ences t o dat a it ems wit hin a
package. An object in Per l is simpl y a r ef er ence t o somet hing t hat knows which cl ass it
bel ongs t o. (Ref er ences ar e cover ed on Day 18, "Ref er ences in Per l 5.") For mor e
inf or mat ion, you can consul t t he perlmod and perlobj t ext f il es at
http://www.metronet.com. These f il es ar e t he pr imar y sour ce of inf or mat ion on t he
Int er net about Per l modul es.
In object -or ient ed pr ogr amming wit h ot her l anguages, you decl ar e a cl ass and t hen
cr eat e object s of t hat cl ass. Al l object s of a par t icul ar cl ass behave in a cer t ain way,
which is gover ned by t he met hods of t hat cl ass. You can cr eat e new cl asses by def ining
new ones or by inher it ing pr oper t ies f r om an exist ing cl ass.
Pr ogr ammer s al r eady f amil iar wit h object -or ient ed pr incipl es wil l r ecognize t he
t er minol ogy used her e. Per l is, and pr et t y much al ways has been, an object -or ient ed
l anguage. In Per l 4, t he use of packages pr ovides dif f er ent symbol t abl es f r om which t o
choose symbol names. Per l 5 changes t he synt ax a bit and somewhat f or mal izes t he use
of object s.
The Three Important Rules
The next t hr ee decl ar at ions ar e ext r emel y impor t ant t o under st anding how object s,
cl asses, and met hods wor k in Per l .
G A class is a Per l package. This package f or a cl ass pr ovides t he met hods f or object s.
G A method is simpl y a Per l subr out ine. The onl y cat ch wit h wr it ing such met hods is
t hat t he name of t he cl ass is t he f ir st ar gument .
G An object in Per l is simpl y a r ef er ence t o some dat a it em wit hin t he cl ass.
The r est of t oday's l esson cover s each of t he pr eceding it ems in mor e det ail .
Classes in Perl
One r ul e is impor t ant enough t o r epeat : A Per l cl ass is simpl y a package. When you see a
Per l document t hat r ef er s t o a "cl ass," t hink "package." Exist ing Per l 5 synt ax enabl es
you t o cr eat e a cl ass. If you ar e al r eady a C pr ogr ammer , you do not have t o know a l ot
of new synt ax. What might be a new concept t o Per l 4 pr ogr ammer s is t he use of t he
doubl e col on (::) t o signif y t he base and inher it ed cl asses.
One of t he key f eat ur es of OOP is inher it ance. The inher it ance f eat ur e of f er ed by Per l ,
however , is not t he same as you might expect f r om ot her object -or ient ed l anguages. Per l
cl asses inher it met hods onl y; you must use your own mechanisms t o impl ement dat a
inher it ance.
Because each cl ass is a package, it has it s own name space wit h it s own associat ive ar r ay
of symbol names. Each cl ass can t her ef or e use it s own independent set of symbol names.
As wit h package r ef er ences, you can addr ess t he var iabl es in a cl ass wit h t he back quot e
(') oper at or . Member s of a cl ass ar e addr essed as $class'$member. In Per l 5, you can use
t he doubl e col on inst ead of t he ' t o get t he r ef er ence. For exampl e, $class'member is
t he same as $class::$member.
Creating a Class
This sect ion cover s t he r equisit e st eps t o t ake when you cr eat e a new cl ass. The exampl e
il l ust r at es t he semant ics in t he cr eat ion of a simpl e cl ass cal l ed Cocoa, which is used f or
pr int ing t he r equir ed par t s of a sour ce code f il e f or a simpl e Java appl icat ion. You wil l
not become a Java exper t , nor wil l t his package r equir e you t o have any exper ience in
Java; t he f ocus is t he concept of cr eat ing a cl ass. The exampl e coul d have just as easil y
used a phone book appl icat ion, but how many simil ar exampl es have you al r eady seen in
books?
NOTE
I am cur r ent l y st il l devel oping t he package Java.pm. It 's
named Cocoa.pm in devel opment because it does not have
t he high caf f eine cont ent of a f ul l -f eat ur ed, or even
mil dl y usef ul , Java.pm package. Per haps af t er r eading
t oday's l esson you wil l be abl e t o cont r ibut e t o t he
Java.pm Per l package; if so, send e-mail t o
khusain@ikra.com.
Time now f or a shamel ess pl ug f or Perl Unleashed, which is
al so by Sams Publ ishing, due t he summer of 1996. It wil l
cont ain gobs of inf or mat ion about wr it ing and using
cl asses and packages-and t r ack t he init ial devel opment
st ages of t he Java.pm package. (Hmmm. Maybe t he
package shoul d be cal l ed Bean.pm in it s ear l y st ages.)
Fir st of al l , cr eat e a package f il e cal l ed Cocoa.pm. (The .pm ext ension, which is t he
def aul t ext ension f or packages, st ands f or Per l modul e.) A modul e is a package, and a
package is a cl ass f or al l pr act ical pur poses. Bef or e you do anyt hing el se, pl ace a 1; in
t he f il e. As you add mor e l ines t o t he package f il e, make sur e you keep t he 1; as t he l ast
l ine. The f ol l owing code shows t he basic st r uct ur e of t he f il e:
package Cocoa;
#
# Put "require" statements in for all required,imported packages
#
#
# Just add code here
#
1; # terminate the package with the required 1;
This r equir ement is impor t ant : Don't f or get t o al ways keep t he 1; l ine as t he l ast of t he
package f il e. This st at ement is r equir ed f or al l packages in Per l . If you f or get t his
st at ement , your package wil l not be pr ocessed by Per l .
Congr at ul at ions; you have just cr eat ed your f ir st package f il e. Now you ar e r eady t o
add your met hods t o t his package and make it a cl ass. The f ir st met hod you shoul d add is
t he new() met hod, which must be cal l ed whenever you cr eat e a new object . The new()
met hod is t he const r uct or f or t he object .
Blessing a Constructor
A constructor is a Per l subr out ine in a cl ass t hat r et ur ns a r ef er ence t o somet hing t hat
has t he cl ass name at t ached t o it . Connect ing a cl ass name wit h a r ef er ence is r ef er r ed
t o as "bl essing" an object because t he f unct ion t o est abl ish t he connect ion is cal l ed
bless.
The f ol l owing code segment shows t he synt ax f or t he bless f unct ion:
bless YeReference [,classname]
YeReference is t he r ef er ence t o t he object being bl essed. The classname is opt ional and
specif ies t he name of t he package f r om which t he object wil l get met hods. If t he
classname is not specif ied, t he name of t he cur r ent package is used inst ead.
The way t o cr eat e a const r uct or in Per l is t o r et ur n a r ef er ence t o an int er nal
st r uct ur e t hat has been bl essed int o t his Cocoa cl ass. List ing 19.1 shows t he init ial
Cocoa.pm package.

List ing 19.1. The init ial Cocoa.pm package. package Cocoa;
sub new {
my $this = {}; # Create an anonymous hash, and #self points to
it.
bless $this; # Connect the hash to the package Cocoa.
return $this; # Return the reference to the hash.
}
1;

Ther e is no out put f or List ing 19.1.
The {} const r uct s a r ef er ence t o a hash t hat cont ains no key/val ue pair s.
The r et ur ned val ue t o t his hash is assigned t o t he l ocal var iabl e $this. The
bless() f unct ion t akes t hat r ef er ence t o $this, t el l s t he obj ect it r ef er ences
t hat it ' s now a Cocoa, and r et ur ns t he r ef er ence.
The r et ur ned val ue t o t he cal l ing f unct ion now r ef er s t o t his anonymous hash. On
r et ur n f r om t he new() f unct ion, t he $this r ef er ence is dest r oyed, but t he cal l ing
f unct ion keeps a r ef er ence t o t his hash. Ther ef or e, t he r ef er ence count t o t he
hash won' t be zer o and Per l keeps t he hash in memor y. (You do not have t o keep it
ar ound, but it ' s nice t o have it ar ound f or r ef er ence l at er .)
To cr eat e an obj ect , you make a cal l such as t he f ol l owing:
$cup = new Cocoa;
List ing 19.2 shows you how t o use t his package t o cr eat e t he const r uct or .

List ing 19.2. Cr eat ing t he const r uct or .
1 #!/usr/bin/perl
2 push (@INC,'pwd');
3 use Cocoa;
4 $cup = new Cocoa;
Line 1 r ef er s t o t he l ocat ion of t he Per l int er pr et er t o use. Your Per l
int er pr et er may be l ocat ed at /usr/local/bin/perl or wher ever you inst al l ed it .
In l ine 2, t he l ocal dir ect or y is added t o t he sear ch pat h in @INC f or t he l ist of
pat hs t o use when l ooking f or a package. You can cr eat e your modul e in a
dif f er ent dir ect or y and specif y t he pat h expl icit l y t her e. Had I cr eat ed t he
package in /home/khusain/test/scripts/, l ine 2 woul d r ead as f ol l ows:
push (@INC,"/home/khusain/test/scripts");
In l ine 3, you incl ude t he package Cocoa.pm t o get al l t he f unct ional it y in your
scr ipt . The use st at ement asks Per l t o l ook in t he @INC pat h f or a f il e named
Cocoa.pm and incl ude it in t he copy of t he sour ce f il e being par sed. The use
st at ement is r equir ed if you want t o wor k wit h a cl ass.
Line 4 cr eat es t he Cocoa obj ect by cal l ing t he new f unct ion on it . Now comes t he
beaut y (and conf usion and power ) of Per l . Ther e is mor e t han one way t o do t his.
You can r ewr it e l ine 4 as t he f ol l owing:
$cup = Cocoa->new();
If you ar e a C pr ogr ammer , you can use t he doubl e col ons (::) t o f or ce t he
f unct ion new() f r om t he Cocoa package. As a r esul t , l ine 4 coul d al so be wr it t en as
t he f ol l owing:
$cup = Cocoa::new();
Not hing pr event s you f r om adding mor e code in t he const r uct or t han what is
shown her e. For t he Cocoa.pm modul e, you can, if you l ike, pr int a discl aimer when
each obj ect is cr eat ed. You might want t o use t he const r uct or t o init ial ize
var iabl es or set up ar r ays or point er s specif ic t o t he modul e.
DO init ial ize var iabl es in your modul e in t he
const r uct or .
DO use t he my const r uct t o cr eat e var iabl es in a met hod.
DON' T use t he local const r uct in a met hod unl ess you
r eal l y do want t he var iabl es t o be passed down t o ot her
subr out ines.
DON' T use gl obal var iabl es in t he cl ass modul e.
TIP
When you ar e wor king wit h inst ance var iabl es, it is
somet imes easy t o visual ize a Per l object as simpl y an
associat ive ar r ay. Then it 's easy t o see t hat each index in
t he associat ive ar r ay is a member of t hat cl ass and each
it em at t he index of t he associat ive ar r ay is a val ue of
t hat member .
List ing 19.3 shows what t he Cocoa const r uct or l ooks l ike.

List ing 19.3. Revised const r uct or f or Cocoa.pm. sub new {
my $this = {};
print "\n /* \n ** Created by Cocoa.pm \n ** Use at own risk";
print "\n ** Did this code even get pass the javac compiler? ";
print "\n **/ \n";
bless $this;
return $this;
}

The f ol l owing shows t he out put f r om r unning t he t est scr ipt cal l ed testme on t his
bar e-bones cl ass:
$ testme
/*
** Created by Cocoa.pm
** Use at own risk
** Did this code even get pass the javac compiler?
**/
Regar dl ess of which of t he t hr ee met hods shown her e you used t o cr eat e t he Cocoa
obj ect , you shoul d see t he same out put .
Gr eat . Now you' ve cr eat ed some comment s at t he beginning of a f il e wit h
some print st at ement s. You can j ust as easil y cal l ot her f unct ions in or out side of
t he package t o get mor e init ial izat ion f unct ional it y. For exampl e, as devel opment
pr ogr esses, you see t he new() f unct ion evol ve t o r esembl e t he f ol l owing:
sub new {
my $this = {}
bless $this;
$this->doInitialization();
return $this;
}
When you cr eat e any given cl ass, you shoul d al l ow it t o be inher it ed. You shoul d
be abl e t o cal l t he new oper at or wit h t he cl ass name as t he f ir st par amet er . This
capabil it y t o par se t he cl ass name f r om t he f ir st ar gument causes t he cl ass t o be
inher it ed. As a r esul t , t he new f unct ion becomes mor e or l ess l ike t he f ol l owing:
sub new {
my $class = shift; # Get the request class name
my $this = {};
bless $this, $class # Use class name to bless()
reference
$this->doInitialization();
return $this;
}
The pr eceding met hod f or ces your cl ass user s t o make cal l s in t he f or m of one of
t hr ee ways:
G Cocoa::new()
G Cocoa->new()
G new Cocoa;
What if you want ed t o use a r ef er ence t o t he obj ect inst ead, such as $obj->new()?
The doInitialization() met hod used wil l be what ever $class you bl essed t he
obj ect int o. The f ol l owing code uses t he f unct ion cal l ref() t o det er mine if t he
cl ass exist s per se. The ref() f unct ion r et ur ns true if t he it em passed t o it is a
r ef er ence and null if it is not a r ef er ence. Wit h cl asses, t he true val ue r et ur ned
f r om t he ref() f unct ion is t he name of t he cl ass.
sub new {
my $this = shift; # Get the class name
my $class = ref($this) || $this;
# If class exists, use it else use reference.
my $this = {};
bless $this, $class
$this->doInitialization();
return $this;
}
Wit hin t he cl ass package, t he met hods t ypical l y t r eat t he r ef er ence as an
or dinar y r ef er ence. Out side t he cl ass package, t he r ef er ence is gener al l y
t r eat ed as an opaque val ue t hat can onl y be accessed t hr ough t he cl ass' s met hods.
You can access t he val ues wit hin t he package dir ect l y, but it ' s not a good idea t o
do so because such access def eat s t he whol e pur pose of obj ect or ient at ion.
It ' s possibl e t o bl ess a r ef er ence obj ect mor e t han once. However , t he caveat is
t hat t he new cl ass must get r id of t he obj ect at t he pr eviousl y bl essed r ef er ence.
For C and Pascal pr ogr ammer s, t his is l ike assigning a point er t o malloced memor y
and t hen assigning t he same point er t o anot her l ocat ion wit hout f ir st f r eeing t he
pr evious l ocat ion. In ef f ect , a Per l obj ect must bel ong t o onl y one cl ass at a t ime.
What ' s t he r eal dif f er ence bet ween an obj ect and a r ef er ence? Per l obj ect s ar e
bl essed t o bel ong t o a cl ass. Ref er ences ar e not bl essed; if t hey ar e, t hey bel ong
t o a cl ass and ar e obj ect s. Obj ect s know t o which cl ass t hey bel ong. Ref er ences do
not have a cl ass t o which t hey bel ong.
Instance Variables
The ar gument s t o a new() f unct ion f or a const r uct or ar e cal l ed instance variables.
Inst ance var iabl es ar e used t o do init ial izat ion f or each inst ance of an obj ect as
it ' s cr eat ed. For exampl e, t he new() f unct ion coul d expect a name f or each new
inst ance of t he obj ect cr eat ed. Using inst ance var iabl es al l ows you t o cust omize
each obj ect as it is cr eat ed.
You can use eit her an anonymous ar r ay or anonymous hash t o hol d inst ance
var iabl es. To use a hash t o st or e t he par amet er s coming in, t he code woul d
r esembl e t he f ol l owing:
sub new {
my $type = shift;
my %parm = @_;
my $this = {};
$this->{'Name'} = $parm{'Name'};
$this->{'x'} = $parm{'x'};
$this->{'y'} = $parm{'y'};
bless $this, $type;
}
You can al so use an ar r ay inst ead of a hash t o st or e t he inst ance var iabl es.
sub new {
my $type = shift;
my %parm = @_;
my $this = [];
$this->[0] = $parm{'Name'};
$this->[1] = $parm{'x'};
$this->[2] = $parm{'y'};
bless $this, $type;
}
To const r uct an obj ect , you can pass t he par amet er s wit h t he new() f unct ion cal l .
For exampl e, t he cal l t o cr eat e t he Cocoa obj ect becomes t he f ol l owing:
$mug = Cocoa::new( 'Name' => 'top',
'x' => 10,
'y' => 20 );
The => oper at or has t he same f unct ion of t he comma oper at or , but => is a bit mor e
r eadabl e. You can wr it e t his code wit h commas inst ead of t he => oper at or if you
pr ef er .
To access t he var iabl es as you woul d any ot her dat a member s, you can use t he
f ol l owing st at ement s:
print "Name=$mug->{'Name'}\n";
print "x=$mug->{'x'}\n";
print "y=$mug->{'y'}\n";
Methods
A method in a Per l cl ass is simpl y a Per l subr out ine. Per l doesn' t pr ovide any
special synt ax f or met hod def init ion. A met hod expect s it s f ir st ar gument t o be
t he obj ect or package on which it is invoked. Per l has t wo t ypes of met hods: st at ic
and vir t ual .
A static met hod expect s a cl ass name as t he f ir st ar gument . A virtual met hod expect s a
r ef er ence t o an obj ect as t he f ir st ar gument . The way each met hod handl es t he
f ir st ar gument det er mines whet her t he met hod is st at ic or vir t ual .
A st at ic met hod appl ies f unct ional it y t o t he ent ir e cl ass as a whol e because it
uses t he name of t he cl ass. Funct ional it y in st at ic met hods is t her ef or e appl icabl e
t o al l obj ect s of t he cl ass. Gener al l y, st at ic met hods ignor e t he f ir st ar gument
because t hey al r eady know which cl ass t hey ar e in. Const r uct or s ar e st at ic
met hods.
A vir t ual met hod expect s a r ef er ence t o an obj ect as it s f ir st ar gument . Typical l y,
t he f ir st t hing a vir t ual met hod does is shif t t he f ir st ar gument int o a self or this
var iabl e and t hen use t hat shif t ed val ue as an or dinar y r ef er ence. For exampl e,
consider t he f ol l owing code:
1. sub nameLister {
2. my $this = shift;
3. my ($keys ,$value );
4. while (($key, $value) = each (%$this)) {
5. print "\t$key is $value.\n";
6. }
7. }
Line 2 in t he l ist ing is wher e t he $this var iabl e is set t o point t o t he obj ect . In l ine
4, t he $this ar r ay is de-r ef er enced at ever y $key l ocat ion.
TIP
Look at t he .pm f il es in t he Per l dist r ibut ion f or sampl e
code t hat wil l show you how met hods ar e decl ar ed and
used.
Exporting Methods
If you t r ied t o invoke t he Cocoa.pm package r ight now, you' d get an er r or message
f r om Per l at compil e t ime about t he met hods not being f ound. This er r or occur s
because t he Cocoa.pm met hods have not been expor t ed. To expor t t hese f unct ions,
you need t he Expor t er modul e. Add t he f ol l owing l ines t o t he beginning of code in
t he package:
require Exporter;
@ISA = qw(Exporter);
These t wo l ines f or ce t he incl usion of t he Exporter.pm modul e and t hen set t he
@ISA ar r ay wit h t he name of t he Expor t er cl ass t o l ook f or .
To expor t your own cl ass' s met hods, you l ist t hem in t he @EXPORT ar r ay. For
exampl e, t o expor t t he closeMain and declareMain met hods, you use t he f ol l owing
st at ement :
@EXPORT(declareMain, closeMain);
Inher it ance in a Per l cl ass is t hr ough t he @ISA ar r ay. The @ISA ar r ay does not have
t o be def ined in ever y package; however , when it is def ined, Per l t r eat s it as a
special ar r ay of dir ect or y names. This ar r ay is simil ar t o t he @INC ar r ay, wher e
dir ect or ies ar e sear ched f or f il es t o incl ude. The @ISA ar r ay cont ains t he names of
t he cl asses (packages) t o l ook f or met hods in ot her cl asses in if a met hod in t he
cur r ent package is not f ound. The @ISA ar r ay cont ains t he names of t he base cl asses
f r om which t he cur r ent cl ass inher it s. The sear ch is done in t he or der t hat t he
cl asses ar e l ist ed in t he @ISA ar r ays.
Al l met hods cal l ed by a cl ass must bel ong t o t he same cl ass or t he base cl asses
def ined in t he @ISA ar r ay. If a met hod isn' t f ound in t he @ISA ar r ay, Per l l ooks f or
an AUTOLOAD() r out ine. This opt ional r out ine is def ined as sub in t he cur r ent
package. To use t he AUTOLOAD f unct ion, you cal l t he autoload.pm package wit h t he
use Autoload; st at ement . The AUTOLOAD f unct ion t r ies t o l oad t he cal l ed f unct ion
f r om t he inst al l ed Per l l ibr ar ies. If t he AUTOLOAD cal l al so f ail s, Per l makes one
f inal t r y at t he UNIVERSAL cl ass, which is t he cat ch-al l f or al l met hods not def ined
el sewher e. Per l gener at es an er r or about unr esol ved f unct ions if t his st ep al so
f ail s.
Invoking Methods
Ther e ar e t wo ways t o invoke a met hod f or an obj ect : by making a r ef er ence t o an
obj ect (vir t ual ) or expl icit l y r ef er r ing t o t he cl ass name (st at ic). You have t o
expor t a met hod t o be abl e t o cal l it . Add a f ew mor e met hods t o t he Cocoa cl ass
t o get t he f il e t o r esembl e t he f ol l owing code:
package Cocoa;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(setImports, declareMain, closeMain);
#
# This routine creates the references for imports in Java functions
#
sub setImports{
my $class = shift @_;
my @names = @_;
foreach (@names) {
print "import " . $_ . ";\n";
}
}
#
# This routine declares the main function in a Java script
#
sub declareMain{
my $class = shift @_;
my ( $name, $extends, $implements) = @_;
print "\n public class $name";
if ($extends) {
print " extends " . $extends;
}
if ($implements) {
print " implements " . $implements;
}
print " { \n";
}
#
# This routine declares the main function in a Java script
#
sub closeMain{
print "} \n";
}
#
# This subroutine creates the header for the file.
#
sub new {
my $this = {};
print "\n /* \n ** Created by Cocoa.pm \n ** Use at own risk \n */
\n";
bless $this;
return $this;
}
1;
Now, wr it e a simpl e Per l scr ipt t o use t he met hods f or t his cl ass. Because you can
onl y st ar t and cl ose t he header , examine t he f ol l owing code f or a scr ipt t o
cr eat e a skel et on Java appl et sour ce:
#!/usr/bin/perl
use Cocoa;
$cup = new Cocoa;
$cup->setImports( 'java.io.InputStream', 'java.net.*');
$cup->declareMain( "Msg" , "java.applet.Applet", "Runnable");
$cup->closeMain();
This scr ipt gener at es code f or a Java appl et cal l ed Msg t hat ext ends t he
java.applet.Applet appl et and impl ement s f unct ions t hat ar e r unnabl e. You cal l
t he f unct ion wit h t he $cup->... cal l . The f ol l owing t hr ee l ines of code:
$cup->setImports( 'java.io.InputStream', 'java.net.*');3
$cup->declareMain( "Msg" , "java.applet.Applet", "Runnable");
$cup->closeMain();
coul d be r ewr it t en as f unct ions:
Cocoa::setImports($cup, 'java.io.InputStream', 'java.net.*');
Cocoa::declareMain($cup, "Msg" , "java.applet.Applet", "Runnable");
Cocoa::closeMain($cup);
This t ype of equival ence was shown in t he sect ion " Bl essing a Const r uct or ,"
ear l ier t oday. In bot h cases, t he f ir st par amet er is t he r ef er ence t o t he obj ect
it sel f . Running t he t est scr ipt shown gener at es t he f ol l owing out put :
/*
** Created by Cocoa.pm
** Use at own risk
*/
import java.io.InputStream;
import java.net.*;
public class Msg extends java.applet.Applet implements Runnable {
}
An impor t ant not e about cal l ing t he met hods: If you have any ar gument s in a
met hod, use par ent heses if you ar e using t he -> (al so known as indir ect ) met hod.
The par ent heses ar e r equir ed t o incl ude al l t he ar gument s wit h t he f ol l owing
st at ement :
$cup->setImports( 'java.io.InputStream', 'java.net.*');
However , t he f ol l owing st at ement :
Cocoa::setImports($cup, 'java.io.InputStream', 'java.net.*');
can al so be r ewr it t en wit hout par ent heses as t his:
Cocoa::setImports $cup, 'java.io.InputStream', 'java.net.*' ;
The choice is your s about how you make your code r eadabl e t o ot her
pr ogr ammer s. Use par ent heses if you f eel t hat it wil l make t he code mor e
r eadabl e.
Overrides
Somet imes you want t o specif y which cl ass' s met hod t o use, such as when t he same
named met hod is specif ied in t wo dif f er ent cl asses. For exampl e, if t he f unct ion
grind is def ined in bot h Espresso and Qava cl asses, you can specif y which cl ass' s
f unct ion t o use by using t he :: oper at or . The f ol l owing cal l s woul d use t he cal l
in Espresso:
$mess = Espresso::grind("whole","lotta","bags");
Espresso::grind($mess, "whole","lotta","bags");
The f ol l owing cal l s woul d use t he grind() f unct ion in t he Qava cl ass:
$mess = Qava::grind("whole","lotta","bags");
Qava::grind($mess, "whole","lotta","bags");
You might want t o cal l a met hod based on some act ion t hat t he pr ogr am you ar e
wr it ing has al r eady t aken. In ot her wor ds, you want t o use t he Qava met hod f or a
cer t ain condit ion and t he Espresso met hod f or anot her . In t his case, you can use
symbol ic r ef er ences t o make t he cal l t o t he r equir ed f unct ion, as in t he
f ol l owing exampl e:
$method = $local ? "Qava::" : "Espresso::";
$cup->{$method}grind(@args);
Destructors
Per l t r acks t he number of l inks t o obj ect s. When t he l ast r ef er ence t o an obj ect
is f r eed t o t he memor y pool , t he obj ect is aut omat ical l y dest r oyed. This
dest r uct ion of t he obj ect coul d occur af t er your code st ops and t he scr ipt is
about t o exit . For gl obal var iabl es, t he dest r uct ion happens af t er t he l ast l ine in
your code execut es.
If you want t o capt ur e cont r ol j ust bef or e t he obj ect is f r eed, you can def ine a
DESTROY() met hod in your cl ass. Not e t he use of al l capit al l et t er s in t he name.
The DESTROY() met hod is cal l ed j ust bef or e t he obj ect is r el eased, which enabl es
you t o do any necessar y cl eanup. The DESTROY() f unct ion does not cal l ot her
DESTROY() f unct ions aut omat ical l y; Per l doesn' t do nest ed dest r uct ion f or you. If
your const r uct or r e-bl essed a r ef er ence f r om one of your base cl asses, your
DESTROY() might need t o cal l DESTROY() f or any base cl asses. Al l obj ect r ef er ences
t hat ar e cont ained in a given obj ect ar e f r eed and dest r oyed aut omat ical l y when
t he cur r ent obj ect is f r eed.
Usual l y, you do not have t o def ine a DESTROY f unct ion, but when you do need it , it
t akes t he f ol l owing f or m:
sub DESTROY {
#
# Add code here.
#
}
For most pur poses, Per l uses a simpl e, r ef er ence-based gar bage col l ect ion syst em.
The number of r ef er ences t o any given obj ect at t he t ime of gar bage col l ect ion
must be gr eat er t han zer o, or t he memor y f or t hat obj ect is f r eed. When your
pr ogr am exit s, an exhaust ive sear ch-and-dest r oy f unct ion in Per l does gar bage
col l ect ion. Ever yt hing in t he pr ocess is summar il y del et ed. In UNIX or UNIX-l ike
syst ems, t his might seem l ike a wast e, but it ' s act ual l y quit e necessar y t o per f or m
in embedded syst ems or in a mul t it hr eaded envir onment .
Inheritance
Met hods in cl asses ar e inher it ed wit h t he pat hs in t he @ISA ar r ay. Var iabl es must
be set up expl icit l y f or inher it ance. Assume you def ine a new cl ass cal l ed Bean.pm
t o incl ude some of t he f unct ional it y t hat anot her cl ass Coffee.pm wil l inher it .
The exampl e in t his sect ion demonst r at es how t o inher it inst ance var iabl es f r om
one cl ass (al so r ef er r ed t o as a " super cl ass" or " base cl ass" ). The st eps in
inher it ance r equir e cal l ing t he super cl ass' s const r uct or and adding one' s own
inst ance var iabl es t o t he new obj ect .
In t his exampl e, t he Coffee cl ass inher it s val ues f r om t he base cl ass cal l ed Bean.
The t wo f il es ar e cal l ed Coffee.pm and Bean.pm, r espect ivel y.
List ing 19.4 is t he code f or Bean.pm.

List ing 19.4. The code f or Bean.pm.
package Bean;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(setBeanType);
sub new {
my $type = shift;
my $this = {};
$this->{'Bean'} = 'Colombian';
bless $this, $type;
return $this;
}
#
# This subroutine sets the class name
sub setBeanType{
my ($class, $name) = @_;
$class->{'Bean'} = $name;
print "Set bean to $name \n";
}
1;

List ing 19.4 has no out put .
In t his l ist ing, t he $this var iabl e set s a val ue in t he anonymous hash f or
t he 'Bean' t ype t o be 'Colombian'. The setBeanType() met hod is al so decl ar ed so
t hat t he 'Bean' t ype can al so be changed by a pr ogr am.
The subr out ine f or r eset t ing t he val ue of 'Bean' uses t he $class r ef er ence t o get
t o t he anonymous hash f or t he obj ect . Remember t hat a r ef er ence t o t his
anonymous hash cr eat ed t he r ef er ence in t he f ir st pl ace wit h t he new() f unct ion.
The val ues in t he Bean cl ass wil l be inher it ed by t he Coffee cl ass. The Coffee.pm
f il e is shown in List ing 19.5.

List ing 19.5. The Coffee.pm f il e.
1 #
2 # The Coffee.pm file to illustrate inheritance.
3 #
4 package Coffee;
5 require Exporter;
6 require Bean;
7 @ISA = qw(Exporter, Bean);
8 @EXPORT = qw(setImports, declareMain, closeMain);
9 #
10 # set item
11 #
12 sub setCoffeeType{
13 my ($class,$name) = @_;
14 $class->{'Coffee'} = $name;
15 print "Set coffee type to $name \n";
16 }
17 #
18 # constructor
19 #
20 sub new {
21 my $type = shift;
22 my $this = Bean->new(); ##### <- LOOK HERE!!! ####
23 $this->{'Coffee'} = 'Instant'; # unless told otherwise
24 bless $this, $type;
25 return $this;
26 }
27 1;

List ing 19.5 has no out put .
Not e t he use of t he require Bean; st at ement in l ine 6. This l ine f or ces t he
incl usion of t he Bean.pm f il e and al l it s r el at ed f unct ions. Lines 12 t hr ough 16
def ine a sub-r out ine t o use when r eset t ing t he val ue of t he l ocal var iabl e in
$class->{'Coffee'}.
Look at t he new() const r uct or f or t he Coffee cl ass in l ine 20. The $this r ef er ence
point s t o t he anonymous hash r et ur ned by Bean.pm and not a hash cr eat ed l ocal l y.
In ot her wor ds, t he f ol l owing st at ement cr eat es an ent ir el y dif f er ent hash t hat
has not hing t o do wit h t he hash cr eat ed in t he Bean.pm const r uct or :
my $this = {}; # This is not the way to do it for inheritance.
my $this = $theSuperClass->new(); # this is the way.
List ing 19.6 shows how t o cal l t hese f unct ions.

List ing 19.6. Cal l ing inher it ed met hods.
1 #!/usr/bin/perl
2 push (@INC,'pwd');
3 use Coffee;
4 $cup = new Coffee;
5 print "\n -------------------- Initial values ------------ \n";
6 print "Coffee: $cup->{'Coffee'} \n";
7 print "Bean: $cup->{'Bean'} \n";
8 print "\n -------------------- Change Bean Type ---------- \n";
9 $cup->setBeanType('Mixed');
10 print "Bean Type is now $cup->{'Bean'} \n";
11 print "\n ------------------ Change Coffee Type ---------- \n";
12 $cup->setCoffeeType('Instant');
13 print "Type of coffee: $cup->{'Coffee'} \n";

-------------------- Initial values ------------
Coffee: Instant
Bean: Colombian
-------------------- Change Bean Type ----------
Set bean to Mixed
Bean Type is now Mixed
------------------ Change Coffee Type ----------
Set coffee type to Instant
Type of coffee: Instant
The init ial val ues f or t he 'Bean' and 'Coffee' indices in t he anonymous
hash f or t he obj ect ar e pr int ed f ir st . The member f unct ions ar e cal l ed t o set t he
val ues t o dif f er ent names and t hen pr int ed.
Met hods can have sever al t ypes of ar gument s. It ' s how you pr ocess t he ar gument s
t hat count s. For exampl e, you can add t he f ol l owing met hod t o t he Coffee.pm
modul e:
sub makeCup {
my ($class, $cream, $sugar, $dope) = @_;
print "\n================================== \n";
print "Making a cup \n";
print "Add cream \n" if ($cream);
print "Add $sugar sugar cubes\n" if ($sugar);
print "Making some really addictive coffee ;-) \n" if ($dope);
print "================================== \n";
}
The f unct ion makeCup() t akes t hr ee ar gument s but pr ocesses t hem onl y if it sees
t hem. To t est t his f unct ional it y, consider List ing 19.7.

List ing 19.7. Using t he makeCup() f unct ion.
1 #!/usr/bin/perl
2 push (@INC,'pwd');
3 use Coffee;
4 $cup = new Coffee;
5 #
6 # With no parameters
7 #
8 print "\n Calling with no parameters: \n";
9 $cup->makeCup;
10 #
11 # With one parameter
12 #
13 print "\n Calling with one parameter: \n";
14 $cup->makeCup('1');
15 #
16 # With two parameters
17 #
18 print "\n Calling with two parameters: \n";
19 $cup->makeCup(1,'2');
20 #
21 # With all three parameters
22 #
23 print "\n Calling with three parameters: \n";
24 $cup->makeCup('1',3,'1');

Calling with no parameters:
==================================
Making a cup
==================================
Calling with one parameter:
==================================
Making a cup
Add cream
==================================
Calling with two parameters:
==================================
Making a cup
Add cream
Add 2 sugar cubes
==================================
Calling with three parameters:
==================================
Making a cup
Add cream
Add 3 sugar cubes
Making some really addictive coffee ;-)
==================================
Line 9 cal l s t he f unct ion wit h no par amet er s. In l ine 14, t he f unct ion cal l
has one par amet er . The par amet er s ar e passed eit her as st r ings or int eger s,
somet hing t his par t icul ar met hod does not car e about . Look at l ine 19 and l ine 24,
wher e bot h st r ings and number s ar e passed in t he same f unct ion cal l . However ,
some met hods you wr it e in t he f ut ur e might r equir e t his dist inct ion.
In any event , you can have def aul t val ues set in t he f unct ion if t he expect ed
par amet er is not passed. The behavior of t he met hod can be dif f er ent depending on
t he number of ar gument s you pass it .
Overriding Methods
Inher it ing f unct ional it y f r om anot her cl ass is benef icial in t hat you can get al l
t he expor t ed f unct ional it y of t he base cl ass in your new cl ass. To see an exampl e
of how t his wor ks, add a f unct ion in t he Bean.pm cl ass cal l ed printType. Her e' s t he
subr out ine:
sub printType {
my $class = shift @_;
print "The type of Bean is $class->{'Bean'} \n";
}
Do not f or get t o updat e t he @EXPORT ar r ay by adding t he name of t he f unct ion t o
expor t . The new st at ement shoul d l ook l ike t his:
@EXPORT = qw(setBeanType, printType, printType);
Now cal l t he printType f unct ion. The next t hr ee l ines show t hr ee ways t o cal l t he
f unct ion:
$cup->Coffee::printType();
$cup->printType();
$cup->Bean::printType();
The out put f r om al l t hr ee l ines is t he same:
The type of Bean is Mixed
The type of Bean is Mixed
The type of Bean is Mixed
Why is t his so? Ther e is no printType() f unct ion in t he inher it ing cl ass, so t he
printType() f unct ion in t he base cl ass is used inst ead. Nat ur al l y, if you want your
own cl ass t o have it s own printType f unct ion, you have t o def ine it .
In t he Coffee.pm f il e, add t he f ol l owing l ines:
#
# This routine prints the type of $class->{'Coffee'}
#
sub printType {
my $class = shift @_;
print "The type of Coffee is $class->{'Coffee'} \n";
}
You must al so modif y t he @EXPORT t o wor k wit h t his f unct ion:
@EXPORT = qw(setImports, declareMain, closeMain, printType);
Now t he out put f r om t he t hr ee l ines l ooks l ike t his:
The type of Coffee is Instant
The type of Coffee is Instant
The type of Bean is Mixed
The base cl ass f unct ion is cal l ed onl y when t he Bean:: over r ide is given. In t he
ot her cases, onl y t he inher it ed cl ass f unct ion is cal l ed.
What if you do not know t he base cl ass name or even wher e t he name is def ined? In
t his case, you can use t he SUPER:: pseudo-cl ass r eser ved wor d. Using t he SUPER::
over r ide enabl es you t o cal l an over r idden super cl ass met hod wit hout act ual l y
knowing wher e t hat met hod is def ined. The SUPER:: const r uct is meaningf ul onl y
wit hin t he cl ass.
If you' r e t r ying t o cont r ol wher e t he met hod sear ch begins and you' r e execut ing
in t he cl ass it sel f , you can use t he SUPER:: pseudo cl ass, which inst r uct s Per l t o
st ar t l ooking in your base cl ass' s @ISA l ist wit hout expl icit l y naming it :
$this->SUPER::function( ... argument list ... );
Inst ead of Bean:: we can use SUPER::. The cal l t o t he f unct ion printType() becomes
$cup->SUPER::printType();
and t he out put is t he f ol l owing:
The type of Bean is Mixed
A Few Comments About Classes and Objects in Perl
One adver t ised st r engt h of obj ect -or ient ed l anguages is t he ease wit h which new
code can use ol d code. Packages in Per l l et you r euse code t hr ough t he use of
obj ect s and inher it ance. OOP l anguages use dat a encapsul at ion t o l et you hide t he
inner wor kings of compl icat ed code. Packages and modul es in Per l pr ovide a gr eat
deal of dat a encapsul at ion wit h t he use of t he my const r uct . Per l , however , does
not guar ant ee t hat a cl ass inher it ing your code wil l not at t empt t o access your
cl ass var iabl es dir ect l y, t her eby el iminat ing t he advant age of dat a encapsul at ion.
They can if t hey r eal l y want t o; however , t his t ype of pr ocedur e is consider ed bad
pr act ice, and shame on you if you do it .
DO def ine met hods t o access cl ass var iabl es.
DON' T access cl ass var iabl es dir ect l y f r om out side t he
modul e.
When wr it ing a package, you shoul d ensur e t hat ever yt hing a met hod needs is
avail abl e t hr ough t he obj ect or is passed as a par amet er t o t he met hod. Fr om
wit hin t he package, access any gl obal var iabl es onl y t hr ough r ef er ences passed
t hr ough met hods.
For st at ic or gl obal dat a t o be used by t he met hods, you have t o def ine t he
cont ext of t he dat a in t he base cl ass using t he local() const r uct . The subcl ass
wil l t hen cal l t he base cl ass t o get t he dat a f or it . On occasion, a subcl ass might
want t o over r ide t hat dat a and r epl ace it wit h new dat a. When t his happens, t he
super cl ass might not know how t o f ind t he new copy of t he dat a. In such cases, it ' s
best t o def ine a r ef er ence t o t he dat a and t hen have al l base cl asses and
subcl asses modif y t he var iabl e t hr ough t hat r ef er ence.
Final l y, you wil l see r ef er ences t o obj ect s and cl asses such as t he f ol l owing:
use Coffee::Bean;
This code is int er pr et ed t o mean " Look f or Bean.pm in t he Coffee subdir ect or y in
al l t he dir ect or ies in t he @INC ar r ay." If I wer e t o move Bean.pm int o t he ./Coffee
dir ect or y, al l t he pr evious exampl es woul d wor k wit h t he new use st at ement . The
advant age t o t his appr oach is t hat you have one subcl ass cl ass f il e in one
dir ect or y and t he base cl ass in a l ower dir ect or y. It hel ps keep code or ganized. To
have a st at ement l ike t he f ol l owing:
use Another::Sub::Menu;
you woul d see a dir ect or y sub-t r ee l ike t his:
./Another/Sub/Menu.pm
Summary
This chapt er pr ovides a br ief int r oduct ion t o obj ect -or ient ed pr ogr amming in
Per l . Per l pr ovides t he OOP f eat ur es of dat a encapsul at ion and inher it ance using
modul es and packages. A cl ass in Per l is simpl y a package. A package f or a cl ass
pr ovides al l t he met hods f or obj ect s cr eat ed f or t he cl ass.
An obj ect is simpl y a r ef er ence t o dat a t hat knows which cl ass it bel ongs t o. A
met hod in a cl ass is simpl y a subr out ine. The onl y cat ch about wr it ing such
met hods is t hat t he name of t he cl ass is al ways t he f ir st ar gument of t he met hod.
The bless() f unct ion is used t o t ie a r ef er ence t o a cl ass name. The bless()
f unct ion is cal l ed in t he const r uct or f unct ion new() t o cr eat e an obj ect and t hen
connect t he r ef er ence t o t he obj ect wit h t he name of t he cl ass.
Wit h inher it ance, t he base cl ass is t he cl ass f r om which met hods (and dat a) ar e
inher it ed. The base cl ass is al so cal l ed t he super cl ass. The cl ass t hat inher it s
t hese it ems f r om t he super cl ass is cal l ed t he subcl ass. Mul t ipl e inher it ance is
al l owed in Per l . Dat a inher it ance is t he pr ogr ammer ' s r esponsibil it y and r equir es
using r ef er ences. The subcl ass is al l owed t o know t hings about it s immediat e
super cl ass; t he super cl ass is not al l owed t o know anyt hing about a subcl ass.
Q&A
Q: What does t he bless() f unct ion do?
A: The bless() f unct ion t akes one or t wo ar gument s. The f ir st ar gument is a
r ef er ence t o an object . The second ar gument is opt ional and specif ies t he name of
a cl ass; if t he name is not specif ied, t he def aul t is t he cur r ent cl ass. Af t er t he
cal l , t he r ef er ence uses t he name as it s cl ass name. As a r esul t , t he r ef er ence
becomes an object of t he cl ass whose name was specif ied.
Q: What ' s t he dif f er ence bet ween an obj ect and a r ef er ence?
A: Object s ar e bl essed; r ef er ences ar e not . Object s bel ong t o a cl ass, but r ef er ences
do not have t o.
Q: What ' s t he dif f er ence bet ween st at ic and vir t ual met hods?
A: St at ic met hods expect a cl ass name as t he f ir st ar gument . Vir t ual met hods expect
a r ef er ence t o an object as t he f ir st ar gument . St at ic met hods ar e cl ass-wide;
vir t ual met hods ar e object -specif ic.
Q: I j ust added a met hod t o my cl ass f il e, but it is never cal l ed! What ' s wr ong?
A: Make sur e you ar e using t he require Exporter; st at ement and t hat t he name of
t he new f unct ion is in t he @EXPORTER ar r ay.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of
t he mat er ial cover ed and exer cises t o give you exper ience in using what you' ve
l ear ned. Tr y and under st and t he quiz and exer cise answer s bef or e you go on t o
t omor r ow' s l esson.
Quiz
1. Show at l east t hr ee ways t o cr eat e a new obj ect of a given cl ass, Balloon.
2. What ' s wr ong t he f ol l owing l ines of code?
{
my $x; my $y;
$x = \$y;
}
3. What ar e t he t hr ee most impor t ant r ul es about OOP in Per l ?
4. How do you over r ide a cal l t o a met hod t o use t he base cl ass inst ead of t he
subcl ass?
Exercises
1. Wr it e a simpl e cl ass t o pr int out t he day of t he week using t he Zel l er s
congr uence f or mul a t o get t he day of t he week given a dat e. The f ol l owing
shows t he f or mul a in Per l code:
$zy = $year;
$zm = ($month + 10) % 12;
$zy- if ($m > 10);
$zc = int ( $y / 100 );
$yy = $year % 100;
$zeller = ( int ( (26*$zm - 2)/10) + $dayOfMonth
+ $yy + int($yy/4)
+ int ($zc/4) - 2* $zc ) % 7;
2. Ext end t he cl ass you j ust cr eat ed t o al l ow specif ying a dat e at cr eat ion
t ime wher e t he day, mont h, year , or al l t hr ee can be opt ional . Hint : Use t he
dat e f unct ion t o get t he cur r ent dat e.
3. Cr eat e a cl ass t o l ist t he ent ir e dir ect or y t r ee when given a pat h name.
4. Modif y t he f ol l owing f unct ion t o pr int black if no par amet er s ar e passed t o
it :sub makeCup {
my ($class, $cream, $sugar, $dope) = @_;
print "\n================================== \n";
print "Making a cup \n";
print "Add cream \n" if ($cream);
print "Add $sugar sugar cubes\n" if ($sugar);
print "Making some really nice coffee ;-) \n" if ($dope);
print "================================== \n";
}

Chapter 20
Miscellaneous Features of Perl
CONTENTS
G The require Funct ion
H The require Funct ion and Subr out ine Libr ar ies
H Using require t o Specif y a Per l Ver sion
G The $#array Var iabl es
H Cont r ol l ing Ar r ay Lengt h Using $#array
G Al t er nat ive St r ing Del imit er s
H Def ining St r ings Using <<
G Special Int er nal Val ues
G Using Back Quot es t o Invoke Syst em Commands
G Pat t er n Mat ching Using ?? and t he reset Funct ion
H Using reset wit h Var iabl es
G Ot her Feat ur es of t he <> Oper at or
H Scal ar Var iabl e Subst it ut ion and <>
H Cr eat ing a List of Fil enames
G Gl obal Indir ect Ref er ences and Al iases
G Packages
H Def ining a Package
H Swit ching Bet ween Packages
H The main Package
H Ref er r ing t o One Package f r om Anot her
H Specif ying No Cur r ent Package
H Packages and Subr out ines
H Def ining Pr ivat e Dat a Using Packages
H Packages and Syst em Var iabl es
H Accessing Symbol Tabl es
G Modul es
H Cr eat ing a Modul e
H Impor t ing Modul es Int o Your Pr ogr am
H Using Pr edef ined Modul es
G Using Per l in C Pr ogr ams
G Per l and CGI Scr ipt s
G Tr ansl at or s and Ot her Suppl ied Code
G Summar y
G Q&A
G Wor kshop
H Quiz
H Exer cises
Today's l esson descr ibes t he f eat ur es of Per l t hat have not been cover ed in pr evious
chapt er s:
G The require f unct ion, which r et r ieves code f r om ot her f il es
G The $#array var iabl es
G Al t er nat ive met hods of st r ing quot ing using q, qq, qw, and <<
G The special int er nal val ues __LINE__, __FILE__, and __END__
G Incor por at ing out put f r om ot her commands using back quot es
G The ?? pat t er n-mat ching const r uct and t he reset f unct ion
G Using <> wit h indir ect f il e var iabl es and as a f il ename specif ier
G Using t he *name const r uct gl obal l y
G Packages
G Modul es
Today's l esson al so pr ovides a br ief over view of t he f ol l owing t opics:
G Using Per l in C pr ogr ams
G Using Per l in CGI scr ipt s
G Tr ansl at or s f r om ot her l anguages t o Per l
The require Function
The require f unct ion pr ovides a way t o br eak your pr ogr am int o separ at e f il es and
cr eat e l ibr ar ies of f unct ions. For exampl e, if you have st or ed Per l st at ement s in t he f il e
myfile.pl, you can incl ude t hem as par t of your pr ogr am by adding t he f ol l owing
st at ement :
require ("myfile.pl");
When t he Per l int er pr et er sees t his require st at ement , it sear ches t he dir ect or ies
specif ied by t he buil t -in ar r ay var iabl e @INC f or a f il e named myfile.pl. If such a f il e is
f ound, t he st at ement s in t he f il e ar e execut ed; if no such f il e exist s, t he pr ogr am
t er minat es and pr int s t he er r or message
Can't find myfile.pl in @INC
on your scr een (by wr it ing it t o t he st andar d er r or f il e STDERR). (For mor e det ail s on t he
@INC ar r ay, r ef er t o Day 17, "Syst em Var iabl es.")
As in a subr out ine cal l , t he l ast expr ession eval uat ed inside a f il e incl uded by require
becomes t he r et ur n val ue. The require f unct ion checks whet her t his val ue is zer o, and
t er minat es if it is. For exampl e, suppose t hat t he f il e myfile.pl cont ains t he f ol l owing
st at ement s:
print ("hello, world!\n");
$var = 14;
If t he st at ement s in t his f il e ar e execut ed by
require ("myfile.pl");
t he r et ur n val ue of myfile.pl is t he f ol l owing expr ession, which has t he val ue 14:
$var = 14
Because t his val ue is not zer o, t he pr ogr am cont inues execut ion wit h t he st at ement
f ol l owing t he require.
If myfile.pl cont ains t he f ol l owing st at ement s, t he r et ur n val ue of myfile.pl is 0:
print ("hello, world!\n");
$var = 0;
Because t his val ue is zer o, t he Per l int er pr et er pr int s t he f ol l owing er r or message
al ong wit h t he name and cur r ent l ine number of your pr ogr am; t hen it exit s:
myfile.pl did not return true value
TIP
By convent ion, f il es cont aining Per l st at ement s
nor mal l y have t he suf f ix .pl. This makes it easy t o
det er mine which f il es in a dir ect or y cont ain Per l
pr ogr ams or code incl uded in Per l pr ogr ams using
require.
You can pass any scal ar val ue t o require, incl uding t hose st or ed in scal ar var iabl es or
ar r ay el ement s:
@reqlist = ("file1.pl", "file2.pl", "file3.pl");
require ($reqlist[$0]);
require ($reqlist[$1]);
require ($reqlist[$2]);
Her e, t he successive cal l s t o require incl ude t he cont ent s of file1.pl, file2.pl, and
file3.pl.
You can al so specif y no f il ename, as in t he f ol l owing:
require;
In t his case, t he val ue of t he scal ar var iabl e $_ is t he f il ename whose cont ent s ar e t o be
execut ed.
One l imit at ion Per l imposes on t he require st at ement is
t hat t he cont ent s of a par t icul ar f il e can be incl uded
onl y once in a pr ogr am. To r epeat a bl ock of code many
t imes, your onl y al t er nat ive is t o put it in a separ at e
pr ogr am and cal l it using t he system f unct ion or t he
eval f unct ion.
Al so, if t wo dir ect or ies in @INC cont ain a f il e named by
require, onl y t he f ir st one is incl uded.
The require Function and Subroutine Libraries
The require f unct ion enabl es you t o cr eat e l ibr ar ies of subr out ines t hat can be used in
al l your Per l pr ogr ams. To cr eat e a subr out ine l ibr ar y, you need onl y t ake t he
f ol l owing st eps:
1. Decide on a dir ect or y in which t o st or e your subr out ine l ibr ar y.
2. Move your subr out ines t o separ at e f il es, and move t hese f il es t o your subr out ine
dir ect or y.
3. To each f il e, add an execut abl e st at ement t hat cont ains an expr ession wit h a
nonzer o val ue. This st ep is necessar y because f il es execut ed by require must
r et ur n a nonzer o val ue, and an empt y pr ogr am is assumed t o have t he val ue zer o.
The easiest way t o per f or m t his t ask is t o add t he f ol l owing st at ement t o t he
bot t om of each f il e:
1;
4. This st at ement is just a simpl e expr ession (t he number 1) wit h a nonzer o val ue.
5. In your main pr ogr am, use require t o r ef er t o one or mor e of t he f il es t hat
cont ain your l ibr ar y subr out ines, as needed.
6. When you st ar t your main pr ogr am, use t he -I opt ion t o specif y t he name of t he
subr out ine dir ect or y. Al t er nat ivel y, add t he subr out ine dir ect or y t o t he @INC
ar r ay bef or e cal l ing require.
For exampl e, suppose t hat t he dir ect or y /u/jqpublic/perldir cont ains your Per l
subr out ine l ibr ar y and t hat t he subr out ine mysub is st or ed in t he f il e mysub.pl in t hat
dir ect or y. (Naming t he f il e af t er t he subr out ine is an easy way t o r emember wher e t he
subr out ine is l ocat ed.) Now, t o incl ude mysub as par t of your pr ogr am, add t he
f ol l owing st at ement s:
unshift (@INC, "/u/jqpublic/perldir");
require ("mysub.pl");
The cal l t o unshift adds t he dir ect or y /u/jqpublic/perldir t o t he @INC ar r ay, which
ensur es t hat any subsequent cal l s t o require wil l sear ch t his dir ect or y. The cal l t o
require t hen incl udes t he cont ent s of mysub.pl as par t of your pr ogr am, which means
t hat mysub now is incl uded.
TIP
You shoul d use unshift, not push, t o add t o t he @INC
ar r ay. The push f unct ion adds t o t he end of t he l ist
st or ed in @INC, which means t hat your subr out ine l ibr ar y
dir ect or y wil l be sear ched l ast .
As a consequence, if your subr out ine f il e has t he same
name as a f il e cont ained in /usr/local/lib/perl, your
f il e wil l not be incl uded, because require incl udes onl y
t he f ir st f il e mat ching t he specif ied name.
You can cont r ol t he sear ch or der of @INC by cr eat ing or
r eshuf f l ing it your sel f bef or e cal l ing require.
Using require to Specify a Perl Version
Per l 5 enabl es you t o use a require st at ement t o specif y t he ver sion of Per l needed t o
r un your pr ogr am. When Per l sees a require st at ement wit h a numer ic associat ed val ue,
it onl y r uns t he pr ogr am if t he ver sion of Per l is gr eat er t han or equal t o t he number .
For exampl e, t he f ol l owing st at ement indicat es t hat t he pr ogr am is t o be r un onl y if t he
Per l int er pr et er is ver sion 5.001 or higher :
require 5.001;
If it is not , t he pr ogr am t er minat es.
This is usef ul if your pr ogr am uses a f eat ur e of Per l t hat you know does not wor k
pr oper l y in ear l ier ver sions of t he l anguage.
NOTE
Because Per l 4 does not under st and
require 5.001;
it det ect s an er r or and t er minat es when it sees t his
st at ement . This is basical l y what you want t o have
happen
The $#array Variables
For each ar r ay var iabl e def ined in your pr ogr am, a var iabl e named $#array, in which
array is t he name of your ar r ay, is al so def ined. This var iabl e cont ains t he subscr ipt of
t he l ast el ement of t he ar r ay. For exampl e:
@myarray = ("goodbye", "cruel", "world");
$lastsub = $#myarray;
Her e, t her e ar e t hr ee el ement s in @myarray, which ar e r ef er enced by t he subscr ipt s 0, 1,
and 2. Because t he subscr ipt of t he l ast el ement of t he ar r ay is 2, $#myarray cont ains t he
val ue 2.
NOTE
Because t he val ue of t he maximum subscr ipt is af f ect ed
by t he syst em var iabl e $[, t he val ue of each $#array
var iabl e is al so af f ect ed by $[. For exampl e:
$[ = 1;
@myarray = ("goodbye", "cruel", "world");
$lastsub = $#myarray;
Her e, t he f ir st subscr ipt of t he ar r ay is 1, because $[ is
set t o t hat val ue. This means t hat t he maximum subscr ipt
is 3 and t he val ue of $#myarray is al so 3
Any $#array var iabl e t hat does not cor r espond t o a def ined ar r ay has t he val ue -1. For
exampl e:
$sublength = $#notdefined;
Her e, if t he ar r ay @notdefined does not exist , $sublength is assigned -1.
A $#array var iabl e is al so def ined f or each buil t -in ar r ay var iabl e. This means, f or
exampl e, t hat t he $#ARGV var iabl e cont ains t he number of el ement s incl uded on t he
command l ine. You can use t his var iabl e t o check whet her f il es have been specif ied on
t he command l ine:
if ($#ARGV == -1) {
die ("No files specified.\n");
}
If t her e ar e no "hol es" (undef ined el ement s) in t he ar r ay, you can use a $#array var iabl e
in a l oop. List ing 20.1 shows how you can car r y out t his act ion.

List ing 20.1. A pr ogr am t hat uses a $#array var iabl e in a l oop.
1: #!/usr/local/bin/perl
2:
3: @myarray = ("testing", 98.6, "Olerud", 47);
4: for ($i = 0; $i <= $#myarray; $i++) {
5: print ("$myarray[$i]\n");
6: }

$ program20_1
testing
98.599999999999994
Olerud
47
$
Line 3 assigns a f our -el ement l ist t o t he ar r ay var iabl e @myarray. Ther ef or e,
t he l ar gest subscr ipt used in t he ar r ay is 3; t his val ue is aut omat ical l y assigned t o t he
var iabl e $#myarray.
The for st at ement in l ine 4 t er minat es when $i is gr eat er t han $#myarray. This
t echnique ensur es t hat each el ement of @myarray is pr int ed, in t ur n, by l ine 5.
Using $#myarray t o t er minat e t he l oop isn't as usef ul if
t he ar r ay cont ains undef ined el ement s as in t he
f ol l owing:
@myarray = ("test1", "test2");
$myarray[5] = "test3";
for ($i = 0; $i <= $#myarray; $i++) {
print ("$myarray[$i]\n");
}
This l oop it er at es six t imes, because t he l ar gest subscr ipt
of t he ar r ay is 5. Ther ef or e, t hr ee bl ank l ines ar e
pr int ed, because t he el ement s of @myarray wit h t he
subscr ipt s 2, 3, and 4 have not been def ined. (You can get
ar ound t his by using t he defined f unct ion.)
Controlling Array Length Using $#array
You can use $#array t o cont r ol t he l engt h of an ar r ay var iabl e.
If a $#array var iabl e is assigned a val ue t hat is l ar ger t han t he cur r ent l ar gest
subscr ipt of t he cor r esponding ar r ay, t he missing el ement s ar e cr eat ed and init ial ized t o
t he special int er nal undef ined val ue (equival ent t o t he nul l st r ing). For exampl e:
@myarray = ("hi", "there");
$#myarray = 4;
This code set s t he maximum subscr ipt of $#myarray t o 4. Because t he subscr ipt of t he l ast
def ined el ement is 1, t hr ee empt y el ement s ar e cr eat ed wit h subscr ipt s 2, 3, and 4.
You can use t his t echnique t o cr eat e a l ar ge ar r ay al l at once:
$#bigarray = 9999;
This st at ement cr eat es an ar r ay l ar ge enough t o hol d 10,000 val ues (or f ail s t r ying). If
t his st at ement execut es successf ul l y, you know t hat your machine has enough space t o
st or e @bigarray bef or e act ual l y assigning t o al l or par t of it .
In Per l 5, if t he val ue you assign t o a $#array var iabl e is l ess t han t he cur r ent maximum
subscr ipt , t he l ef t over ar r ay val ues ar e dest r oyed. For exampl e:
@myarray = ("hello", "there", "Dave!");
$#myarray = 1;
Her e, @myarray is or iginal l y assigned a t hr ee-el ement l ist , which means t hat it s maximum
subscr ipt is 2. Assigning 1 t o $#myarray set s t he maximum subscr ipt t o 1, which means t hat
@myarray now cont ains ("hello", "there"). The t hir d el ement , Dave!, is dest r oyed.
NOTE
This is one inst ance in which Per l 5 and Per l 4 behave
dif f er ent l y. In Per l 4, ar r ay el ement s ar e not dest r oyed
when $#array is assigned a val ue l ess t han t he cur r ent
maximum subscr ipt .
In Per l 4, ar r ay el ement s t hat have been "r emoved" by
assigning t o t he $#array var iabl e can be r est or ed t o
exist ence by r eset t ing $#array t o it s or iginal val ue.
Alternative String Delimiters
As you've seen, Per l enabl es you t o encl ose char act er st r ings in eit her singl e quot at ion
mar ks or doubl e quot at ion mar ks. St r ings in doubl e quot at ion mar ks ar e sear ched f or
var iabl e names, which ar e r epl aced wit h t heir val ues when f ound; st r ings in singl e
quot at ion mar ks ar e not sear ched.
Consider t he f ol l owing exampl e:
$var = 5;
print ("$var\n");
print ('$var\n');
The f ir st cal l t o print pr int s 5 f ol l owed by a newl ine char act er ; t he second pr int s t he
st r ing $var\n as is.
Per l enabl es you t o use any del imit er you want in pl ace of eit her singl e quot at ion
mar ks or doubl e quot at ion mar ks. To specif y a st r ing t hat -l ike a singl e-quot ed st r ing-is
not sear ched f or var iabl e names, use q f ol l owed by t he del imit er you want t o use. For
exampl e, t he f ol l owing st r ings ar e equival ent :
q!hello $there!
'hello $there'
A usef ul t r ick is t o use newl ine char act er s as del imit er s:
q
this is my string
This exampl e is equival ent t o t he f ol l owing because t he newl ine af t er t he q indicat es
t he beginning of t he st r ing, and t he newl ine af t er string indicat es t he end of t he
st r ing:
'this is my string'
To def ine a st r ing t hat is sear ched f or var iabl e names, use qq:
qq/This string contains $var./
The / char act er s del imit t he st r ing
This string contains $var.
which is t hen sear ched f or var iabl e names. This means t hat $var is r epl aced by it s
cur r ent val ue.
NOTE
If you use a l ef t par ent hesis as t he opening del imit er f or
a st r ing def ined using q or qq, t he Per l int er pr et er
expect s a r ight par ent hesis as t he cl osing del imit er . This
met hod of oper at ion enabl es you t o t r eat q and qq as if
t hey wer e f unct ions:
q(Here is a single quoted string);
qq(Here is a double quoted string);
These ar e equival ent t o bot h of t he f ol l owing:
'Here is a single quoted string'
"Here is a double quoted string"
Be car ef ul not t o l eave a space bet ween t he q or qq and
t he l ef t par ent hesis; if you do, t he Per l int er pr et er wil l
assume t hat t he space char act er , not t he (, is t he
del imit er
qw, def ined in Per l 5, pr ovides a convenient way of br eaking a st r ing int o wor ds. The
f ol l owing st at ement s ar e equival ent :
@words = qw/this is a list of words/;
@words = split(' ', q/this is a list of words/);
In each case, @words is assigned t he l ist
("this", "is", "a", "list", "of", "words")
qw suppor t s any al t er nat ive st r ing del imit er suppor t ed by q and qq.
Defining Strings Using <<
You can use << (t wo l ef t angl e br acket s) t o indicat e t he beginning of a st r ing. This
st r ing cont inues unt il t he next bl ank l ine. The f ol l owing is an exampl e:
$longstring = <<
Here is the first part of the string.
Here is the last part of the string.
# here is the next statement
This exampl e def ines a st r ing consist ing of t he t wo input l ines
Here is the first part of the string.
Here is the last part of the string.
and assigns it t o $longstring. The newl ine char act er s ar e incl uded as par t of t he st r ing.
You can specif y t he char act er s t hat indicat e "end of st r ing" by incl uding t hem af t er t he
<<. For exampl e:
$longstring = <<END
Here is the first part of the string.
Here is the last part of the string.
END
# here is the next statement.
Her e, END indicat es t he end of t he st r ing.
You can encl ose t he end-of -st r ing char act er s in eit her singl e or doubl e quot at ion
mar ks. Singl e-quot ed end-of -st r ing char act er s behave l ike nor mal end-of -st r ing
char act er s:
$longstring = <<'END'
Here is the first part of the string.
Here is the last part of the string.
END
# here is the next statement
Doubl e-quot ed end-of -st r ing char act er s ar e sear ched f or var iabl e names, which ar e
r epl aced by t heir val ues if f ound.
$endchars = "END";
$longstring = <<"$endchars"
Here is the first part of the string.
Here is the last part of the string.
END
# here is the next statement
Her e, $endchars is r epl aced by it s val ue, END, which is used t o indicat e t he end of t he
st r ing.
A st r ing cr eat ed using << can be used wher ever a st r ing is expect ed. For exampl e, t he
st at ement
print <<END
Hello there!
This is a test!
END
wr it es t he f ol l owing t o t he st andar d out put f il e:
Hello there!
This is a test!
(This is one pl ace wher e omit t ing t he par ent heses when you pass an ar gument t o a
f unct ion becomes usef ul .)
You can use t he x oper at or t o wr it e a st r ing mor e t han once:
print <<END x 2
Hello there!
END
This sends t he f ol l owing t o t he st andar d out put f il e:
Hello there!
Hello there!
You can suppl y mor e t han one << at a t ime. If you do, t hey ar e pr ocessed in t he or der in
which t hey ar e r eceived. For exampl e, t he st at ement
$longstring = <<END1 <<END2
This is the first part.
END1
This is the second part.
END2
assigns t he f ol l owing (incl uding t he t r ail ing newl ines) t o $longstring:
This is the first part.
This is the second part.
DON' T l eave a space bet ween t he << and t he end-of -
st r ing char act er s. (If you do, t he Per l int er pr et er wil l
t er minat e t he st r ing when it sees t he next bl ank l ine.)
DON' T put anyt hing el se in t he l ine cont aining t he end-
of -st r ing char act er s.
Special Internal Values
Per l def ines t hr ee special int er nal val ues your pr ogr am can use: __LINE__, __FILE__,
and __END__.
__LINE__ and __FILE__ cont ain, r espect ivel y, t he cur r ent l ine number and cur r ent
f il ename of t he pr ogr am you ar e r unning. These ar e t he val ues t hat die and warn use
when pr int ing t he l ine number and f il ename on which an er r or or a war ning occur s.
__END__ is a special val ue t hat indicat es "end of f il e." Ever yt hing af t er __END__ is
t r eat ed as dat a. If t he pr ogr am is cont ained in a f il e, you can r ead t he dat a af t er
__END__ by r eading f r om t he DATA f il e var iabl e:
$data = <DATA>;
NOTE
__LINE__ and __FILE__ cannot be subst it ut ed int o doubl e-
quot ed st r ings.
You can use t he ^D or ^Z char act er (Ct r l +D or Ct r l +Z)
in pl ace of __END__
__END__ does not need t o appear on a l ine by it sel f as
l ong as some whit e space separ at es it f r om t he next it em
in t he f il e. However , t he f ir st l ine of t he f il e
r epr esent ed by DATA is al ways t he l ine immediat el y
f ol l owing t he __END__. For exampl e:
__END__ Here is some input.
Here is some more input.
In t his case, t he f ir st l ine r ead by <DATA> is
Here is some more input.
The inf or mat ion immediat el y f ol l owing t he __END__ is
l ost .
Using Back Quotes to Invoke System Commands
Per l pr ovides a way t o t r eat t he val ue pr int ed by a syst em command as a st r ing. To do
t his, encl ose t he syst em command in back quot e char act er s (t he ` char act er ).
For exampl e, her e is a way t o incl ude your user name in a Per l pr ogr am:
$myname = `whoami`;
chop ($myname);
The f ir st st at ement cal l s t he syst em command whoami, which pr int s t he name of t he
per son l ogged on. This name is assigned t o $myname. (The cal l t o chop is necessar y because
whoami appends a newl ine char act er t o t he name, which enabl es it t o appear on it s own
l ine on t he scr een.)
The Per l int er pr et er per f or ms var iabl e subst it ut ion on t he st r ing encl osed in back
quot es bef or e t r eat ing it as a syst em command.
$command = "whoami";
$myname = `$command`;
chop ($myname);
Her e, t he val ue of $command, whoami, is subst it ut ed int o t he st r ing encl osed in back
quot es, and it becomes t he syst em command t hat is cal l ed.
When a syst em command is execut ed, t he r et ur n code f r om t he command is st or ed in t he
syst em var iabl e $?. To det er mine whet her t he syst em command has execut ed pr oper l y,
check t his syst em var iabl e. (Nor mal l y, a val ue of zer o indicat es successf ul execut ion,
and any ot her val ue indicat es an er r or . The act ual er r or val ue depends on t he
command.)
To use a char act er ot her t han a back quot e as a del imit er , use qx:
$myname = qx#whoami#;
chop ($myname);
As wit h q and qq, descr ibed pr eviousl y, t he f ir st char act er af t er qx is t r eat ed as t he
st r ing del imit er . The st r ing cont inues unt il anot her st r ing del imit er -in t his case, #-is
seen.
NOTE
If ( is used as an opening st r ing del imit er , ) becomes t he
cl osing st r ing del imit er :
$myname = qx(whoami);
Pattern Matching Using ?? and the reset Function
The ?? pat t er n mat ching oper at or is ident ical t o t he // pat t er n-mat ching oper at or you
have been using al l al ong, except t hat it mat ches onl y once, even if it is inside a l oop.
For exampl e, t he f ol l owing st at ement l oops onl y once, because t he pat t er n ?abc? is not
mat ched t he second t ime it is execut ed:
while ($line =~ ?abc?) {
# stuff goes here
}
To make t he ?? pat t er n mat ching oper at or mat ch again, cal l t he reset f unct ion. This
f unct ion t el l s t he Per l int er pr et er t hat a par t icul ar ?? oper at or can be used t o mat ch
a pat t er n again. List ing 20.2 is an exampl e of a pr ogr am t hat uses ?? and reset.

List ing 20.2. A demonst r at ion of ?? and t he reset f unct ion.
1: #!/usr/local/bin/perl
2:
3: while ($line = <STDIN>) {
4: last unless ($line =~ ?\bthe\b?);
5: print ("$$");
6: reset;
7: }

$ program20_2
this is the first line
this is first line
the next line of input
next line of input
last line-not matched
$
Line 4 of t his pr ogr am uses t he ?? pat t er n mat ching oper at or t o check
whet her t he wor d the appear s in t he cur r ent input l ine. If it does not , t he pr ogr am
t er minat es. If it does, l ine 5 uses t he $` and $_ var iabl es t o pr int t he par t s of t he
l ine not mat ched.
Line 6 cal l s reset, which r eset s t he ?? oper at or in l ine 4. If reset is not cal l ed, l ine
4 wil l not mat ch even if t he new input l ine cont ains t he wor d the.
The ?? oper at or is depr ecat ed in Per l ver sion 5. This
means t hat t he oper at or is st il l suppor t ed but is
consider ed obsol et e. Fut ur e ver sions of Per l might not
suppor t t his oper at or
Using reset with Variables
You al so can use t he reset f unct ion t o cl ear al l var iabl es whose name begins wit h
a specif ied char act er . The f ol l owing st at ement assigns t he nul l st r ing t o al l
scal ar var iabl es whose names begin wit h t he l et t er w (such as, f or inst ance, $which)
and assigns t he empt y l ist t o al l ar r ay var iabl es whose names begin wit h t his
l et t er :
reset ("w");
The f ol l owing st at ement assigns t he nul l st r ing or t he empt y l ist t o al l var iabl es
whose names begin wit h a or e:
reset ("ae");
You can use r anges of l et t er s wit h reset:
reset ("a-d");
This exampl e r eset s al l var iabl es whose names begin wit h a, b, c, or d.
Be car ef ul wit h reset because it r eset s al l var iabl es
whose names begin wit h t he specif ied l et t er s, incl uding
buil t -in var iabl es such as @ARGV.
Other Features of the <> Operator
As you' ve seen, t he <> oper at or r eads f r om t he f il e specif ied by t he encl osed f il e
var iabl e. For exampl e, t he f ol l owing st at ement r eads a l ine f r om t he f il e
r epr esent ed by MYFILE:
$line = <MYFILE>;
The f ol l owing sect ions descr ibe how t o use <> wit h scal ar var iabl e subst it ut ion
and how t o use <> t o cr eat e a l ist of f il enames.
Scalar Variable Substitution and <>
If a scal ar var iabl e is cont ained in t he <> oper at or , t he val ue of t he var iabl e is
assumed t o be t he name of a f il e var iabl e. For exampl e:
$filename = "MYFILE";
$line = <$filename>;
Her e, t he val ue of $filename, MYFILE, is assumed t o be t he f il e var iabl e associat ed
wit h t he input f il e t o r ead f r om. When you change t he val ue of $filename, you
change t he input f il e.
Creating a List of Filenames
UNIX commands t hat manipul at e f il es, such as mv and cp, enabl e you t o suppl y a
pat t er n t o gener at e a l ist of f il enames. Any f il ename mat ching t his pat t er n is
incl uded as par t of t he l ist . For exampl e, t he f ol l owing command copies ever y f il e
whose name ends in .pl t o t he dir ect or y /u/jqpublic/srcdir:
$ cp *.pl /u/jqpublic/srcdir
In Per l , if t he <> oper at or encl oses somet hing ot her t han a f il e var iabl e or a
scal ar var iabl e cont aining a f il e var iabl e, it is assumed t o be a pat t er n t hat
mat ches a l ist of f il es. For exampl e, t he f ol l owing st at ement assigns a l ist of t he
f il enames ending in .pl t o t he ar r ay var iabl e @filelist:
@filelist = <*.pl>;
You can use f il ename pat t er ns in l oops:
while ($line = <*.pl>) {
print ("$line\n");
}
This code pr int s each f il ename ending in .pl on a separ at e l ine.
Global Indirect References and Aliases
On Day 9, " Using Subr out ines," you l ear ned t hat you can pass t he name of an ar r ay
t o a subr out ine using an al ias. For exampl e:
sub my_sub {
local (*subarray) = @_;
$arraylength = @subarray;
}
The *subarray def init ion in my_sub t el l s t he Per l int er pr et er t o oper at e on t he
act ual l ist inst ead of making a copy. When t his subr out ine is cal l ed by a st at ement
such as t he f ol l owing, t he Per l int er pr et er r eal izes t hat myarray and subarray
r ef er t o t he same ar r ay var iabl e:
&my_sub(*myarray);
When a name is given an al ias, al l var iabl es wit h t hat name can be r ef er r ed t o
using t he al ias. This means, in t his exampl e, t hat t he @subarray var iabl e and t he
@myarray var iabl e r ef er t o t he same ar r ay. If t he pr ogr am al so def ines var iabl es
named $subarray and %subarray, you can use $myarray and %myarray, r espect ivel y, t o
r ef er t o t hese var iabl es.
In t he ear l ier exampl e, t he f ol l owing t wo st at ement s:
my_sub (*myarray);
local (*subarray) = @_;
ar e equival ent t o t he assignment
local (*subarray) = *myarray;
In each case, t he name subarray is def ined t o be an al ias of t he name myarray. Because
*subarray is cont ained inside a local def init ion in a subr out ine, subarray and myarray
ar e equival ent onl y whil e t he subr out ine is being execut ed.
If desir ed, you can def ine an al ias f or a name t hat r emains in f or ce t hr oughout
your pr ogr am. For exampl e:
*subarray = *myarray;
If t his st at ement is par t of your main pr ogr am, subarray becomes an al ias f or
myarray in al l par t s of your pr ogr am, incl uding al l subr out ines. The val ues of
$subarray, @subarray, and %subarray, if t hey ar e def ined, ar e l ost .

List ing 20.3 is a simpl e exampl e of a pr ogr am t hat def ines and uses a
gl obal al ias.
List ing 20.3. An exampl e of a gl obal al ias.
1: #!/usr/local/bin/perl
2:
3: *name2 = *name1;
4: $name1 = 14;
5: print ("$name2\n");

$ program20_3
14
$
Line 3 of t his pr ogr am def ines name2 as an al ias f or name1. Ever y var iabl e
named name1 can t her ef or e be r ef er r ed t o using t he name name2. As a r esul t , $name1
and $name2 ar e r eal l y t he same scal ar var iabl e; t his means t hat l ine 5 pr int s t he
val ue assigned in l ine 4.
DON' T use al iases unl ess you absol ut el y must , because
t hey can become ver y conf using.
DO, inst ead, subst it ut e t he var iabl e name int o a st r ing
and t hen execut e it using eval. This is a bet t er way t o
r ef er ence a var iabl e indir ect l y. For exampl e:
$name2 = '$name1';
eval ("$name2 = 14;");
The st r ing $name1 is subst it ut ed f or t he var iabl e name
$name2, yiel ding t he st r ing
$name1 = 14;
eval t hen execut es t his st at ement , which assigns 14 t o
$name1.
Packages
A Per l pr ogr am keeps t r ack of t he var iabl es and subr out ines def ined wit hin it by
st or ing t heir names in a symbol t abl e. In Per l , t he col l ect ion of names in a symbol
t abl e is cal l ed a package. The f ol l owing sect ions descr ibe packages and how t o use
t hem.
Defining a Package
Per l enabl es you t o def ine mor e t han one package f or a pr ogr am, wit h each
package cont ained in a separ at e symbol t abl e. To def ine a package, use t he package
st at ement .
package mypack;
This st at ement cr eat es a new package named mypack. Al l var iabl e and subr out ine
names def ined f r om t his point on in t he pr ogr am ar e st or ed in t he symbol t abl e
associat ed wit h t he new package. This pr ocess cont inues unt il anot her package
st at ement is encount er ed.
Each symbol t abl e cont ains it s own set of var iabl e and subr out ine names, and each
set of names is independent . This means t hat you can use t he same var iabl e name in
mor e t han one package.
$var = 14;
package mypack;
$var = 6;
The f ir st st at ement cr eat es a var iabl e named $var and st or es it in t he main symbol
t abl e. The st at ement f ol l owing t he package st at ement cr eat es anot her var iabl e
named $var and st or es it in t he symbol t abl e f or t he mypack package.
Switching Between Packages
You can swit ch back and f or t h bet ween packages at any t ime. List ing 20.4 shows how
you can car r y out t his act ion.

List ing 20.4. A pr ogr am t hat swit ches bet ween packages.
1: #!/usr/local/bin/perl
2:
3: package pack1;
4: $var = 26;
5: package pack2;
6: $var = 34;
7: package pack1;
8: print ("$var\n");

$ program20_4
26
$
Line 3 def ines a package named pack1. Line 4 cr eat es a var iabl e named
$var, which is t hen st or ed in t he symbol t abl e f or t he pack1 package. Line 5 t hen
def ines a new package, pack2. Line 6 cr eat es anot her var iabl e named $var, which is
st or ed in t he symbol t abl e f or t he pack2 package. Two separ at e copies of $var now
exist , one in each package.
Line 7 specif ies t he pack1 package again. Because pack1 has al r eady been def ined,
t his st at ement j ust set s t he cur r ent package t o be pack1; t her ef or e, al l var iabl e
and subr out ine r ef er ences and def init ions r ef er t o names st or ed in t he symbol
t abl e f or t his package.
As a consequence, when l ine 8 r ef er s t o $var, it r ef er s t o t he $var st or ed in t he
pack1 package. The val ue st or ed in t his var iabl e, 26, is r et r ieved and pr int ed.
The main Package
The def aul t symbol t abl e, in which var iabl e and subr out ine names ar e nor mal l y
st or ed, is associat ed wit h t he package named main. If you have def ined a package
using t he package st at ement and you want t o swit ch back t o using t he nor mal
def aul t symbol t abl e, specif y t he main package as shown her e:
package main;
When t his st at ement is execut ed, your pr ogr am r esumes behaving as t hough no
package st at ement s have ever been seen. Subr out ine and var iabl e names ar e st or ed
as t hey nor mal l y ar e.
Referring to One Package from Another
To r ef er t o a var iabl e or subr out ine def ined in one package f r om inside anot her
package, pr ecede t he var iabl e name wit h t he package name f ol l owed by a singl e
quot at ion-mar k char act er . For exampl e:
package mypack;
$var = 26;
package main;
print ("$mypack'var\n");
Her e, $mypack'var r ef er s t o t he var iabl e named $var l ocat ed in t he package mypack.
Do not put any spaces bet ween t he quot at ion-mar k
char act er and eit her t he package name or t he var iabl e
name. The f ol l owing exampl es ar e not cor r ect :
$mypack ' var
$mypack' var
$mypack 'var
NOTE
In Per l 5, t he package name and var iabl e name ar e
separ at ed by a pair of col ons inst ead of a quot at ion
mar k:
$mypack::var
The quot at ion-mar k char act er is suppor t ed f or now but
might not be under st ood in f ut ur e ver sions of Per l .
Specifying No Current Package
Per l 5 enabl es you t o st at e t hat t her e is t o be no cur r ent package. To do t his,
specif y a package st at ement wit hout a package name, as in t he f ol l owing:
package;
This t el l s t he Per l int er pr et er t hat al l var iabl es must have t heir package names
expl icit l y specif ied in or der f or a st at ement t o be val id.
$mypack::var = 21; # OK
$var = 21; # error - no current package
This r est r ict ion r emains in ef f ect unt il a cur r ent package is expl icit l y def ined by
anot her package st at ement .
Packages and Subroutines
A package def init ion af f ect s al l t he st at ement s in a pr ogr am, incl uding subr out ine
def init ions. For exampl e:
package mypack;
subroutine mysub {
local ($myvar);
# stuff goes here
}
Her e, t he names mysub and myvar ar e bot h par t of t he mypack package. To cal l t he
subr out ine mysub f r om out side t he package mypack, specif y &mypack'mysub.
You can change packages in t he middl e of a subr out ine:
package pack1;
subroutine mysub {
$var1 = 1;
package pack2;
$var1 = 2;
}
This code cr eat es t wo copies of $var1, one in pack1 and one in pack2.
NOTE
Local var iabl es t hat ar e par t of packages can be
r ef er enced onl y in t he subr out ine or st at ement bl ock in
which t hey ar e def ined. (In ot her wor ds, t hey behave
just l ike or dinar y l ocal var iabl es do.)
Defining Private Data Using Packages
The most common use of packages is in f il es cont aining subr out ines and gl obal
var iabl es t hat ar e used in t hese subr out ines. By def ining a package f or t hese
subr out ines, you can ensur e t hat t he gl obal var iabl es used in t he subr out ines ar e
used nowher e el se; such var iabl es ar e cal l ed private data.
Bet t er st il l , you can ensur e t hat t he package name it sel f is used nowher e el se.
List ing 20.5 is an exampl e of a f il e cont aining a package name and var iabl e names
t hat ar e used nowher e el se.

List ing 20.5. A f il e t hat cont ains pr ivat e dat a.
1: package privpack;
2: $valtoprint = 46;
3:
4: package main;
5: # This function is the link to the outside world.
6: sub printval {
7: &privpack'printval();
8: }
9:
10: package privpack;
11: sub printval {
12: print ("$valtoprint\n");
13: }
14:
15: package main;
16: 1; # return value for require

This subr out ine, by it sel f , cannot gener at e it s out put unt il printval is cal l ed.
This f il e can be divided int o t wo par t s: t he par t t hat communicat es wit h
t he out side wor l d and t he par t t hat does t he wor k. The par t t hat communicat es is
in t he main or def aul t package, and t he par t t hat does t he wor k is in a special
package named privpack. This package is def ined onl y in t his f il e.
The subr out ine printval, def ined in l ines 6-8, is designed t o be cal l ed f r om
pr ogr ams and subr out ines def ined el sewher e. It s onl y t ask is t o cal l t he ver sion
of printval def ined in t he privpack package.
The ver sion of printval in t he privpack package pr int s t he number by r et r ieving it
f r om t he scal ar var iabl e $valtoprint. This var iabl e is al so par t of t he privpack
package, and it is def ined onl y inside it .
Lines 15 and 16 ensur e t hat t his f il e behaves pr oper l y if it is incl uded in a pr ogr am
by require. Line 15 set s t he cur r ent package t o t he def aul t package, and l ine 16 is a
nonzer o r et ur n val ue t o ensur e t hat require does not gener at e an er r or .
Packages and System Variables
The f ol l owing var iabl es ar e assumed t o be in t he main package, even when
r ef er enced f r om inside anot her package:
G The f il e var iabl es STDIN, STDOUT, STDERR, and ARGV
G The %ENV, %INC, @INC, $ARGV, and @ARGV var iabl es
G Any syst em var iabl e wit h a special char act er in it s name (such as, f or
exampl e, $_ and $%)
Accessing Symbol Tables
To act ual l y l ook in a symbol t abl e f r om wit hin a pr ogr am, use t he associat ive
ar r ay %_package, in which package is t he name of t he package whose symbol t abl e
you want t o access. For exampl e, t he var iabl e %_main cont ains t he def aul t symbol
t abl e.
Nor mal l y, you wil l not need t o l ook in t he symbol t abl e your sel f .
Modules
Most l ar ge pr ogr ams ar e divided int o component s, each of which per f or ms a
specif ic t ask or set of t asks. Each component nor mal l y cont ains one or mor e
execut abl e f unct ions, pl us t he var iabl es needed t o make t hese f unct ions wor k. The
col l ect ion of f unct ions and var iabl es in a component is known as a program module.
One modul e can appear in a var iet y of pr ogr ams.
Creating a Module
Per l 5 enabl es you t o use packages t o def ine modul es. To def ine a modul e in Per l 5,
cr eat e t he package and st or e it in a f il e of t he same name. For exampl e, a package
named Mymodule woul d be st or ed in t he f il e Mymodule.pm. (The .pm suf f ix indicat es
t hat t he f il e is a Per l modul e.)
List ing 20.6 cr eat es a modul e named Mymodule, cont aining subr out ines myfunc1 and
myfunc2, and var iabl es $myvar1 and $myvar2. This code shoul d be st or ed in t he f il e
Mymodule.pm.

List ing 20.6. Code t hat cr eat es a Per l modul e.
1: #/usr/local/bin/perl
2:
3: package Mymodule;
4: require Exporter;
5: @ISA = qw(Exporter);
6: @EXPORT = qw(myfunc1 myfunc2);
7: @EXPORT_OK = qw($myvar1 $myvar2);
8:
9: sub myfunc1 {
10: $myvar1 += 1;
11: }
12:
13: sub myfunc2 {
14: $myvar2 += 2;
15: }
Lines 3-7 use t he st andar d Per l modul e def init ion convent ions. Line 3
def ines t he package. Line 4 incl udes a buil t -in Per l modul e, Exporter, which
pr ovides inf or mat ion about t hese def init ion convent ions. Lines 6 and 7 def ine t he
subr out ines and var iabl es t hat ar e t o be made avail abl e t o t he out side wor l d.
Line 6 cr eat es a special ar r ay named @EXPORT. This ar r ay l ist s t he subr out ines t hat
can be cal l ed by ot her pr ogr ams. Her e, t he subr out ines myfunc1 and myfunc2 ar e
accessibl e. Any subr out ine def ined inside a modul e t hat is not incl uded in t he l ist
assigned t o @EXPORT is a pr ivat e subr out ine, and can onl y be cal l ed inside t he
modul e.
Line 7 cr eat es anot her special ar r ay, cal l ed @EXPORT_OK, t hat l ist s t he var iabl es
t hat can be accessed by ot her pr ogr ams. Her e, t he var iabl es $myvar1 and $myvar2
ar e accessibl e f r om t he out side wor l d.
Importing Modules Into Your Program
To impor t a modul e int o your Per l pr ogr am, use t he use st at ement . For exampl e,
t he f ol l owing st at ement impor t s t he Mymodule modul e int o a pr ogr am:
use Mymodule;
The subr out ines and var iabl es in Mymodule can now be used in your pr ogr am.
To undef ine a pr eviousl y impor t ed modul e, use t he no st at ement . For exampl e, t he
f ol l owing st at ement undef ines t he Mymodule modul e:
no Mymodule;
List ing 20.7 is an exampl e of a pr ogr am t hat impor t s and undef ines a modul e. The
integer modul e r ef er enced her e specif ies t hat al l ar it hmet ic oper at ions ar e t o be
on int eger s. Fl oat ing-point number s ar e conver t ed t o int eger s bef or e t he
ar it hmet ic oper at ions ar e per f or med.

List ing 20.7. A pr ogr am t hat uses t he use and no st at ement s.
1: #/usr/local/bin/perl
2:
3: use integer;
4: $result = 2.4 + 2.4;
5: print ("$result\n");
6:
7: no integer;
8: $result = 2.4 + 2.4;
9: print ("$result\n");

$ program20_7
4
4.8
$
Line 3 of t his pr ogr am impor t s t he integer modul e. As a consequence, Line
4 conver t s 2.4 t o 2 bef or e per f or ming t he addit ion, yiel ding t he r esul t 4.
Line 7 undef ines t he integer modul e. This t el l s t he Per l int er pr et er t o r ever t t o
using f l oat ing-point number s in ar it hmet ic oper at ions.
If a use or no st at ement appear s inside a st at ement bl ock,
it r emains in ef f ect onl y f or t he dur at ion of t hat bl ock.
For exampl e:
use integer;
$result1 = 2.4 + 2.4;
if ($result1 == 4) {
no integer;
$result2 = 3.4 + 3.4;
}
$result3 = 4.4 + 4.4;
Her e, t he no st at ement is onl y in ef f ect inside t he if
st at ement . In t he st at ement af t er t he if, t he integer
modul e is st il l in use, which means t hat 4.4 is conver t ed
t o 4 bef or e t he addit ion is per f or med.
Using Predefined Modules
Per l 5 pr ovides a var iet y of pr edef ined modul es t hat per f or m usef ul t asks. Each
modul e can be impor t ed by t he use st at ement and r emoved by t he no st at ement .
The f ol l owing ar e some of t he most usef ul modul es in t his l ibr ar y:
int eger As you have seen, t his modul e t el l s Per l t o use int eger
ar it hmet ic inst ead of f l oat ing-point ar it hmet ic.
Diagnost ics Tel l s t he Per l int er pr et er t o pr int mor e diagnost ic
messages (war nings) when r unning your pr ogr am.
Engl ish Al l ows t he use of Engl ish names as synonyms f or syst em
var iabl es.
Env A Per l modul e t hat impor t s envir onment var iabl es.
POSIX The Per l int er f ace t o t he POSIX st andar d (IEEE 1003.1).
Socket Loads t he C pr ogr amming l anguage's socket handl ing
mechanisms.
A compl et e l ist of t he pr edef ined modul es incl uded wit h Per l 5 can be f ound in
your Per l document at ion.
TIP
Per l 5 user s al l over t he wor l d wr it e usef ul modul es
and make t hem avail abl e t o t he Per l communit y t hr ough
t he Int er net . The Compr ehensive Per l Ar chive Net wor k
(CPAN) of Per l ar chives pr ovides a compl et e l ist of t hese
modul es. Mor e inf or mat ion on t he CPAN net wor k is
avail abl e at t he Web sit e l ocat ed at
http://www.perl.com/perl/CPAN/README.html.
Using Perl in C Programs
Per l 5 enabl es you t o cal l Per l subr out ines f r om wit hin C pr ogr ams. To add t his
capabil it y, you need t o do t wo t hings: add r ef er ences t o Per l t o your pr ogr am
sour ce, and t hen l ink t he Per l l ibr ar y when you compil e your pr ogr am.
See t he Per l document at ion f or mor e det ail s on how t o use Per l subr out ines in C
pr ogr ams.
Perl and CGI Scripts
The Common Gat eway Int er f ace (CGI) is a st andar d f or int er f acing ext er nal
appl icat ions wit h inf or mat ion ser ver s (such as t hose f ound on t he Wor l d Wide
Web).
For mor e inf or mat ion on CGI, go t o t he Web page l ocat ed at
http://hoohoo.ncsa.uiuc.edu/cgi. A l ibr ar y of CGI scr ipt s wr it t en in Per l can be
f ound at http://www.bio.cam.ac.uk/web/cgi-lib.pl.txt.
Translators and Other Supplied Code
The Per l dist r ibut ion pr ovides pr ogr ams t hat t r ansl at e t he f ol l owing it ems int o
Per l :
G Pr ogr ams wr it t en in t he awk pr ogr amming l anguage
G Scr ipt s wr it t en f or t he sed command
G Commands sent t o t he find command
G Incl ude f il es wr it t en in t he C pr ogr amming l anguage
For inf or mat ion on t hese t r ansl at ion pr ogr ams, r ef er t o t he document at ion
suppl ied wit h your Per l dist r ibut ion.
Summary
Today you l ear ned about f eat ur es of Per l t hat wer e not discussed on pr evious
days.
G require, which incl udes code f r om ot her f il es
G The $#array var iabl e, which r et ur ns t he l ar gest subscr ipt of an ar r ay
G Al t er nat ive met hods of encl osing st r ings using q, qq, qw, <<, and qx
G The special int er nal val ues __LINE__, __FILE__, and __END__, which r et r ieve
t he cur r ent f il ename and l ine number and end t he pr ogr am
G Using back quot es t o t r eat t he out put f r om a command as a scal ar val ue
G Using ?? t o mat ch a pat t er n once, and using reset t o r eset ?? and var iabl es
G Using <> wit h indir ect f il e var iabl es and f il e l ist s
G Gl obal al iasing using *
G Packages and modul es
G Using Per l in C pr ogr ams
Q&A
Q: Why does a f il e incl uded by require need t o execut e a st at ement ? Why does
require check a r et ur n code?
A: Because f il es incl uded by require can cont ain st at ement s t hat ar e immediat el y
execut ed, checking f or a r et ur n code enabl es pr ogr ams t o det er mine whet her
code incl uded by require gener at ed any er r or s.
Q: Is a $#array var iabl e def ined f or syst em ar r ay var iabl es such as @ARGV?
A: Yes. For exampl e, $#ARGV cont ains t he l ar gest subscr ipt of t he @ARGV ar r ay; you
can t est t his t o det er mine whet her your pr ogr am was passed enough ar gument s.
Q: Ar e $#array var iabl es def ined f or associat ive ar r ays?
A: No, because t her e is no concept of a "l ar gest subscr ipt " in associat ive ar r ays.
Q: What happens t o syst em var iabl es when reset is cal l ed? For exampl e, is
@ARGV r eset when reset is passed "A"?
A: The reset f unct ion af f ect s al l var iabl es, incl uding syst em var iabl es. For t his
r eason, you shoul d be car ef ul when you use reset.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of
t he mat er ial cover ed, and exer cises t o give you exper ience in using what you' ve
l ear ned. Tr y and under st and t he quiz and exer cise answer s bef or e you go on t o
t omor r ow' s l esson.
Quiz
1. What do t hese const ant s cont ain?
a. __LINE__
b. __FILE__
c. __END__
2. What is t he val ue of each of t he f ol l owing st r ings? (Assume t hat $var has
t he val ue hello.)
1. q(It's time to say $var)
2. qq "It's time to say $var"; # a comment
3. qx/echo $var/
2. What is st or ed in @array af t er t he f ol l owing st at ement s have been execut ed?
@array = ("one", "two", "three", "four");
$#array = 2;
$array[4] = "five";
3. How can you incl ude code f r om anot her f il e in your pr ogr am?
Exercises
1. Wr it e a pr ogr am t hat uses t he <> oper at or t o l ist al l t he f il es in a
dir ect or y in al phabet ical or der .
2. Wr it e a pr ogr am t hat uses a subr out ine named sum t o add t he number s in a
l ist and r et ur n t he t ot al . Read t he l ist f r om st andar d input (one per l ine).
Assume t hat t he subr out ine is cont ained in t he f il e
/u/jqpublic/perlfiles/sum.pl. Pr int t he t ot al r et ur ned by sum.
3. Wr it e a pr ogr am t hat cr eat es t wo packages named pack1 and pack2. For each
package, r ead a l ine f r om st andar d input and assign it t o t he var iabl e $var.
Assume t hat each $var cont ains a number , add t he t wo number s t oget her , and
pr int t he t ot al .
4. BUG BUSTER: What is wr ong wit h t he f ol l owing st at ement s?
print ("Perl files in this directory:\n");
$filepattern = "*.pl";
while ($name = <$filepattern>) {
print ("$name\n");
}
5. BUG BUSTER: What is wr ong wit h t he f ol l owing st at ement ?
print << EOF
Here is part of my string.
Here is the rest of my string.
EOF

Chapter 21
The Perl Debugger
CONTENTS
G Ent er ing and Exit ing t he Per l Debugger
H Ent er ing t he Debugger
H Exit ing t he Debugger
G List ing Your Pr ogr am
H The l command
H The - Command
H The w Command
H The // and ?? Commands
H The S Command
G St epping Thr ough Pr ogr ams
H The s Command
H The n Command
H The f command
H The Car r iage-Ret ur n Command
H The r Command
G Displ aying Var iabl e Val ues
H The X Command
H The V Command
G Br eakpoint s
H The b Command
H The c Command
H The L Command and Br eakpoint s
H The d and D Commands
G Tr acing Pr ogr am Execut ion
G Line Act ions
H The a Command
H The A Command
H The < and > Commands
H Displ aying Line Act ions Using t he L Command
G Ot her Debugging Commands
H Execut ing Ot her Per l St at ement s
H The H Command: List ing Pr eceding Commands
H The ! Command: Execut ing Pr evious Commands
H The T Command: St ack Tr acing
H The p Command: Pr int ing an Expr ession
H The = Command: Def ining Al iases
H Pr edef ining Al iases
H The h Command: Debugger Hel p
G Summar y
G Q&A
G Wor kshop
H Quiz
Today's l esson descr ibes t he Per l debugging f acil it y. You'l l l ear n t he f ol l owing:
G How t o ent er and exit t he Per l debugger
G How t o l ist par t s of your pr ogr am
G How t o execut e one st at ement at a t ime
G How t o set br eakpoint s and t r ace pr ogr am execut ion
G How t o per f or m l ine act ions
G About ot her usef ul debugging commands
Entering and Exiting the Perl Debugger
The f ol l owing sect ions descr ibe how t o st ar t t he Per l debugger and how t o exit .
Entering the Debugger
To debug a Per l pr ogr am, specif y t he -d opt ion when you r un t he pr ogr am. For exampl e,
t o debug a pr ogr am named debugtest, specif y t he f ol l owing command:
$ perl -d debugtest
You can suppl y ot her opt ions al ong wit h -d if you want t o.
When t he Per l int er pr et er sees t he -d opt ion, it st ar t s t he Per l debugger . The debugger
begins by displ aying a message simil ar t o t he f ol l owing one on your scr een:
Loading DB routines from $RCSfile: perldb.pl,v $$Revision: 4.0.1.3
$$Date: 92/06/08 13:43:57 $
Emacs support available.
Enter h for help.
main::(debugtest:3): $dircount = 0;
DB<1>
The f ir st f ew l ines displ ay t he dat e on which t his ver sion of t he debugger was cr eat ed.
The onl y l ines of int er est ar e t he l ast t wo.
The second-t o-l ast l ine in t his displ ay l ist s t he l ine t hat t he debugger is about t o
execut e. When t he debugger st ar t s, t he f ir st execut abl e l ine of t he pr ogr am is
displ ayed.
When t he debugger displ ays a l ine t hat it is about t o execut e, it al so pr ovides t he
f ol l owing inf or mat ion about t he l ine:
G The package in which t he l ine is cont ained (in t his case, t he def aul t package,
which is main)
G The name of t he f il e cont aining t he l ine (her e, t he f il e is named debugtest)
G The cur r ent l ine number (which, in t his exampl e, is 3)
The l ast l ine of t he displ ay pr ompt s you f or a debugging command. The number encl osed
in angl e br acket s indicat es t he command number ; in t his case, t he number is 1, because
you ar e about t o specif y t he f ir st debugging command.
Lat er t oday you wil l l ear n how t o use t he debugging command number t o r e-ent er
debugging commands you have pr eviousl y execut ed.
NOTE
To ent er t he debugger wit hout suppl ying a pr ogr am,
suppl y t he -e opt ion wit h t he -d opt ion:
$ perl -d -e "1;"
This l ine st ar t s t he debugger wit h a "pr ogr am" consist ing
of t he singl e st at ement
1;
(which is an expr ession t hat doesn't do anyt hing
meaningf ul ).
St ar t ing t he debugger wit hout a pr ogr am enabl es you t o
examine t he pr edef ined syst em var iabl es or suppl y
st at ement s t o be execut ed. You wil l l ear n how t o
per f or m bot h of t hese t asks l at er in t oday's l esson
Exiting the Debugger
To exit t he debugger , ent er t he debugging command q:
DB<1> q
This command hal t s pr ogr am execut ion immediat el y and r et ur ns you t o t he command
shel l .
Listing Your Program
You can l ist any par t of your pr ogr am f r om wit hin t he debugger . The f ol l owing sect ions
descr ibe debugging commands t hat per f or m t he displ ay oper at ions.
The l command
The simpl est way t o l ist par t of your pr ogr am is wit h t he l command, which l ist s t he next
f ew st at ement s in your pr ogr am:
DB<1> l
3: $dircount = 0;
4: $curdir = "";
5: while (1) {
6: # if we don't have a current directory, get one
7: if ($curdir eq "") {
8: print ("Enter directory to list:\n");
9: $curdir = <STDIN>;
10: $curdir =~ s/^\s+|\s+$//g;
11: $curdir = &followlink($curdir);
12: &readsubdirs($curdir);
The l command l ist s a window of execut abl e st at ement s, which is a gr oup of st at ement s
smal l enough t o be easil y displ ayed on your scr een. A window usual l y consist s of about
t en st at ement s. The l ine number of each st at ement is displ ayed at t he beginning of it s
l ine.
NOTE
The st at ement s displ ayed in t oday's l esson ar e t aken
f r om t he pr ogr am pr esent ed in "Week 2 in Review."
Ent er ing t he l command again displ ays t he window of st at ement s immediat el y f ol l owing
t he l ast displ ayed l ine, which in t his exampl e is l ine 12:
DB<1> l
13: }
14: $curdir = &menudir($curdir);
15: }
16:
17:
18: # Find all subdirectories of the given directory,
19: # and store them in an associative array.
20: #
21: # The associative array subscripts and values are:
22: # <directory name>: 1
You can specif y t he l ines displ ayed by t he l command. If you specif y a singl e l ine number
wit h t he l command, it displ ays t hat l ine:
DB<1> l 10
10: $curdir =~ s/^\s+|\s+$//g;
To displ ay a r ange of l ines, specif y t he f ir st and l ast l ine number , and separ at e t hem
wit h a hyphen:
DB<1> l 10-15
10: $curdir =~ s/^\s+|\s+$//g;
11: $curdir = &followlink($curdir);
12: &readsubdirs($curdir);
13: }
14: $curdir = &menudir($curdir);
15: }
To displ ay a specif ied number of l ines st ar t ing at a cer t ain point , suppl y t he st ar t ing l ine
number , a + char act er , and a number of addit ional l ines t o displ ay:
DB<1> l 10+5
10: $curdir =~ s/^\s+|\s+$//g;
11: $curdir = &followlink($curdir);
12: &readsubdirs($curdir);
13: }
14: $curdir = &menudir($curdir);
15: }
You al so can use t he l command t o specif y a subr out ine t o displ ay. To do t his, pr ovide t he
name of t he subr out ine t o displ ay:
DB<1> l readsubdirs
26: sub readsubdirs {
27: local ($dirname) = @_;
28: local ($dirvar, $subdircount, $name, $index);
29:
30: # open the current directory;
31: # $dircount ensures that each file variable is unique
32: $dirvar = "DIR" . ++$dircount;
33: if (!opendir ($dirvar, $dirname)) {
34: warn ("Can't open $dirname\n");
35: return;
This command l ist s t he st at ement s in t he subr out ine. If t he subr out ine is t oo l ar ge t o f it
in a singl e window, onl y t he f ir st f ew st at ement s ar e l ist ed; you can l ist subsequent
st at ement s by ent er ing l wit h no ar gument s.
The - Command
You can displ ay t he l ines immediat el y pr eceding t he l ast displ ayed l ine by ent er ing t he -
command. For exampl e, t he f ol l owing - command l ist s t he window of l ines immediat el y
pr eceding t he subr out ine readsubdirs.
DB<1> -
16:
17:
18: # Find all subdirectories of the given directory,
19: # and store them in an associative array.
20: #
21: # The associative array subscripts and values are:
22: # <directory name>: 1
23: # (indicates that directory has been read)
24: # <directory name>.<num> the <num>th subdirectory
25:
Subsequent - commands go back f ur t her in t he f il e.
The w Command
To l ist a window of l ines cont aininga specif ied l ine, use t he w command, and specif y t he
number of t he l ine t o be incl uded:
DB<1> w 7
4: $curdir = "";
5: while (1) {
6: # if we don't have a current directory, get one
7: if ($curdir eq "") {
8: print ("Enter directory to list:\n");
9: $curdir = <STDIN>;
10: $curdir =~ s/^\s+|\s+$//g;
11: $curdir = &followlink($curdir);
12: &readsubdirs($curdir);
13: }
The w command displ ays t he t hr ee l ines bef or e t he specif ied l ine and f il l s t he window
wit h t he l ines f ol l owing it .
The // and ?? Commands
You can sear ch f or a l ine cont aining a par t icul ar pat t er n by encl osing t he pat t er n in
sl ashes:
DB<1> /Find/
18: # Find all subdirectories of the given directory,
The debugger sear ches f or war d f r om t he l ast displ ayed l ine f or a l ine mat ching t he
specif ied pat t er n. If it f inds such a l ine, t he l ine is displ ayed.
To sear ch backwar d f or a par t icul ar pat t er n, encl ose t he pat t er n in quest ion mar ks:
DB<1> ?readsubdirs?
12: &readsubdirs($curdir);
This command st ar t s wit h t he l ast displ ayed l ine and sear ches backwar d unt il it f inds a
l ine mat ching t he specif ied pat t er n.
NOTE
Pat t er ns specif ied by // and ?? can cont ain any special
char act er under st ood by t he Per l int er pr et er .
You opt ional l y can omit t he f inal / or ? char act er when
you mat ch a pat t er n.
The S Command
The S command l ist s al l t he subr out ines in t he cur r ent f il e, one subr out ine per l ine:
DB<> S
main::display
main::followlink
main::menudir
main::readsubdirs
Each subr out ine name is pr eceded by t he package name and a singl e quot at ion mar k.
Stepping Through Programs
One of t he most usef ul f eat ur es of t he Per l debugger is t he capabil it y t o execut e a
pr ogr am one st at ement at a t ime. The f ol l owing sect ions descr ibe t he st at ement s t hat
car r y out t his act ion.
The s Command
To execut e a singl e st at ement of your pr ogr am, use t he s command:
DB<2> s
main::(debugtest:4): $curdir = "";
This command execut es one st at ement of your pr ogr am and t hen displ ays t he next
st at ement t o be execut ed. If t he st at ement execut ed needs t o r ead f r om t he st andar d
input f il e, t he debugger wait s unt il t he input is pr ovided bef or e displ aying t he next l ine
t o execut e.
TIP
If you have f or got t en which l ine is t he next l ine t o
execut e (because, f or exampl e, you have displ ayed l ines
using t he l command), you can l ist t he next l ine t o
execut e using t he L command:
DB<2> L
3: $dircount = 0;
The L command l ist s t he l ast l ines execut ed by t he
pr ogr am. It al so l ist s any br eakpoint s and l ine act ions
t hat have been def ined f or par t icul ar l ines. Br eakpoint s
and l ine act ions ar e discussed l at er t oday.
If t he st at ement execut ed by t he s command cal l s a subr out ine, t he Per l debugger
ent er s t he subr out ine but does not execut e any st at ement s in it . Inst ead, it st ops at t he
f ir st execut abl e st at ement in t he subr out ine and displ ays it . For exampl e, if t he
f ol l owing is t he cur r ent l ine:
main::(debugtest:12): &readsubdirs($curdir);
specif ying t he s command t el l s t he Per l debugger t o ent er readsubdirs and displ ay t he
f ol l owing, which is t he f ir st execut abl e l ine of readsubdirs:
main::readsubdirs(debugtest:27): local ($dirname) = @_;
The s command assumes t hat you want t o debug t he subr out ine you have ent er ed. If you
know t hat a par t icul ar subr out ine wor ks pr oper l y and you don't want t o st ep t hr ough
it one st at ement at a t ime, use t he n command, descr ibed in t he f ol l owing sect ion.
The n Command
The n command, l ike t he s command, execut es one l ine of your pr ogr am and displ ays t he
next l ine t o be execut ed:
DB<2> n
main::(debugtest:5): while (1) {
The n st at ement , however , does not ent er any subr out ines. If t he st at ement execut ed by
n cont ains a subr out ine cal l , t he subr out ine is execut ed in it s ent ir et y. Af t er t he
subr out ine is execut ed, t he debugger displ ays t he l ine immediat el y f ol l owing t he cal l .
For exampl e, if t he cur r ent l ine is
main::(debugtest:12): &readsubdirs($curdir);
t he n command t el l s t he debugger t o execut e readsubdirs and t hen displ ay t he next
l ine in t he pr ogr am, which is
main::(debugtest:13:): }
Combining t he use of s and n ensur es t hat t he debugger examines onl y t he subr out ines
you want t o see.
NOTE
The Per l debugger does not enabl e you t o ent er any
l ibr ar y f unct ions. You can ent er onl y subr out ines t hat
you have cr eat ed your sel f or t hat have been cr eat ed
pr eviousl y and added t o a subr out ine l ibr ar y
The f command
The f command t el l s t he Per l debugger t o execut e t he r emainder of t he st at ement s in
t he cur r ent subr out ine and t hen displ ay t he l ine immediat el y af t er t he subr out ine cal l .
This is usef ul when you ar e l ooking f or a bug and have det er mined t hat t he cur r ent
subr out ine does not cont ain t he pr obl em.
The Carriage-Return Command
If you ar e st epping t hr ough a pr ogr am using s or n, you can save your sel f some t yping by
just pr essing Ent er when you want t o execut e anot her st at ement . When you pr ess
Ent er , t he debugger r epeat s t he l ast s or n command execut ed.
For exampl e, t o st ep f r om l ine 5 t o l ine 7, you can use t he s command as usual :
DB<3> s
main::(debugtest:7): if ($curdir eq "") {
(Line 6 is skipped because it cont ains no execut abl e st at ement s.) To execut e l ine 7, you
can now just pr ess Ent er :
DB<2>
main::(debugtest:8): print ("Enter directory to
list:\n");
NOTE
Pr essing Ent er has no ef f ect if you have not specif ied any
s or n commands.
The r Command
If you ar e inside a subr out ine and decide t hat you no l onger need t o st ep t hr ough it , you
can t el l t he Per l debugger t o f inish execut ing t he subr out ine and r et ur n t o t he
st at ement af t er t he subr out ine cal l . To do t his, use t he r command:
DB<4> r
main::(debugtest:13:): }
The st at ement displ ayed by t he debugger is t he f ir st st at ement f ol l owing t he cal l t o
t he subr out ine.
Displaying Variable Values
Anot her power f ul f eat ur e of t he Per l debugger is t he capabil it y t o displ ay t he val ue of
any var iabl e at any t ime. The f ol l owing sect ions descr ibe t he commands t hat per f or m
t his act ion.
The X Command
The X command displ ays var iabl es in t he cur r ent package (which is main if no ot her
package has been specif ied). If t he X command is specif ied by it sel f , it l ist s al l t he
var iabl es in t he cur r ent package, incl uding t he syst em-def ined var iabl es and t he
var iabl es used by t he Per l int er pr et er it sel f . Usual l y, you won't want t o use t he X
command by it sel f , because t her e ar e a l ot of syst em-def ined and int er nal var iabl es
known t o t he Per l int er pr et er .
To pr int t he val ue of a par t icul ar var iabl e or var iabl es, specif y t he var iabl e name or
names wit h t he X command:
DB<5> X dircount
$dircount = '0'
This capabil it y of t en is usef ul when you ar e checking f or er r or s in your pr ogr am.
You must not suppl y t he $ char act er wit h t he var iabl e
name when you use t he X command. If you suppl y t he $
char act er (or t he @ or % char act er s f or ar r ays), t he
debugger displ ays not hing.
You can use X t o displ ay t he val ues of ar r ay var iabl es and associat ive ar r ay var iabl es.
DB<6> X regarray
@regarray = (
0 14
1 'hello'
2 36
)
DB<7> X assocarray
%assoc_array = (
'hi' 1
'there' 2
)
Each command pr int s t he subscr ipt s of t he ar r ay and t heir val ues. Regul ar ar r ays ar e
pr int ed in or der of subscr ipt ; associat ive ar r ays ar e pr int ed in no par t icul ar or der .
NOTE
If you have an ar r ay var iabl e and a scal ar var iabl e wit h
t he same name, t he X command pr int s bot h var iabl es:
DB<8> X var
$var = '0'
@var = (
0 'test1'
1 'test2'
)
Ther e is no way t o use X t o displ ay one var iabl e but not
t he ot her .
The V Command
The V command is ident ical t o t he X command except t hat it pr int s t he val ues of
var iabl es in any package. If you specif y just a package name, as in t he f ol l owing, t his
command displ ays t he val ues of al l var iabl es in t he package (incl uding syst em-def ined
and int er nal var iabl es):
DB<9> V mypack
If you specif y a package name and one or mor e var iabl e names, as in t he f ol l owing, t he
debugger pr int s t he val ues of t he var iabl es (if t hey ar e def ined in t hat package):
DB<10> V main dircount
$dircount = '0'
Breakpoints
As you have seen, you can t el l t he Per l debugger t o execut e one st at ement at a t ime.
Anot her way of cont r ol l ing pr ogr am execut ion is t o t el l t he debugger t o execut e up t o
a cer t ain specif ied point in t he pr ogr am, cal l ed a breakpoint.
The f ol l owing sect ions descr ibe t he commands t hat cr eat e br eakpoint s, and t he command
t hat execut es unt il a br eakpoint is det ect ed.
The b Command
To set a br eakpoint in your pr ogr am, use t he b command. This command t el l s t he
debugger t o hal t pr ogr am execut ion whenever it is about t o execut e t he specif ied l ine.
For exampl e, t he f ol l owing command t el l s t he debugger t o hal t when it is about t o
execut e l ine 10:
DB<11> b 10
(If t he l ine is not br eakabl e, t he debugger wil l r et ur n Line 10 is not breakable.)
NOTE
You can have as many br eakpoint s in your pr ogr am as you
want . The debugger wil l hal t pr ogr am execut ion if it is
about t o execut e any of t he st at ement s at which a
br eakpoint has been def ined.
The b command al so accept s subr out ine names:
DB<12> b menudir
This set s a br eakpoint at t he f ir st execut abl e st at ement of t he subr out ine menudir.
You can use t he b command t o t el l t he pr ogr am t o hal t onl y when a specif ied condit ion
is t r ue. For exampl e, t he f ol l owing command t el l s t he debugger t o hal t if it is about t o
execut e l ine 10 and t he var iabl e $curdir is equal t o t he nul l st r ing:
DB<12> b 10 ($curdir eq "")
The condit ion specif ied wit h t he b st at ement can be any l egal Per l condit ional
expr ession.
If a st at ement is l onger t han a singl e l ine, you can set a
br eakpoint onl y at t he f ir st l ine of t he st at ement :
71: print ("Test",
72: " here is more output");
Her e, you can set a br eakpoint at l ine 71, but not l ine 72.
The c Command
Af t er you have set a br eakpoint , you can t el l t he debugger t o execut e unt il it r eaches
eit her t he br eakpoint or t he end of t he pr ogr am. To do t his, use t he c command:
DB<13> c
main::(debugtest:10): $curdir =~ s/^\s+|\s+$//g;
DB<14>
When t he debugger det ect s t hat it is about t o execut e l ine 10-t he l ine at which t he
br eakpoint was set -it hal t s and displ ays t he l ine. (Recal l t hat t he debugger al ways
displ ays t he l ine it is about t o execut e.)
The debugger now pr ompt s you f or anot her debugging command. This act ion enabl es you
t o st ar t execut ing one st at ement at a t ime using n or s, cont inue execut ion using c, set
mor e br eakpoint s using b, or per f or m any ot her debugging oper at ion.
You can specif y a t empor ar y (one-t ime-onl y) br eakpoint wit h t he c command by suppl ying
a l ine number :
DB<15> c 12
main::(debugtest:12): &readsubdirs($curdir);
The ar gument 12 suppl ied wit h t he c command t el l s t he debugger t o def ine a t empor ar y
br eakpoint at l ine 12 and t hen r esume execut ion. When t he debugger r eaches l ine 12, it
hal t s execut ion, displ ays t he l ine, and del et es t he br eakpoint . (The l ine it sel f st il l
exist s, of cour se.)
Using c t o def ine a t empor ar y br eakpoint is usef ul if you want t o skip a f ew l ines
wit hout wast ing your t ime execut ing t he pr ogr am one st at ement at a t ime. Using c al so
means t hat you don't have t o bot her def ining a br eakpoint using b and del et ing it using
d (descr ibed in t he f ol l owing sect ion).
TIP
If you int end t o def ine br eakpoint s using c or b, it is a
good idea t o ensur e t hat each l ine of your pr ogr am
cont ains at most one st at ement . If you ar e in t he habit of
wr it ing l ines t hat cont ain mor e t han one st at ement ,
such as
$x++; $y++;
you won't get as much use out of t he debugger , because
it can't st op in t he middl e of a l ine
The L Command and Breakpoints
To l ist al l of your br eakpoint s, use t he L command. This command l ist s t he l ast f ew l ines
execut ed, t he cur r ent l ine, t he br eakpoint s you have def ined, and t he condit ions under
which t he br eakpoint s go int o ef f ect .
DB<16> L
3: $dircount = 0;
4: $curdir = "";
5: while (1) {
7: if ($curdir eq "") {
10: $curdir =~ s/^\s+|\s+$//g;
break if (1)
Her e, t he pr ogr am has execut ed l ines 3-7, and a br eakpoint is def ined f or l ine 10. (Line 6
is not l ist ed because it is a comment .) You can dist inguish br eakpoint s f r om execut ed
l ines by l ooking f or t he br eakpoint condit ional expr ession, which immediat el y f ol l ows
t he br eakpoint . Her e, t he condit ional expr ession is (1), which indicat es t hat t he
br eakpoint is al ways in ef f ect .
The d and D Commands
When you ar e f inished wit h a br eakpoint , you can del et e it using t he d command.
DB<16> d 10
This command t el l s t he debugger t o del et e t he br eakpoint at l ine 10. The l ine it sel f
r emains in t he pr ogr am.
If you do not specif y a br eakpoint t o del et e, t he debugger assumes t hat a br eakpoint is
def ined f or t he next l ine t o be execut ed, and del et es it .
main::(debugtest:12): &readsubdirs($curdir);
DB<17> d
Her e, l ine 12 is t he next l ine t o be execut ed, so t he debugger del et es t he br eakpoint at
l ine 12.
To del et e al l your br eakpoint s, use t he D command.
DB<18> D
This command del et es al l t he br eakpoint s you have def ined wit h t he b command.
Tracing Program Execution
When you r un a pr ogr am using t he Per l debugger , you can t el l it t o displ ay each l ine as
it is execut ed. When t he debugger is doing t his, it is said t o be in trace mode.
To t ur n on t r ace mode, use t he T command.
DB<18> t
Trace = on
When a st at ement is execut ed in t r ace mode, t he st at ement is displ ayed. For exampl e, if
t he cur r ent l ine is l ine 5 and t he command c 10 (which execut es up t o l ine 10) is ent er ed,
t he f ol l owing is displ ayed:
DB<18> c 10
main::(debugtest:5): while (1) {
main::(debugtest:7): if ($curdir eq "") {
main::(debugtest:10): $curdir =~ s/^\s+|\s+$//g;
DB<19>
The debugger pr int s and execut es l ine 5 and l ine 7, t hen displ ays l ine 10 and wait s f or
f ur t her inst r uct ions.
To t ur n of f t r ace mode, specif y t he t command again.
DB<19> t
Trace = off
At t his point , t r ace mode is t ur ned of f unt il anot her t command is ent er ed.
Line Actions
The Per l debugger enabl es you t o specif y one or mor e st at ement s t o be execut ed
whenever t he pr ogr am r eaches a specif ied l ine. Such st at ement s ar e known as l ine
act ions. The most common l ine act ions ar e pr int ing t he val ue of a var iabl e and r eset t ing
a var iabl e cont aining an er r oneous val ue t o t he val ue you want .
The f ol l owing sect ions descr ibe t he debugging commands t hat def ine l ine act ions.
The a Command
To specif y a l ine act ion f or a par t icul ar l ine, use t he a command.
DB<19> a 10 print ("curdir is $curdir\n");
This command t el l s t he debugger t o execut e t he st at ement
print ("curdir is $curdir\n");
whenever it is about t o execut e l ine 10 of t he pr ogr am. The debugger per f or ms t he
act ion just af t er it displ ays t he cur r ent l ine and bef or e it asks f or t he next debugging
command.
To cr eat e a l ine act ion cont aining mor e t han one st at ement , just st r ing t he st at ement s
t oget her . If you need mor e t han one l ine f or t he st at ement s, put a backsl ash at t he end
of t he f ir st l ine.
DB<20> a 10 print ("curdir is $curdir\n"); print \
("this is a long line action\n");
In t his case, when t he debugger r eaches l ine 10, it execut es t he f ol l owing st at ement s:
print ("curdir is $curdir\n");
print ("this is a long line action\n");
The A Command
To del et e t he l ine act ions def ined using t he a command, use t he A command.
DB<21> A
This command del et es al l l ine act ions cur r ent l y def ined.
NOTE
The A command does not af f ect t he < and > commands,
descr ibed in t he f ol l owing sect ion.
The < and > Commands
To def ine a l ine act ion t hat is t o be execut ed bef or e t he debugger execut es any f ur t her
st at ement s, use t he > command.
DB<21> > print ("curdir before execution is $curdir\n");
This command t el l s t he debugger t o pr int t he val ue of $curdir bef or e cont inuing.
Simil ar l y, t he < command def ines a l ine act ion t hat is t o be per f or med af t er t he
debugger has f inished execut ing st at ement s and bef or e it asks f or anot her debugging
command:
DB<22> < print ("curdir after execution is $curdir\n");
This command t el l s t he debugger t o pr int t he val ue of $curdir bef or e hal t ing execut ion
again.
The < and > commands ar e usef ul when you know t hat one of your var iabl es has t he
wr ong val ue, but you don't know which st at ement assigned t he wr ong val ue t o t he
var iabl e. By singl e-st epping t hr ough t he pr ogr am using s or n, and pr int ing t he var iabl e
eit her bef or e or af t er execut ing each st at ement , you can det er mine wher e t he var iabl e
was given it s incor r ect val ue.
NOTE
To del et e a l ine act ion def ined by t he < command, ent er
anot her < command wit h no l ine act ion def ined.
DB<23> <
Simil ar l y, t he f ol l owing command undoes t he ef f ect s of
a > command:
DB<24> >
Displaying Line Actions Using the L Command
The L command pr int s any l ine act ions you have def ined using t he a command (as wel l as
br eakpoint s and execut ed l ines). For exampl e, suppose t hat you have def ined a l ine
act ion using t he f ol l owing command:
DB<25> a 10 print ("curdir is $curdir\n");
The L command t hen displ ays t his l ine act ion as shown her e:
main::(debugtest:10): $curdir =~ s/^\s+|\s+$//g;
action: print ("curdir is $curdir\n");
The l ine act ion is al ways displ ayed immediat el y af t er t he l ine f or which it is def ined.
This met hod of displ ay enabl es you t o dist inguish l ines cont aining l ine act ions f r om
ot her l ines displ ayed by t he L command.
Other Debugging Commands
The f ol l owing sect ions descr ibe t he debugging commands not pr eviousl y cover ed.
Executing Other Perl Statements
In t he debugger , anyt hing t hat is not a debugging command is assumed t o be a Per l
st at ement and is per f or med r ight away. For exampl e:
DB<4> @array = (1, 2, 3);
You can use st at ement s such as t his t o al t er val ues in your pr ogr am as it is being
execut ed. This capabil it y is usef ul when you ar e t est ing your code.
NOTE
If you wish, you can omit t he semicol on at t he end of t he
st at ement .
The H Command: Listing Preceding Commands
The H (f or "hist or y") command l ist s t he pr eceding f ew commands you have ent er ed.
DB<4> H
3: b 7
2: b 14
1: b 13
The commands ar e l ist ed in r ever se or der , wit h t he most r ecent l y execut ed command
l ist ed f ir st . Each command is pr eceded by it s command number , which is used by t he !
command (descr ibed in t he f ol l owing sect ion).
NOTE
The debugger saves onl y t he commands t hat act ual l y
af f ect t he debugging envir onment . Commands such as l
and s, which per f or m usef ul wor k but do not change how
t he debugger behaves, ar e not l ist ed by t he H command.
This is not a signif icant l imit at ion because you can ent er
t he l et t er again if needed.
The ! Command: Executing Previous Commands
Each command t hat is saved by t he debugger and can be l ist ed by t he H command has a
command number . You can use t his command number t o r epeat a pr eviousl y execut ed
command. For exampl e, t o r epeat command number 5, make t he f ol l owing ent r y:
DB <11> !5
b 8
DB <12>
The debugger displ ays command number 5-in t his case, t he command b 8- and t hen
execut es it .
If you omit t he number , t he debugger r epeat s t he l ast command execut ed.
DB <12> $foo += $bar + 1
DB <13> !
$foo += $bar + 1
DB <14>
If you specif y a negat ive number wit h !, t he debugger skips back t hat many commands:
DB <14> $foo += $bar + 1
DB <15> $foo *= 2
DB <16> ! -2
$foo += $bar + 1
DB <17>
Her e, t he ! -2 command r ef er s t o t he command $foo += $bar + 1.
You can use ! onl y t o r epeat commands t hat ar e
act ual l y r epeat abl e. Use t he H command t o l ist t he
commands t hat t he debugger has saved and t hat can be
r epeat ed
The T Command: Stack Tracing
The T command enabl es you t o displ ay a st ack t r ace, which is a col l ect ion of al l t he
subr out ines t hat have been cal l ed, l ist ed in r ever se or der . Her e is an exampl e:
DB <16> T
$ = &main::sub2('hi') from file debug1 line 7
$ = &main::sub1('hi') from file debug1 line 3
Her e, t he T command indicat es t hat t he pr ogr am is cur r ent l y inside subr out ine sub2,
which was cal l ed f r om l ine 7 of your pr ogr am; t his subr out ine is par t of t he main
package. The cal l t o sub2 is passed t he ar gument 'hi'.
The $ = pr eceding t he subr out ine name indicat es t hat t he subr out ine cal l is expect ing a
scal ar r et ur n val ue. If t he cal l is expect ing a l ist t o be r et ur ned, t he char act er s @ =
appear in f r ont of t he subr out ine name.
The next l ine of t he displ ayed out put t el l s you t hat sub2 was cal l ed by anot her
subr out ine, sub1. This subr out ine was al so passed t he ar gument 'hi', and it was cal l ed
by l ine 3 of t he pr ogr am. Because t he st ack t r ace l ist s no mor e subr out ines, l ine 3 is par t
of your main pr ogr am.
NOTE
The l ist of ar gument s passed t o a subr out ine t hat is
displ ayed by t he st ack t r ace is t he l ist of act ual val ues
af t er var iabl e subst it ut ion and expr ession eval uat ion
ar e per f or med. This pr ocedur e enabl es you t o use t he
st ack t r ace t o check whet her your subr out ines ar e being
passed t he val ues you expect .
The p Command: Printing an Expression
An easy way t o pr int t he val ue of an expr ession f r om inside t he debugger is t o use t he p
command.
DB <17> p $curdir + 1
1
The p command eval uat es t he expr ession and displ ays t he r esul t .
NOTE
The p command wr it es t o t he scr een even when t he
pr ogr am has r edir ect ed STDOUT t o a f il e.
The = Command: Defining Aliases
If you f ind your sel f r epeat edl y ent er ing a l ong debugging command and you want t o
save your sel f some t yping, you can def ine an al ias f or t he l ong command by using t he =
command. For exampl e:
DB <15> = pc print ("curdir is $curdir\n");
= pc print ("curdir is $curdir\n");
The = command pr int s t he al ias you have just def ined and t hen st or es it in t he
associat ive ar r ay %DB'alias (package DB, ar r ay name alias) f or f ut ur e r ef er ence. Fr om
her e on, t he command
DB <16> pc
is equival ent t o t he command
DB <16> print ("curdir is $curdir\n");
To l ist t he al iases you have def ined so f ar , ent er t he = command by it sel f :
DB <17> =
pc = print ("curdir is $curdir\n")
This command displ ays your def ined al iases and t heir equival ent val ues.
Predefining Aliases
You can def ine al iases t hat ar e t o be cr eat ed ever y t ime you ent er t he Per l debugger .
When t he debugger st ar t s, it f ir st sear ches f or a f il e named .perldb in your home
dir ect or y. If t he debugger f inds t his f il e, it execut es t he st at ement s cont ained t her e.
To cr eat e an al ias, add it t o t he .perldb f il e. For exampl e, t o add t he al ias
= pc print ("curdir is $curdir\n");
add t he f ol l owing st at ement t o your .perldb f il e:
$DB'alias{"pc"} = 's/^pc/print ("curdir is $curdir\n");/';
Her e's how t his wor ks: when t he Per l debugger cr eat es an al ias, it adds an el ement t o
t he $DB'alias associat ive ar r ay. The subscr ipt f or t his el ement is t he al ias you ar e
def ining, and t he val ue is a subst it ut ion command t hat r epl aces t he al ias wit h t he
act ual command you want t o use. In t he pr eceding exampl e, t he subst it ut ion t akes any
command st ar t ing wit h pc and r epl aces it wit h
print ("curdir is $curdir\n");
Be car ef ul when you def ine al iases in t his way. For
exampl e, your subst it ut ion shoul d mat ch onl y t he
beginning of a command, as in /^pc/. Ot her wise, t he al ias
wil l r epl ace any occur r ence of t he l et t er s pc wit h your
pr int command, which is not what you want .
The h Command: Debugger Help
The h (f or hel p) command pr ovides a l ist of each of t he debugger commands l ist ed in
t oday's l esson, al ong wit h a one-l ine expl anat ion of each. This is handy if you ar e in t he
middl e of debugging a pr ogr am and f or get t he synt ax of a par t icul ar command.
Summary
Today, you have l ear ned about t he Per l debugger . This debugger enabl es you t o per f or m
t he f ol l owing t asks, among ot her s:
G List any par t of your sour ce f il e
G St ep t hr ough your pr ogr am one st at ement at a t ime
G Displ ay any var iabl es you have def ined
G Set br eakpoint s, which t el l t he debugger when t o st op and r equest f ur t her
commands
G Set l ine act ions, which ar e st at ement s t o be execut ed when t he pr ogr am r eaches a
par t icul ar l ine
G Tr ace pr ogr am execut ion as it happens
G Pr int a st ack t r ace, which l ist s t he cur r ent subr out ine you ar e in and t he
subr out ines t hat cal l ed it
Q&A
Q: Is it possibl e t o ent er mor e t han one debugging command at a t ime?
A: No; however , t her e's no r eal need t o do so. If you want t o per f or m sever al singl e
st eps at once, use t he c command t o skip ahead t o a specif ied point . If you want t o
bot h st ep ahead and pr int t he val ue of a var iabl e, use t he < or > command.
Q: Is it possibl e t o examine var iabl es in one package whil e inside anot her ?
A: Yes. Use t he V command or t he st andar d Per l package/var iabl e synt ax.
Q: If I discover t hat my pr ogr am wor ks and I want t o t ur n of f debugging, what
do I do?
A: You cannot exit t he debugger in t he middl e of a pr ogr am. However , if you del et e
al l br eakpoint s and l ine act ions and t hen ent er t he c command, t he pr ogr am
begins execut ing nor mal l y and is no l onger under cont r ol of t he debugger .
Q: How can I conver t t o a r eusabl e br eakpoint a one-t ime br eakpoint cr eat ed
using c?
A: By def aul t , t he b command set s a br eakpoint at t he l ine t hat is about t o be
execut ed. This is t he l ine at which c has set it s one-t ime br eakpoint .
Q: How can I execut e ot her UNIX commands f r om inside t he debugger ?
A: Ent er a st at ement cont aining a cal l t o t he Per l system f unct ion. For exampl e, t o
displ ay t he cont ent s of t he cur r ent dir ect or y, ent er t he f ol l owing command:
DB <11> system ("ls");
To t empor ar il y escape f r om t he debugger t o a UNIX shel l , ent er t he f ol l owing
command:
DB <12> system ("sh");
When you ar e f inished wit h t he shel l , ent er t he command exit , and you wil l
r et ur n t o t he debugger .
Q: What special buil t -in var iabl es can be accessed f r om inside t he debugger ?
A: Al l of t hem.
Workshop
The Wor kshop pr ovides quiz quest ions t o hel p you sol idif y your under st anding of t he
mat er ial cover ed.
Quiz
1. Def ine t he f ol l owing t er ms:
1. t r ace mode
2. st ack t r ace
3. br eakpoint
4. l ine act ion
2. Expl ain t he dif f er ences bet ween t he X and V commands.
3. Expl ain t he dif f er ences bet ween t he // and ?? commands.
4. Expl ain t he dif f er ences bet ween t he < and > commands.
5. Expl ain t he dif f er ences bet ween t he s and n commands.
6. What do t he f ol l owing commands do?
1. l
2. l 26
3. l 5-7
4. l 5+7
5. w

Week
3
Week 3 in Review
In t he f inal week of t eaching your sel f how t o use Per l , you've l ear ned about t he
ext ensive Per l f unct ion l ibr ar y and about buil t -in syst em var iabl es and opt ions. The pair
of pr ogr ams in List ings R3.1 and R3.2 use some of t he f eat ur es you've l ear ned about
dur ing t his week.
These pr ogr ams pr ovide a simpl e "chat " ser vice. The f ir st pr ogr am, t he chat ser ver ,
est abl ishes connect ions wit h cl ient s and passes messages back and f or t h. The second
pr ogr am, t he chat cl ient , enabl es user s t o est abl ish connect ions t o t his ser ver and send
messages t o t he ot her user s r unning t he chat pr ogr am.
Each message t hat a user ent er s is sent t o al l t he cl ient s cur r ent l y r unning t he chat
pr ogr am. To quit chat t ing, t he user ent er s quit.
The ser ver pr ogr am can be cal l ed wit h t he -m (f or monit or ) opt ion. When -m is specif ied,
each message sent by a cl ient is displ ayed by t he ser ver as it is sent .

List ing R3.1. The chat ser ver pr ogr am.
1: #!/usr/local/bin/perl -s
2:
3: # get port from command line, or use 2000 as default
4: if ($#ARGV == -1) {
5: $port = 2000;
6: } else {
7: $port = $ARGV[0];
8: }
9: if (getservbyport($port, "tcp")) {
10: die ("can't access port $port\n");
11: }
12:
13: # initialization stuff
14: $nextport = $port + 1;
15: $maxclient = 0;
16:
17: # establish main socket connection: clients use this to
18: # get ports for their own connections
19: ($d1, $d2, $prototype) = getprotobyname ("tcp");
20: $hostname = 'hostname';
21: chop ($hostname);
22: ($d1, $d2, $d3, $d4, $serverraddr) = gethostbyname ($hostname);
23: $serveraddr = pack ("Sna4x8", 2, $port, $serverraddr);
24: socket (SSOCKET, 2, 1, $prototype) ||
25: die ("No main server socket\n");
26: bind (SSOCKET, $serveraddr) ||
27: die ("Can't bind main server socket\n");
28: listen (SSOCKET, 5) ||
29: die ("Can't listen on main server socket\n");
30: select (STDOUT);
31: $| = 1;
32:
33: while (1) {
34: # listen for clients
35: ($clientaddr = accept (SOCKET, SSOCKET)) ||
36: die ("Can't accept connection to main socket\n");
37: select (SOCKET);
38: $| = 1;
39: # find ports for new client
40: $recvport = $nextport;
41: while (getservbyport($recvport, "tcp")) {
42: $recvport++;
43: }
44: $nextport = $recvport + 1;
45: print SOCKET ("$recvport\n");
46: $sendport = $nextport;
47: while (getservbyport($sendport, "tcp")) {
48: $sendport++;
49: }
50: $nextport = $sendport + 1;
51: # send ports to client
52: print SOCKET ("$sendport\n");
53: print SOCKET ("$$\n");
54: close (SOCKET);
55: # now connect for this client: first receive, then send
56: socket (C1SOCKET, 2, 1, $prototype) ||
57: die ("No receive client socket\n");
58: $msgaddr = pack ("Sna4x8", 2, $recvport, $serverraddr);
59: bind (C1SOCKET, $msgaddr) ||
60: die ("Can't bind receive client\n");
61: listen (C1SOCKET, 1) ||
62: die ("Can't listen for receive client\n");
63: $rsockname = "CRSOCKET" . $maxclient;
64: ($clientaddr = accept ($rsockname, C1SOCKET)) ||
65: die ("Can't accept receive client\n");
66: socket (C2SOCKET, 2, 1, $prototype) ||
67: die ("No send client socket\n");
68: $msgaddr = pack ("Sna4x8", 2, $sendport, $serverraddr);
69: bind (C2SOCKET, $msgaddr) ||
70: die ("Can't bind send client\n");
71: listen (C2SOCKET, 1) ||
72: die ("Can't listen for send client\n");
73: $ssockname = "CSSOCKET" . $maxclient;
74: ($clientaddr = accept ($ssockname, C2SOCKET)) ||
75: die ("Can't accept send client\n");
76: select ($ssockname);
77: $| = 1;
78: # when a new client is created, we have to kill all the
79: # existing children and start new ones, so that all
80: # of the sockets are known to all of the clients
81: for ($i = 0; $i <= $maxclient-1; $i++) {
82: kill (2, $procids[$i]);
83: }
84: for ($i = 0; $i <= $maxclient; $i++) {
85: if ($child = fork()) {
86: # parent: continue forking
87: $procids[$i] = $child;
88: } else {
89: # child: communicate with this client
90: &talk_to_client ($i, $maxclient);
91: exit(0);
92: }
93: }
94: # once we're done forking, go back and listen for
95: # more clients
96: $maxclient += 1;
97: }
98:
99: sub talk_to_client {
100: local ($clientnum, $maxclient) = @_;
101: local ($msg, $i, $count, $rsockname, $sockname);
102:
103: # get read socket for this client
104: $rsockname = "CRSOCKET" . $clientnum;
105: while (1) {
106: $msg = <$rsockname>;
107: last if ($msg eq "quit");
108: if ($m) {
109: select (STDOUT);
110: print ("$msg");
111: }
112:
113: # send message to all other clients
114: for ($i = 0; $i <= $maxclient; $i++) {
115: $sockname = "CSSOCKET" . $i;
116: select ($sockname);
117: print ("$msg");
118: }
119: }
120: }
This pr ogr am st ar t s of f by obt aining t he number of t he por t t o be used f or t he
main socket connect ion. This por t number is assumed t o be t he f ir st ar gument on t he
command l ine; if no por t number is suppl ied, 2000 is used. Lines 9-11 cal l getservbyport t o
check whet her t his por t number is ment ioned in t he /etc/services f il e. If it is, t he por t
number is r eser ved f or use by some ot her pr ogr am and can't be used her e.
Next , l ines 17-29 def ine a socket using t he specif ied por t number . Cl ient pr ogr ams use t his
socket t o est abl ish connect ions t o t he ser ver . Not e, in par t icul ar , t hat l ines 20-21 r ead
t he machine name by cal l ing t he UNIX hostname command. This enabl es you t o move t his
pr ogr am t o anot her machine wit hout having t o edit it .
Once t he main socket has been est abl ished, t he ser ver is r eady t o l ist en f or cl ient s.
When a cl ient est abl ishes a connect ion, t he ser ver f inds t wo unused por t number s and
sends t hem t o t he cl ient . These por t s wil l be used t o est abl ish t wo new socket
connect ions-one f or r eading and one f or wr it ing-which wil l be used by t he ser ver and
t his par t icul ar cl ient . This l eaves t he main socket f r ee t o est abl ish connect ions wit h
ot her cl ient s. Lines 44-54 handl e t he t ask of obt aining t he por t s and sending t hem t o
t he cl ient ; l ines 55-77 t hen est abl ish connect ions t o t he cl ient using t he socket s. (Not e
t hat l ine 53 al so sends t he pr ocess ID of t he chat ser ver t o t he cl ient . This enabl es t he
cl ient t o kil l of f t he ser ver if somet hing hor r ibl e happens.)
The chat ser ver communicat es wit h a cl ient by spawning a chil d pr ocess t hat handl es
t he t ask of r eceiving a message f r om t hat cl ient and sending it t o t he ot her cl ient s. One
chil d pr ocess is def ined f or each cl ient . The cal l t o fork in l ine 85 cr eat es a chil d
pr ocess.
When a chil d pr ocess is cr eat ed, it knows t he names of t he f il e var iabl es cor r esponding
t o t he socket s def ined f or each of t he exist ing cl ient s. However , if a new cl ient appear s,
t he exist ing chil d pr ocesses cannot send messages t o t he new cl ient because t hey cannot
access it s socket s (because t hey ar e cr eat ed af t er t he chil dr en wer e spawned). To ensur e
t hat t he exist ing cl ient s can send messages t o t he new cl ient s, t he ser ver pr ogr am does
t he f ol l owing:
1. It kil l s al l t he chil d pr ocesses t hat communicat e wit h cl ient s. Lines 81-83
accompl ish t his t ask by cal l ing kill.
2. The ser ver cr eat es a new chil d pr ocess f or each cl ient . Lines 84-93 per f or m t his
t ask.
At t his point , each cl ient can t al k t o ever y ot her cl ient because al l of t he socket
connect ions ar e known by each chil d. (Recal l t hat when a pr ogr am spl it s int o par ent
and chil d pr ocesses, each pr ocess has a copy of al l t he var iabl es t hat have been def ined
t o t his point .)
The chat ser ver uses t he gl obal var iabl e $maxclient t o keep t r ack of how many cl ient s
ar e on t he machine. This ensur es t hat t he cor r ect number of chil d pr ocesses ar e cr eat ed.
Each chil d pr ocess cr eat ed by fork cal l s t he subr out ine talk_to_client, which r eads
messages f r om t he cl ient and t hen sends t hem t o al l t he ot her cl ient s via t he "send"
socket connect ions. Line 106 r eads a message f r om t he cl ient . Line 107 checks whet her
t he message is in f act quit; if it is, t he subr out ine (and t he pr ocess) t er minat es. Lines 108-
111 t hen pr int t he message if t he -m opt ion is specif ied. Final l y, l ines 113-118 send t he
message t o t he ot her cl ient s.
NOTE
The chat ser ver does not make any at t empt t o cl ean up
af t er it sel f or t o r euse socket s cl osed by cl ient s. This
means t hat t his par t icul ar pr ogr am can't be used by t oo
many cl ient s at a t ime, or by t oo many dif f er ent cl ient s.
If you ar e l ooking f or a chal l enging exer cise, t r y
modif ying t his pr ogr am t o cl ose socket s when cl ient s ar e
f inished wit h t hem. (This is a chal l enging exer cise
because t he chil d pr ocess somehow has t o t el l t he main
ser ver t hat t he socket can be cl osed. You can do it , but
it 's not easy!)
Now t hat you've seen how t he chat ser ver wor ks, List ing R3.2 shows t he chat cl ient
pr ogr am. User s r un t his pr ogr am t o est abl ish a connect ion wit h t he chat ser ver and t o
chat wit h ot her user s.

List ing R3.2. The chat cl ient pr ogr am.
1: #!/usr/local/bin/perl
2:
3: # obtain the server port from the command line;
4: # use 2000 as the default
5: if ($#ARGV == -1) {
6: $servport = 2000;
7: } else {
8: $servport = $ARGV[0];
9: }
10:
11: # obtain the server machine name from the command line;
12: # use "silver" as the default
13: if ($#ARGV < 1) {
14: $servname = "silver";
15: } else {
16: $servname = $ARGV[1];
17: }
18: # establish socket connection with server to obtain
19: # ports for this client
20: if (getservbyport($servport, "tcp")) {
21: die ("can't access port $servport\n");
22: }
23: ($d1, $d2, $prototype) = getprotobyname ("tcp");
24: $hostname = 'hostname';
25: chop ($hostname);
26: ($d1, $d2, $d3, $d4, $clientraddr) = gethostbyname ($hostname);
27: ($d1, $d2, $d3, $d4, $serverraddr) = gethostbyname ($servname);
28: $clientaddr = pack ("Sna4x8", 2, 0, $clientraddr);
29: $serveraddr = pack ("Sna4x8", 2, $servport, $serverraddr);
30: socket (SOCKET, 2, 1, $prototype) ||
31: die ("No server socket\n");
32: bind (SOCKET, $clientaddr) ||
33: die ("Can't bind server socket\n");
34: connect (SOCKET, $serveraddr) ||
35: die ("Can't connect to server\n");
36: $sendport = <SOCKET>;
37: $recvport = <SOCKET>;
38: $serverid = <SOCKET>;
39: close (SOCKET);
40: chop ($sendport);
41: chop ($recvport);
42:
43: # use returned ports to create sockets for this client:
44: # first socket is send, the second is receive
45: $conncaddr = pack ("Sna4x8", 2, 0, $clientraddr);
46: $connsaddr = pack ("Sna4x8", 2, $sendport, $serverraddr);
47: socket (SSOCKET, 2, 1, $prototype) ||
48: &nuke ("No send socket");
49: bind (SSOCKET, $conncaddr) ||
50: &nuke ("Can't bind send socket");
51: connect (SSOCKET, $connsaddr) ||
52: &nuke ("Can't connect to send socket");
53: $connraddr = pack ("Sna4x8", 2, $recvport, $serverraddr);
54: socket (RSOCKET, 2, 1, $prototype) ||
55: &nuke ("No receive socket");
56: bind (RSOCKET, $conncaddr) ||
57: &nuke ("Can't bind receive socket");
58: connect (RSOCKET, $connraddr) ||
59: &nuke ("Can't connect to receive socket");
60: select (SSOCKET);
61: $| = 1;
62: select (STDOUT);
63: $| = 1;
64:
65: # now, we're ready to go: prompt for user name
66: select (STDOUT);
67: print ("Welcome to chat! Who are you? ");
68: $username = <STDIN>;
69: chop ($username);
70: print ("Type 'quit' to exit chat.\n");
71: $child = fork();
72: if ($child == 0) {
73: # child: receive messages
74: &receive_msgs();
75: exit(0);
76: }
77: # parent: send messages
78: while (1) {
79: # prompt for message
80: select (STDOUT);
81: $msg = <STDIN>;
82: chop ($msg);
83: # send message to server
84: select (SSOCKET);
85: if ($msg eq "quit") {
86: print ($msg);
87: last;
88: }
89: if ($msg !~ /^\s*$/) {
90: print ($username . ": " . $msg . "\n");
91: }
92: }
93: kill (9, $child);
94: close (RSOCKET);
95: close (SSOCKET);
96:
97: sub receive_msgs {
98: local ($msg);
99:
100: while (1) {
101: $msg = <RSOCKET>;
102: select (STDOUT);
103: print ("$msg");
104: }
105: }
106:
107: sub nuke {
108: local ($errmsg) = @_;
109:
110: kill (-9, $serverid);
111: die ("$errmsg\n");
112: }
This pr ogr am st ar t s of f by obt aining t he por t number of t he main socket
connect ion empl oyed by t he chat ser ver . This por t number can be suppl ied on t he
command l ine; if it is not , t he chat pr ogr am uses 2000 as t he por t number .
The chat pr ogr am t hen obt ains t he name of t he machine on which t he chat ser ver is
r unning. This name al so can be suppl ied on t he command l ine; if it isn't , t he chat pr ogr am
assumes t he machine is a l ocal machine named silver.
Lines 23-41 est abl ish a connect ion t o t he main ser ver socket and r eceive t he por t
number s f or t he socket s t o be used by t his par t icul ar cl ient -ser ver connect ion. The
cl ient al so r eceives t he pr ocess ID of t he ser ver .
Once t he por t number s have been r eceived, t he chat pr ogr am can connect t o t he chat
ser ver by est abl ishing t wo socket connect ions wit h t he ser ver : one t o send messages and
anot her t o r eceive t hem. Lines 43-63 accompl ish t his t ask.
When t hese socket connect ions have been est abl ished, t he chat pr ogr am is r eady t o send
messages. Lines 67-68 ask f or a name by which you can ident if y your sel f t o t he ot her
user s on t he syst em. Once t his name has been r ead in, t he chat pr ogr am spl it s it sel f in
t wo by cal l ing fork. The par ent pr ocess handl es t he sending of messages, and t he chil d
handl es messages r eceived by ot her cl ient s. This ensur es t hat sending and r eceiving can
t ake pl ace at t he same t ime.
Lines 77-95 send messages t o t he chat ser ver . Line 81 pr ompt s f or a l ine of input . If t he
l ine of input is t he message quit, t he cl ient pr ogr am kil l s of f it s chil d, cl oses it s socket
connect ion, and exit s. Ot her wise, t he message-al ong wit h t he name of t he user sending
it -is t r ansmit t ed t o t he chat ser ver via t he "wr it e" socket . The ser ver t hen sends it t o
al l of t he cl ient s on t he syst em.
The chil d pr ocess cal l s t he subr out ine receive_msgs, which handl es t he t ask of
r eceiving messages f r om t he ot her cl ient s. Messages ar e r eceived via t he "r ead" socket
and ar e pr int ed as t hey ar e r eceived.
If somet hing goes r adical l y wr ong, t he chat pr ogr am cal l s t he subr out ine nuke, which
kil l s bot h it sel f and t he ser ver pr ogr am.

Appendix A
Answers
CONTENTS
G Answer s f or Day 1, "Get t ing St ar t ed"
H Quiz
H Exer cises
G Answer s f or Day 2, "Basic Oper at or s and Cont r ol Fl ow"
H Quiz
H Exer cises
G Answer s f or Day 3, "Under st anding Scal ar Val ues"
H Quiz
H Exer cises
G Answer s f or Day 4, "Mor e Oper at or s"
H Quiz
H Exer cises
G Answer s f or Day 5, "List s and Ar r ay Var iabl es"
H Quiz
H Exer cises
G Answer s f or Day 6, "Reading f r om and Wr it ing t o Fil es"
H Quiz
H Exer cises
G Answer s f or Day 7, "Pat t er n Mat ching"
H Quiz
H Exer cises
G Answer s f or Day 8, "Mor e Cont r ol St r uct ur es"
H Quiz
H Exer cises
G Answer s f or Day 9, "Using Subr out ines"
H Quiz
H Exer cises
G Answer s f or Day 10, "Associat ive Ar r ays"
H Quiz
H Exer cises
G Answer s f or Day 11, "For mat t ing Your Out put "
H Quiz
H Exer cises
G Answer s f or Day 12, "Wor king wit h t he Fil e Syst em"
H Quiz
H Exer cises
G Answer s f or Day 13, "Pr ocess, St r ing, and Mat hemat ical Funct ions"
H Quiz
H Exer cises
G Answer s f or Day 14, "Scal ar -Conver sion and List -Manipul at ion Funct ions"
H Quiz
H Exer cises
G Answer s f or Day 15, "Syst em Funct ions"
H Quiz
H Exer cises
G Answer s f or Day 16, "Command-Line Opt ions"
H Quiz
H Exer cises
G Answer s f or Day 17, "Syst em Var iabl es"
H Quiz
H Exer cises
G Answer s f or Day 18, "Ref er ences in
Per l 5"
H Quiz
H Exer cises
G Answer s f or Day 19, "Object -Or ient ed Pr ogr amming in Per l "
H Quiz
H Exer cises
G Answer s f or Day 20, "Miscel l aneous Feat ur es of Per l "
H Quiz
H Exer cises
G Answer s f or Day 21, "The Per l Debugger "
H Quiz
Answers for Day 1, "Getting Started"
Quiz
1. Per l has t he power of a high-l evel pr ogr amming l anguage such as C, and t he ease
of use of simpl e l anguages such as shel l scr ipt s.
2. The Per l int er pr et er execut es your Per l pr ogr am (st ar t ing f r om t he beginning,
and cont inuing one st at ement at a t ime).
3. The answer s ar e as f ol l ows:
1. A st at ement is one par t icul ar t ask or inst r uct ion (usual l y cor r esponding t o
a l ine of code). A st at ement is t er minat ed by a semicol on (;).
2. A t oken is t he smal l est unit of inf or mat ion under st ood by t he Per l
int er pr et er . A st at ement consist s of sever al t okens.
3. An ar gument is an it em passed t o a l ibr ar y f unct ion (such as $inputline t o
print).
4. Er r or r ecover y occur s when t he Per l int er pr et er det ect s an er r or in your
pr ogr am. The int er pr et er t r ies t o deduce what you meant t o wr it e and
at t empt s t o cont inue det ect ing er r or s in t he pr ogr am.
5. The st andar d input f il e is t he f il e t hat st or es t he char act er s you ent er at
t he keyboar d.
4. A comment is any t ext t hat is pr eceded by a #. A comment can appear anywher e in
your pr ogr am. Ever yt hing af t er t he # char act er is assumed t o be par t of t he
comment .
5. Per l usual l y is l ocat ed in t he f il e /usr/local/bin/perl.
6. The header comment is t he special comment t hat t el l s t he syst em t hat t his is a
Per l pr ogr am. It appear s as t he f ir st l ine of ever y Per l pr ogr am.
7. A l ibr ar y f unct ion is def ined as par t of t he Per l int er pr et er and per f or ms a specif ic
t ask.
Exercises
1. The f ol l owing is one possibl e sol ut ion:
#!/usr/local/bin/perl
$inputline = <STDIN>;
print ($inputline, $inputline);
2. The f ol l owing is one possibl e sol ut ion:
#!/usr/local/bin/perl
$inputline = <STDIN>;
print ($inputline);
$inputline = <STDIN>;
print ($inputline);
3. The f ol l owing is one possibl e sol ut ion:
#!/usr/local/bin/perl
$inputline = <STDIN>;
$inputline = <STDIN>; # this throws away the previous input line
print( $inputline );
4. The t hir d l ine of t he pr ogr am is missing a semicol on at t he end of t he st at ement :
#!/usr/local/bin/perl
$inputline = <STDIN>;
print ($inputline);
5. The print($inputline) l ine is ignor ed because t he ent ir e t hir d l ine is being
t r eat ed as a comment . You want t he f ol l owing inst ead:
#!/usr/local/bin/perl
$inputline = <STDIN>;
print($inputline); # print my line!
6. This pr ogr am r eads t wo l ines of input and pr int s t hem in r ever se or der (second l ine
f ir st ).
Answers for Day 2, "Basic Operators and Control Flow"
Quiz
1. The answer s ar e as f ol l ows:
1. An expr ession is a col l ect ion of oper at or s and t he val ues on which t hey
oper at e.
2. An oper and is a val ue associat ed wit h an oper at or .
3. A condit ional st at ement is a st at ement t hat is execut ed onl y when it s
condit ional expr ession is t r ue.
4. A st at ement bl ock is a col l ect ion of st at ement s cont ained inside t he br aces
of a condit ional st at ement . The st at ement bl ock is execut ed onl y when t he
condit ional expr ession associat ed wit h it s condit ional st at ement is t r ue.
5. An inf init e l oop is a condit ional st at ement whose condit ional expr ession is
al ways t r ue.
2. A while st at ement st ops l ooping when it s condit ional expr ession is f al se.
3. An until st at ement st ops l ooping when it s condit ional expr ession is t r ue.
4. The == oper at or compar es it s t wo oper ands. If t hey ar e numer ical l y equal , t he ==
oper at or yiel ds a r esul t of t r ue; ot her wise, it yiel ds f al se.
5. 27.
6. The l egal ones ar e a, c, and f .
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
print ("Enter a number to be multiplied by 2:\n");
$number = <STDIN>;
chop ($number);
$number = $number * 2;
print ("The result is ", $number, "\n");
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
print ("Enter the dividend (number to divide):\n");
$dividend = <STDIN>;
chop ($dividend);
print ("Enter the divisor (number to divide by):\n");
$divisor = <STDIN>;
chop ($divisor);
if ($divisor == 0) {
print ("Error: can't divide by zero!\n");
} elsif ($dividend == 0) {
$result = $dividend;
} elsif ($divisor == 1) {
$result = $dividend;
} else {
$result = $divisor / $dividend;
}
if ($divisor == 0) {
# skip the print, since we detected an error
} else {
print ("The result is ", $result, "\n");
}
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$count = 1;
$done = 0;
while ($done == 0) {
print ($count, "\n");
if ($count == 10) {
$done = 1;
}
$count = $count + 1;
}
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$count = 10;
until ($count == 0) {
print ($count, "\n");
$count = $count - 1;
}
5. Ther e ar e, in f act , t hr ee separ at e bugs in t his pr ogr am:
1. You must cal l chop t o get r id of t he t r ail ing newl ine char act er in $value
bef or e compar ing it t o 17.
2. The condit ional expr ession shoul d r ead $value == 17, not $value = 17.
3. Ther e shoul d be a cl osing br ace } bef or e t he else.
6. This pr ogr am cont ains an inf init e l oop. To f ix it , add t he f ol l owing st at ement just
bef or e t he cl osing br ace }:
$input = $input + 1;
Al so, t he st at ement
$input = $terminate + 5;
shoul d r ead
$terminate = $input + 5;
Answers for Day 3, "Understanding Scalar Values"
Quiz
1. The answer s ar e as f ol l ows:
1. A r ound-of f er r or is t he dif f er ence bet ween t he f l oat ing-point number t hat
appear s in a pr ogr am and t he number as it is r epr esent ed in t he machine.
2. Oct al not at ion is anot her way of r ef er r ing t o base-8 not at ion: Each digit
can be a number f r om 0 t o 7 and is mul t ipl ied by 8 t o t he exponent n, wher e n
is t he number of digit s t o skip.
3. The pr ecision of a f l oat ing-point r epr esent at ion on a machine is t he number
of signif icant digit s it can hol d.
4. Scient if ic not at ion is a way of wr it ing f l oat ing-point number s. It consist s of
one digit bef or e t he decimal point , as many digit s as r equir ed af t er t he
decimal point , and an exponent .
2. The answer s ar e as f ol l ows:
1. 255 (t he ASCII end-of -f il e char act er )
2. 6
3. 601
3. The answer s ar e as f ol l ows:
1. 255
2. 17
3. 48813
4. This l ine pr int s I am bored, and t hen backspaces over bored and r epl aces it wit h
happy!. (I don't know a l ot of pr act ical uses f or t he \b escape char act er , but it 's
f un t o wat ch.)
5. The answer s ar e as f ol l ows:
1. This string contains 21.
2. \21 is my favorite number.
3. Assign \$num to this string.
6. The answer s ar e as f ol l ows:
1. 4.371e01
2. 6.0e-08 (t he .0 is opt ional )
3. 3.0e+00 (act ual l y, 3 by it sel f is accept abl e)
4. -1.04e+00
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$count = 1;
$number = 0.1;
until ($count == 10) {
print ("$number\n");
$number = $number + 0.1;
$count = $count + 1;
}
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$inputline = <STDIN>;
chop ($inputline);
if ($inputline == 0) {
print ("0\n");
} else {
print ("1\n");
}
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
print ("Enter a number:\n");
$number = <STDIN>;
chop ($number);
until ($number == 47) {
print ("Wrong! Try again!\n");
$number = <STDIN>;
chop ($number);
}
print ("\aCorrect!\n");
4. The f ir st st r ing in t he print st at ement is not t er minat ed pr oper l y, because t her e is
a backsl ash \ bef or e t he f inal '. To f ix t his, add anot her quot e:
print ('here is the value of \$inputline\'', ": $inputline");
5. This code f r agment does not pr oduce t he expect ed r esul t because of a r ound-of f
er r or . Tr y subt r act ing $num3 f r om $num1 bef or e adding $num2 and $num4.
6. "0xce" conver t s t o 0, not t o t he hexadecimal const ant 0xce. To f ix t his, l eave of f
t he quot es.
Answers for Day 4, "More Operators"
Quiz
1. The answer s ar e as f ol l ows:
1. An oper at or is a char act er or st r ing of char act er s t hat r epr esent s a
par t icul ar Per l oper at ion.
2. An oper and is a val ue used by an oper at or . In Per l , oper at or s r equir e one,
t wo, or t hr ee oper ands.
3. An expr ession is a col l ect ion of oper at or s and oper ands, yiel ding a f inal
r esul t .
4. Oper at or pr ecedence is t he or der in which dif f er ent t ypes of oper at ions ar e
per f or med.
5. Oper at or associat ivit y is t he or der in which oper at ions of t he same
pr ecedence ar e per f or med.
2. The answer s ar e as f ol l ows:
1. l ogical AND
2. bit wise AND
3. bit wise XOR
4. st r ing inequal it y
5. st r ing concat enat ion
3. The answer s ar e as f ol l ows:
1. eq
2. %
3. x
4. |
5. >=
4. The answer s ar e as f ol l ows:
1. 0000000010101011
2. 0000010001010001
3. 0 (or 00000000)
5. The answer s ar e as f ol l ows:
1. 100
2. 15
3. 65
6. The answer s ar e as f ol l ows:
1. 4
2. 0 (I hope you didn't cal cul at e al l of t he expr ession! Once you see t he f ir st 0,
you shoul d know t hat t he r esul t is 0.)
3. 1819
4. "abcdede"
Exercises
1. The f ol l owing is just one of many possibl e answer s:
#!/usr/local/bin/perl
$value = 1;
$counter = 0;
while ($counter < 16) {
print ("2 to the power $counter is $value\n");
$value = $value << 1;
$counter++;
}
2. The answer is as f ol l ows:
$result = $var1 == 5 || $var2 == 7 ?
$var1 * $var2 + 16.5 :
(print("condition is false\n"), 0);
3. The answer is as f ol l ows:
if ($var1 <= 26) {
$result = ++$var2;
} else {
$result = 0;
}
4. The f ol l owing is just one of many possibl e answer s:
#!/usr/local/bin/perl
print("Enter the integer to be divided:\n");
$dividend = <STDIN>;
print("Enter the integer to divide by:\n");
$divisor = <STDIN>;
# check for division by zero
if ($divisor == 0) {
print("error: can't divide by zero\n");
} else {
$quotient = $dividend / $divisor;
$remainder = $dividend % $divisor;
print("The result is $quotient\n");
print("The remainder is $remainder\n");
}
5. Adding 100005.2 and t hen subt r act ing it causes r ound-of f er r or s, which means
t hat t he f inal val ue isn't exact l y t he same as 5.1.
6. ($result = ((($var1 * 2) << (5 + 3)) || ($var2 ** 3))), $var3;
7. 81
8. Her e is t he cor r ect ed pr ogr am, wit h t he f ixed er r or s l ist ed:
#!/usr/local/bin/perl
$num = <STDIN>;
chop ($num);
$x = "";
$x .= "hello"; # += is for integers
if ($x ne "goodbye" || $x eq "farewell") {
# the previous line had two problems:
# the operators were numeric, not string;
# the or operator was bitwise, not logical.
$result = $num == 0 ? 43 : 0;
# the : and third operand were missing in the previous
# line; eq replaced by ==
} else {
$result = ++$num; # can't have ++ on both sides
}
print("the result is $result\n");
Answers for Day 5, "Lists and Array Variables"
Quiz
1. The answer s ar e as f ol l ows:
1. A l ist is an or der ed col l ect ion of scal ar val ues.
2. An empt y l ist is a l ist wit h zer o el ement s in it .
3. An ar r ay var iabl e is a var iabl e t hat can st or e a l ist .
4. A subscr ipt is a scal ar val ue t hat r ef er s t o an el ement of a l ist . The
subscr ipt 0 r ef er s t o t he f ir st el ement , t he subscr ipt 1 r ef er s t o t he second,
and so on.
5. An ar r ay sl ice is a l ist consist ing of some el ement s of an ar r ay var iabl e.
(Not ice t hat t he el ement s do not have t o be in or der .)
2. The answer s ar e as f ol l ows:
1. (1, 2, 3)
2. (3, 2)
3. ("hello", 2, 2)
4. (2, 3)
5. ("", 3, 2, 2)
6. The cont ent s of t he st andar d input f il e, one l ine per l ist el ement .
3. The answer s ar e as f ol l ows:
1. 2
2. 4
3. "one"
4. 2
5. "three"
6. "" (Onl y t hr ee el ement s in t he l ist ar e st or ed in @list2.)
4. A l ist is a col l ect ion of scal ar val ues. An ar r ay var iabl e is a pl ace wher e you can
st or e a l ist .
5. The br acket s [] encl osing t he subscr ipt dist inguish an ar r ay el ement f r om a scal ar
var iabl e.
6. You can do t his in many ways. The t wo easiest ar e
H Use singl e-quot ed st r ings, which do not al l ow subst it ut ions.
H Put a backsl ash \ bef or e t he char act er t hat you want l ef t as is.
7. You can obt ain t he l engt h of a l ist st or ed in an ar r ay var iabl e by assigning t he
ar r ay var iabl e t o a scal ar var iabl e.
8. Al l undef ined ar r ay el ement s ar e assumed t o cont ain t he nul l st r ing "".
9. When you assign t o an ar r ay el ement t hat is l ar ger t han t he cur r ent l engt h of
t he ar r ay, t he ar r ay gr ows t o incl ude t he new el ement .
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$thecount = 0;
$line = <STDIN>;
while ($line ne "") {
chop ($line);
@words = split(/ /, $line);
$wordindex = 1;
while ($wordindex <= @words) {
if ($words[$wordindex-1] eq "the") {
$thecount += 1;
}
$wordindex++;
}
$line = <STDIN>;
}
print ("Total occurrences of \"the\": $thecount\n");
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$grandtotal = 0;
$line = <STDIN>;
while ($line ne "") {
$linetotal = 0;
@numbers = split(/ /, $line);
$numbercount = 1;
while ($numbercount <= @numbers) {
$linetotal += $numbers[$numbercount-1];
$numbercount++;
}
print("line total: $linetotal\n");
$grandtotal += $linetotal;
$line = <STDIN>;
}
print("grand total: $grandtotal\n");
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
@lines = <STDIN>;
chop (@lines);
$longlongline = join(" ", @lines);
@words = split(/ /, $longlongline);
@words = reverse sort (@words);
$index = 0;
print("Words sorted in reverse order:\n");
while ($index < @words) {
# note that the first time through, the following
# comparison references $words[-1]. This is all
# right, as $words[-1] is replaced by the null
# string, and we want the first word to be printed
if ($words[$index] ne $words[$index-1]) {
print ("$words[$index]\n");
}
$index++;
}
4. The ar r ay el ement r ef er ence shoul d be $array[4], not @array[4].
5. Ther e ar e f our separ at e bugs in t his pr ogr am:
1. You must cal l chop t o r emove t he newl ine char act er s f r om t he input l ines
st or ed in @input. Ot her wise, t hey make your out put unr eadabl e.
2. Simil ar l y, you have t o append a newl ine when cal l ing join:
$input[$currline] = join(" ", @words, "\n");
3. The condit ional expr ession shoul d r ead
$currline <= @input
inst ead of
$currline < @input
t o make sur e t hat t he l ast l ine of t he input f il e is r ead.
4. Your subscr ipt s shoul d r ead [$currline-1], not [$currline]. (This bug wil l
keep coming up in your pr ogr ams because it 's easy t o f or get t hat subscr ipt s
st ar t wit h zer o.)
Answers for Day 6, "Reading from and Writing to Files"
Quiz
1. The answer s ar e as f ol l ows:
1. A f il e var iabl e is a name t hat r epr esent s an open f il e.
2. A r eser ved wor d is a wor d t hat can't be used as a var iabl e name because it
has a special meaning in Per l (such as if).
3. The f il e mode specif ies how you want t o access a f il e when you open it (r ead,
wr it e, or append).
4. Append mode indicat es t hat you want t o open t he f il e f or wr it ing and
append anyt hing you wr it e t o t he exist ing cont ent s of t he f il e.
5. A pipe is a connect ion bet ween out put f r om one pr ogr am and input t o
anot her .
2. The <> oper at or r eads it s dat a f r om t he f il es specif ied on t he command l ine.
3. The answer s ar e as f ol l ows:
1. -r t est s whet her you have per mission t o r ead a f il e.
2. -x t est s whet her you have per mission t o execut e a f il e (and whet her t he f il e
is execut abl e).
3. -s indicat es t he size of a f il e in byt es.
4. @ARGV cont ains t he f ol l owing l ist :
("file1", "file2", "file3")
5. The answer s ar e as f ol l ows:
1. To open a f il e in wr it e mode, put a > char act er in f r ont of t he f il ename.
2. To open a f il e in append mode, put t wo > char act er s (>>) in f r ont of t he
f il ename.
3. To open a f il e in r ead mode, just specif y t he f il ename. By def aul t , f il es ar e
opened in r ead mode.
4. To open a pipe, put a | char act er in f r ont of t he command t o be piped t o.
6. The <> oper at or r eads dat a f r om t he f il es whose names ar e st or ed in t he ar r ay
var iabl e @ARGV. When t he <> oper at or r uns out of dat a in one f il e, it opens t he f il e
named in $ARGV[0] and t hen cal l s shift t o move t he el ement s of @ARGV over .
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$total = 0;
$count = 1;
while ($count <= @ARGV) {
$total += $ARGV[$count-1];
$count++;
}
print ("The total is $total.\n");
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$count = 1;
while ($count <= @ARGV) {
if (-e $ARGV[$count-1] && -s $ARGV[$count-1] > 10000) {
print ("File $ARGV[$count-1] is a big file!\n");
}
$count++;
}
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
open (INFILE, "file1") ||
die ("Can't open file1 for reading\n");
open (OUTFILE, ">file2") ||
die ("Can't open file2 for writing\n");
# the following only works if file1 isn't too big
@contents = <INFILE>;
print OUTFILE (@contents);
# we don't really need the call to close, but they
# make things a little clearer
close (OUTFILE);
open (OUTFILE, ">>file2") ||
die ("Can't append to file2\n");
print OUTFILE (@contents);
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$wordcount = 0;
while ($line = <>) {
# this isn't the best possible pattern to split with,
# but it'll do until you've finished Day 7
@words = split(/ /, $line);
$wordcount += @words;
}
open (MESSAGE, "| mail dave") ||
die ("Can't mail to userid dave.\n");
print MESSAGE ("Total number of words: $wordcount\n");
close (MESSAGE);
5. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$count = 1;
while ($count <= @ARGV) {
print ("File $ARGV[$count-1]:");
if (!(-e $ARGV[$count-1])) {
print (" does not exist\n");
} else {
if (-r $ARGV[$count-1]) {
print (" read");
}
if (-w $ARGV[$count-1]) {
print (" write");
}
if (-x $ARGV[$count-1]) {
print (" execute");
}
print ("\n");
}
$count++;
}
6. This pr ogr am is opening outfile in r ead mode, not wr it e mode. To open in wr it e
mode, change t he cal l t o open t o
open (OUTFILE, ">outfile");
Answers for Day 7, "Pattern Matching"
Quiz
1. The answer s ar e as f ol l ows:
1. Eit her t he l et t er a or b, f ol l owed by zer o or mor e occur r ences of c.
2. One, t wo, or t hr ee digit s.
3. The wor ds cat, cot, and cut. (This pat t er n does not mat ch t hese l et t er s if
t hey ar e in t he middl e of a wor d.)
4. The f ir st par t of t his pat t er n mat ches a subpat t er n consist ing of x, one or
mor e of y, and z. The r est of t he pat t er n t hen mat ches a per iod, f ol l owed by
t he subpat t er n f ir st mat ched.
5. This mat ches an empt y l ine (t he nul l st r ing).
2. The answer s ar e as f ol l ows:
1. /[a-z]{5,}/
2. /1|one/
3. /\d+\.?\d+/
4. /([A-Za-z])[aeiou]\1/
5. /\++/
3. It ems a, b, c, and f ar e t r ue; d and e ar e f al se.
4. The answer s ar e as f ol l ows:
1. "def123abc"
2. "X123X"
3. "aWc123abc"
4. "abd"
5. "abc246abc"
5. The answer s ar e as f ol l ows:
1. "ABC123ABC"
2. "abc456abc"
3. "abc456abc"
4. "abc abc"
5. "123"
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
while ($line = <STDIN>) {
$line =~ tr/aeiou/AEIOU/;
print ($line);
}
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
while ($inputline = <STDIN>) {
$inputline =~ tr/0-9/ /c;
$inputline =~ s/ +//g;
@digits = split(//, $inputline);
$total += @digits;
$count = 1;
while ($count <= @digits) {
$dtotal[$digits[$count-1]] += 1;
$count++;
}
}
print ("Total number of digits found: $total\n");
print ("Breakdown:\n");
$count = 0;
while ($count <= 9) {
if ($dtotal[$count] > 0) {
print ("\tdigit $count: $dtotal[$count]\n");
}
$count++;
}
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
while ($line = <STDIN>) {
$line =~ s/(\w+)(\s+)(\w+)(\s+)(\w+)/$5$2$3$4$1/;
print ($line);
}
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
while ($line = <STDIN>) {
$line =~ s/\d+/$&+1/eg;
print ($line);
}
5. Ther e ar e t wo pr obl ems. The f ir st is t hat t he pat t er n mat ches t he ent ir e l ine,
incl uding t he cl osing newl ine. You do not want t o put a quot at ion mar k af t er
t he cl osing newl ine of each l ine. In t his case, it causes t he pr ogr am t o omit t he s
oper at or , which specif ies subst it ut ion.
The second pr obl em is t hat t he r epl acement st r ing shoul d cont ain $1, not \1. \1 is
def ined onl y inside t he sear ch pat t er n.
6. The pat t er n uses t he * special char act er , which mat ches zer o or mor e occur r ences
of any digit . This means t he pat t er n al ways mat ches.
The pat t er n shoul d use t he + special char act er , which mat ches one or mor e
occur r ences of any digit .
Answers for Day 8, "More Control Structures"
Quiz
1. 7
2. 11
3. 5
4. 6
5. last if ($x eq "done");
6. redo if ($list[0] == 26);
7. next LABEL if ($scalar eq "#");
8. print ("$count\n") while ($count++ < 10);
9. The continue st at ement def ines a bl ock of code t o be execut ed each t ime a while
or until st at ement l oops.
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$count = 1;
do {
print ("$count\n");
$count++;
} while ($count <= 10);
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
for ($count = 1; $count <= 10; $count++) {
print ("$count\n");
}
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
for ($count = 1; $count <= 5; $count++) {
$line = <STDIN>;
last if ($line eq "");
print ($line);
}
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
for ($count = 1; $count <= 20; $count++) {
next if ($count % 2 == 1);
print ("$count\n");
}
5. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$linenum = 0;
while ($line = <STDIN>) {
$linenum += 1;
$occurs = 0;
$line =~ tr/A-Z/a-z/;
@words = split(/\s+/, $line);
foreach $word (@words) {
$occurs += 1 if ($word eq "the");
}
if ($occurs > 0) {
print ("line $linenum: $occurs occurrences\n");
}
}
6. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$count = 10;
while ($count >= 1) {
print ("$count\n");
}
continue {
$count-;
}
7. You can't use t he last st at ement inside a do st at ement . To get ar ound t his
pr obl em, use anot her l oop const r uct such as while or for, or put t he condit ional
expr ession in t he while st at ement at t he bot t om.
Answers for Day 9, "Using Subroutines"
Quiz
1. The answer s ar e as f ol l ows:
1. A subr out ine is a separ at e body of code designed t o per f or m a par t icul ar
t ask.
2. An invocat ion is a st at ement t hat t el l s t he Per l int er pr et er t o execut e a
par t icul ar subr out ine.
3. An ar gument is a val ue t hat is passed t o a subr out ine when it is invoked.
4. A singl e-exit modul e is a subr out ine whose r et ur n val ue is cal cul at ed by
t he f inal st at ement in t he subr out ine.
5. Al iasing occur s when one name is def ined t o be equival ent t o anot her .
2. The answer s ar e as f ol l ows:
1. 0
2. (4, 5, 6)
3. (4, 5, 6)
3. Fal se (or zer o), because t he condit ional expr ession $count <= 10 is t he l ast
expr ession eval uat ed in t he subr out ine.
4. (1, 5, 3)
Exercises
1. Her e is one possibl e sol ut ion:
sub add_two {
local ($arg1, $arg2) = @_;
$result = $arg1 + $arg2;
}
2. Her e is one possibl e sol ut ion:
sub count_t {
local ($string) = @_;
# There are a couple of tricks you can use to do this.
# This one splits the string into words using "t" as
# the split pattern. The number of occurrences of "t"
# is one less than the number of words resulting from
# the split.
@dummy = split(/t/, $string);
$retval = @dummy - 1;
}
3. Her e is one possibl e sol ut ion:
sub diff {
local ($file1, $file2) = @_;
# return false if we can't open a file
return (0) unless open (FILE1, "$file1");
return (0) unless open (FILE2, "$file2");
while (1) {
$line1 = <FILE1>;
$line2 = <FILE2>;
if ($line1 eq "") {
$retval = ($line2 eq "");
last;
}
if ($line2 eq "" || $line1 ne $line2) {
$retval = 0;
last;
}
}
# you should use close here, as this subroutine may
# be called many times
close (FILE1);
close (FILE2);
# ensure that the return value is the last evaluated
# expression
$retval;
}
4. Her e is one possibl e sol ut ion:
sub dieroll {
$retval = int (rand(6)) + 1;
}
5. Her e is one possibl e sol ut ion:
# assume that the first call to printlist passes the argument
# 0 as the value for $index
sub printlist {
local ($index, @list) = @_;
if ($index + 1 < @list) {
&printlist ($index+1, @list);
}
# the conditional handles the case of an empty list
print ("$list[$index]\n") if (@list > 0);
}
6. The subr out ine print_ten over wr it es t he val ue st or ed in t he gl obal var iabl e
$count. To f ix t his pr obl em, def ine $count as a l ocal var iabl e. (You al so shoul d
def ine $printval as a l ocal var iabl e, in case someone adds t his var iabl e t o t he
main pr ogr am at a l at er t ime.)
7. The local st at ement in t he subr out ine assigns bot h t he l ist and t he sear ch wor d
t o @searchlist, which means t hat $searchword is assigned t he empt y st r ing. To f ix
t his pr obl em, swit ch t he or der of t he ar gument s, put t ing t he sear ch wor d f ir st .
8. If split pr oduces a nonempt y l ist , t he l ast expr ession eval uat ed in t he subr out ine
is t he condit ional expr ession, which has t he val ue 0 (f al se):
@words == 0
Ther ef or e, t he r et ur n val ue of t his subr out ine is 0, not t he l ist of wor ds.
To get ar ound t his pr obl em, put t he f ol l owing st at ement af t er t he if st at ement :
@words;
This ensur es t hat t he l ist of wor ds is al ways t he r et ur n val ue.
Answers for Day 10, "Associative Arrays"
Quiz
1. The answer s ar e as f ol l ows:
1. An associat ive ar r ay is an ar r ay whose subscr ipt s can be any scal ar val ue.
2. A point er is an associat ive ar r ay el ement whose val ue is t he subscr ipt of
anot her associat ive ar r ay el ement .
3. A l inked l ist is an associat ive ar r ay in which each el ement of t he ar r ay
point s t o t he next .
4. A binar y t r ee is a dat a st r uct ur e in which each el ement point s t o (at most )
t wo ot her el ement s.
5. A node is an el ement of a binar y t r ee.
6. A chil d is an el ement of a binar y t r ee t hat is point ed t o by anot her el ement .
2. This st at ement cr eat es an associat ive ar r ay cont aining t hr ee el ement s:
H An el ement wit h subscr ipt 17.2 whose val ue is hello
H An el ement wit h subscr ipt there whose val ue is 46
H An el ement wit h subscr ipt e+6 whose val ue is 88
3. When you assign an associat ive ar r ay t o an or dinar y ar r ay var iabl e, t he val ue of
t he ar r ay var iabl e becomes a l ist consist ing of al l of t he subscr ipt /val ue pair s of
t he associat ive ar r ay (in t he or der in which t hey wer e st or ed in t he associat ive
ar r ay, which is r andom).
4. Def ine a scal ar var iabl e cont aining t he val ue of t he l ist 's f ir st el ement . Then, use
t he val ue of one associat ive ar r ay el ement as t he subscr ipt f or t he next .
5. This is a t r ick quest ion: Because t he associat ive ar r ay %list st or es it s el ement s in
r andom or der , it is not cl ear how many t imes t he foreach l oop it er at es. It coul d be
one, t wo, or t hr ee.
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
while ($line = <STDIN>) {
$line =~ s/^\s+|\s+$//g;
($subscript, $value) = split(/\s+/, $line);
$array{$subscript} = $value;
}
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$linenum = 0;
while ($line = <STDIN>) {
$linenum += 1;
$line =~ s/^\s+|\s+$//g;
@words = split(/\s+/, $line);
if ($words[0] eq "index" &&
$index{$words[1]} eq "") {
$index{$words[1]} = $linenum;
}
}
foreach $item (sort keys (%index)) {
print ("$item: $index{$item}\n");
}
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$linenum = 0;
while ($line = <STDIN>) {
$linenum += 1;
$line =~ s/^\s+|\s+$//g;
@words = split(/\s+/, $line);
# This program uses a trick: for each word, the array
# item $index{"word"} stores the number of occurrences
# of that word. Each occurrence is stored in the
# element $index{"word#n"}, where[]is a
# positive integer.
if ($words[0] eq "index") {
if ($index{$words[1]} eq "") {
$index{$words[1]} = 1;
$occurrence = 1;
} else {
$index{$words[1]} += 1;
$occurrence = $index{$words[1]};
}
$index{$words[1]."#".$occurrence} = $linenum;
}
}
# The loop that prints the index takes advantage of the fact
# that, when the list is sorted, the elements that count
# occurrences are always processed just before the
# corresponding elements that store occurrences. For example:
# $index{word}
# $index{word#1}
# $index{word#2}
foreach $item (sort keys (%index)) {
if ($item =~ /#/) {
print ("\n$item:");
} else {
print (" $index{$item}");
}
}
print ("\n");
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$student = 0;
@subjects = ("English", "history", "mathematics",
"science", "geography");
while ($line = <STDIN>) {
$line =~ s/^\s+|\s+$//g;
@words = split (/\s+/, $line);
@students[$student++] = $words[0];
for ($count = 1; $count <= 5; $count++) {
$marks{$words[0].$subjects[$count-1]} =
$words[$count];
}
}
# now print the failing grades, one student per line
foreach $student (sort (@students)) {
$has_failed = 0;
foreach $subject (sort (@subjects)) {
if ($marks{$student.$subject} < 50) {
if ($has_failed == 0) {
$has_failed = 1;
print ("$student failed:");
}
print (" $subject");
}
}
if ($has_failed == 1) {
print ("\n");
}
}
5. This pr ogr am has one pr obl em and one unwant ed f eat ur e.
The pr obl em: Adding a new el ement t o %list in t he middl e of a foreach l oop t hat
uses t he f unct ion keys yiel ds unpr edict abl e r esul t s.
The unwant ed f eat ur e: The foreach l oop doubl es t he size of t he associat ive ar r ay
because t he or iginal el ement s Fred, John, Jack, and Mary ar e not del et ed.
Answers for Day 11, "Formatting Your Output"
Quiz
1. The answer s ar e as f ol l ows:
1. @<<<<<<<<<
2. @>>>>
3. @|
4. @####.###
5. ~~ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
2. The answer s ar e as f ol l ows:
1. Five l ef t -just if ied char act er s.
2. Seven cent er ed char act er s.
3. One char act er .
4. Mul t ipl e (unf or mat t ed) l ines of t ext .
5. Ten r ight -just if ied char act er s, wit h t he l ine being pr int ed onl y if t he l ine is
not bl ank.
3. The answer s ar e as f ol l ows:
1. An int eger (base 10) in a f iel d of at l east f ive digit s.
2. A f l oat ing-point number wit h a t ot al f iel d widt h of 11 char act er s, f our of
which ar e t o t he r ight of t he decimal point .
3. A base-10 int eger in a f iel d of at l east 10 digit s. Empt y char act er s in t he
f iel d ar e f il l ed wit h zer oes.
4. A char act er st r ing of at l east 12 char act er s, l ef t -just if ied.
5. An int eger in hexadecimal (base-16) f or m.
4. Number s wit h r ounding pr obl ems ar e number s t hat nor mal l y r ound up but cannot
be exact l y st or ed on t he machine. The cl osest equival ent t hat can be st or ed
r ounds down.
5. To cr eat e a page header f or an out put f il e, def ine a pr int f or mat named
filename_TOP, wher e filename is t he f il e var iabl e associat ed wit h t he f il e. (Or ,
you can cr eat e a pr int f or mat of any name and assign t he name t o t he syst em
var iabl e $^.)
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
for ($count = 1; $count <= 9; $count += 3) {
$num1 = 2 ** $count;
$num2 = 2 ** ($count + 1);
$num3 = 2 ** ($count + 2);
write;
}
$num1 = 2 ** 10;
$num2 = $num3 = "";
write;
format STDOUT =
^>>> ^>>> ^>>>
$num1 $num2 $num3
.
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
for ($count = 1; $count <= 10; $count++) {
printf ("%4d", 2 ** $count);
if ($count % 3 == 0) {
print ("\n");
} else {
print (" ");
}
}
print ("\n");
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
@text = <STDIN>;
$line = join("", @text);
write;
format STDOUT =
******************************************
~~^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
$line
******************************************
.
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$total1 = $total2 = 0;
while (1) {
$num1 = <STDIN>;
last if ($num1 eq "");
chop ($num1);
$num2 = <STDIN>;
last if ($num2 eq "");
chop ($num2);
$~ = "LINE";
write;
$total1 += $num1;
$total2 += $num2;
}
$~ = "TOTAL";
write;
$~ = "GRAND_TOTAL";
write;
format LINE =
@####.## @####.##
$num1 $num2
.
format TOTAL =
column totals: @#####.## @#####.##
$total1 $total2
.
format GRAND_TOTAL =
grand total: @#####.##
$total1 + $total2
.
5. When print wr it es a l ine t o t he page, t he $- var iabl e is not aut omat ical l y
updat ed. This means t hat t he l ine count is of f . To f ix t his, subt r act one f r om t he $-
var iabl e your sel f .
Al so, you must specif y what is t o be pr int ed by t he STDOUT pr int f or mat :
format STDOUT =
@*
$line
.
Answers for Day 12, "Working with the File System"
Quiz
1. The answer s ar e as f ol l ows:
1. The tell f unct ion r et ur ns t he cur r ent l ocat ion in t he f il e being r ead (t he
l ocat ion of t he next l ine t o r ead).
2. The mkdir f unct ion cr eat es a dir ect or y.
3. The link f unct ion cr eat es a har d l ink (def ines a second name t hat r ef er s t o
a par t icul ar f il e).
4. The unlink f unct ion dest r oys a har d l ink (t he connect ion bet ween t he
f il ename and t he f il e). If no addit ional har d l inks have been def ined (using
link), unlink del et es t he f il e.
5. The truncate f unct ion r educes t he size of a f il e t o t he l engt h specif ied.
2. lstat assumes t hat t he name it is wor king wit h is a symbol ic l ink. stat assumes it is
wor king wit h an act ual f il e.
3. tell r et r ieves t he l ocat ion of t he next l ine t o be r ead in a f il e. telldir r et r ieves
t he l ocat ion of t he next name t o be r ead in a dir ect or y.
4. The answer s ar e as f ol l ows:
1. file1 is open f or r eading onl y.
2. file2 is act ual l y a pipe t hat is sending t he out put f r om a command t o t his
pr ogr am (wher e it is t r eat ed as input ).
3. file3 is open f or r eading and wr it ing. (+<file3 is equival ent .)
4. MYFILE is being t r eat ed as ident ical t o STDOUT (t he t wo f il e var iabl es now
r ef er t o t he same f il e).
5. The answer s ar e as f ol l ows:
1. Read and wr it e per missions f or ever ybody.
2. Read, wr it e, and execut e per missions f or ever ybody.
3. Read, wr it e, and execut e per missions f or t he owner onl y.
4. Read and wr it e per missions f or t he owner ; r ead per missions f or ever ybody
el se.
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
opendir (MYDIR, "/u/jqpublic") ||
die ("Can't open directory");
while ($file = readdir (MYDIR)) {
next if ($file =~ /^\.{1,2}$|^[^.]/);
print ("$file\n");
}
closedir (MYDIR);
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$filecount = 1;
&print_dir ("/u/jqpublic");
sub print_dir {
local ($dirname) = @_;
local ($file, $subdir, $filevar);
$filevar = "MYFILE" . $filecount++;
opendir ($filevar, $dirname) ||
die ("Can't open directory");
# first pass: read and print file names
print ("\ndirectory $dirname:\n");
while ($file = readdir ($filevar)) {
next if ($file eq "." || $file eq "..");
next if (-d ($dirname . "/" . $file));
print ("$file\n");
}
# second pass: recursively print subdirectories
rewinddir ($filevar);
while ($subdir = readdir ($filevar)) {
next unless (-d ($dirname . "/" . $subdir));
next if ($subdir eq "." || $subdir eq "..");
&print_dir ($dirname . "/" . $subdir);
}
closedir ($filevar);
}
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
opendir (MYDIR, "/u/jqpublic") ||
die ("Can't open directory");
# the following is a trick: "." is alphabetically less than
# anything we want to print, so it makes a handy
# initial value
$lastfile = ".";
until (1) {
rewinddir (MYDIR);
$currfile = "";
while ($file = readdir (MYDIR)) {
next if ($file =~ /^\./);
if ($file gt $lastfile &&
($currfile eq "" || $file lt $currfile)) {
$currfile = $file;
}
}
last if ($currfile eq "");
print ("$currfile\n");
$lastfile = $currfile;
}
closedir (MYDIR);
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
@digits = ("zero", "one", "two", "three",
"four", "five", "six", "seven",
"eight", "nine");
&start_hot_keys;
while (1) {
$char = getc(STDIN);
last if ($char eq "\033");
next if ($char =~ /[^0-9]/);
print ("$digits[$char]\n");
}
&end_hot_keys;
sub start_hot_keys {
system ("stty cbreak");
system ("stty -echo");
}
sub end_hot_keys {
system ("stty -cbreak");
system ("stty echo");
}
5. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$dir = "/u/dave/newperl/testdir";
opendir (MYDIR, $dir) ||
die ("Can't open directory");
chdir ($dir);
while ($file = readdir (MYDIR)) {
next if (-d $file);
next if ($file eq "." || $file eq "..");
if ($file =~ /\.pl$/) {
@stat = stat($file);
chmod (($stat[2] | 0700), $file);
} else {
chmod (0400, $file);
}
}
closedir (MYFILE);
6. This pr ogr am is t r ying t o use eof() t o t est f or t he end of a par t icul ar input f il e. In
Per l , eof() t est s f or t he end of t he ent ir e set of input f il es, and eof (wit h no
par ent heses) t est s f or t he end of a par t icul ar input f il e.
Answers for Day 13, "Process, String, and Mathematical Functions"
Quiz
1. The answer s ar e as f ol l ows:
1. srand pr ovides a seed f or t he r andom number gener at or .
2. pipe cr eat es an input f il e var iabl e and out put f il e var iabl e t hat ar e l inked
t oget her . This is most f r equent l y used by fork t o al l ow pr ocesses t o
communicat e wit h one anot her .
3. atan2 cal cul at es t he ar ct angent f or a par t icul ar val ue (in t he r ange -p t o
p).
4. sleep suspends t he pr ogr am f or a specif ied number of seconds.
5. gmtime r et ur ns t he cur r ent Gr eenwich Mean Time (in machine-r eadabl e
f or mat ).
2. fork st ar t s an ident ical copy of t he pr ogr am cur r ent l y r unning. system st ar t s a
compl et el y dif f er ent pr ogr am t hat r uns concur r ent l y (at t he same t ime as t he
cur r ent pr ogr am). exec t er minat es t he cur r ent pr ogr am and st ar t s a new one.
3. wait wait s f or any chil d pr ocess t o t er minat e. waitpid wait s f or a par t icul ar chil d
pr ocess t o t er minat e.
4. The easiest way t o obt ain t he val ue of p is wit h t he f ol l owing st at ement :
$pi = atan2(1, 1) * 4;
This nor mal l y pr oduces as cl ose an appr oximat ion of p as is possibl e on your syst em.
5. You can obt ain e wit h t his st at ement : $e = exp(1);
6. The answer s ar e as f ol l ows:
1. %x
2. %o
3. %e
4. %f
7. The answer s ar e as f ol l ows:
1. "abc"
2. "efgh"
3. "gh"
4. The nul l st r ing (a l engt h of 0 is being specif ied)
8. The answer s ar e as f ol l ows:
1. 1
2. -1
3. 1
4. 6
5. 5
9. The answer s ar e as f ol l ows:
1. 4
2. 9
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$child = fork();
if ($child == 0) {
print ("This line goes first\n");
exit (0);
} else {
$child2 = fork();
if ($child2 == 0) {
waitpid ($child, 0);
print ("This line goes second\n");
exit (0);
} else {
waitpid ($child2, 0);
print ("This line goes third\n");
}
}
2. Her e is a pr ogr am t hat r eads f r om temp:
#!/usr/local/bin/perl
open (INFILE, "temp") || die ("Can't open input");
while ($line = <INFILE>) {
print ($line);
}
close (INFILE);
Her e is a pr ogr am t hat wr it es t o temp and cal l s t he f ir st pr ogr am (which is assumed
t o be named ch13.2a):
#!/usr/local/bin/perl
open (OUTFILE, ">temp") || die ("Can't open output");
while ($line = <STDIN>) {
print OUTFILE ($line);
}
close (OUTFILE);
exec ("ch13.2a");
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
for ($val = 1; $val <= 100; $val++) {
print ("log of $val is ", log($val), "\n");
}
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
for ($i = 1; $i <= 6; $i++) {
&sum(10 ** $i);
}
sub sum {
local($limit) = @_;
local(@startval, @stopval);
local($i, $count);
$count = 0;
@startval = times();
for ($i = 1; $i <= $limit; $i++) {
$count += $i;
}
@stopval = times();
print ("sum $limit: ", $stopval[0]-$startval[0], "\n");
}
5. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$degrees = <STDIN>;
chop ($degrees);
$radians = $degrees * atan2(1,1) / 45;
$sin = sin ($radians);
$cos = cos ($radians);
print ("sin of $degrees is ", $sin, "\n");
print ("cos of $degrees is ", $cos, "\n");
print ("tan of $degrees is ", $sin/$cos, "\n");
6. The out put specif ied by t he f ir st cal l t o print might get jumbl ed because t he cal l
t o system def ines it s own st andar d out put buf f er s. To get ar ound t his pr obl em, set
t he syst em var iabl e $| t o 1 bef or e cal l ing system.
7. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
@searchletters = ("a", "e", "i", "o", "u");
$inputline = <STDIN>;
foreach $letter (@searchletters) {
printf("searching for $letter...\n");
$location = 0;
while (1) {
$location = index ($inputline, $letter,
$location);
last if ($location == -1);
print("\tfound at location $location\n");
$location += 1;
}
}
8. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
@searchletters = ("a", "e", "i", "o", "u");
$inputline = <STDIN>;
foreach $letter (@searchletters) {
printf("searching for $letter...\n");
$location = length ($inputline);
while (1) {
$location = rindex ($inputline, $letter,
$location);
last if ($location == -1);
print("\tfound at location $location\n");
$location -= 1;
}
}
9. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
@searchletters = ("a", "e", "i", "o", "u");
$inputline = <STDIN>;
$len = length ($inputline);
foreach $letter (@searchletters) {
print ("searching for $letter...\n");
$currpos = 0;
while ($currpos < $len) {
$substring = substr ($inputline, $currpos, 1);
if ($letter eq $substring) {
print("\tfound at location $currpos\n");
}
$currpos++;
}
}
10. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$_ = <STDIN>; # reads to $_ by default
print ("number of a's found: ", tr/a/a/, "\n");
print ("number of e's found: ", tr/e/e/, "\n");
print ("number of i's found: ", tr/i/i/, "\n");
print ("number of o's found: ", tr/o/o/, "\n");
print ("number of u's found: ", tr/u/u/, "\n");
11. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$number = <STDIN>;
if ($number =~ /\.|[eE]/) {
printf ("in exponential form: %e\n", $number);
printf ("in fixed-point form: %f\n", $number);
} else {
printf ("in decimal form: %d\n", $number);
printf ("in octal form: 0%o\n", $number);
printf ("in hexadecimal form: 0x%x\n", $number);
}
12. This pr ogr am goes int o an inf init e l oop if index act ual l y f inds t he subst r ing xyz.
To get ar ound t his pr obl em, incr ement $lastfound (at t he bot t om of t he l oop)
bef or e cal l ing index again.
Answers for Day 14, "Scalar-Conversion and List-Manipulation
Functions"
Quiz
1. The answer s ar e as f ol l ows:
1. A char act er st r ing, padded wit h nul l char act er s if necessar y.
2. A char act er st r ing, padded wit h bl anks if necessar y.
3. A f l oat ing-point number (doubl e-pr ecision).
4. A point er t o a st r ing (as in t he C pr ogr amming l anguage).
5. Skip t o t he posit ion specif ied.
2. The answer s ar e as f ol l ows:
1. Unpack a char act er st r ing (unst r ipped).
2. Skip f our byt es, unpack a 10-char act er st r ing (st r ipping nul l char act er s and
bl anks), and t hen t r eat t he r est of t he packed st r ing as int eger s.
3. Skip t o t he end of t he packed st r ing, back up f our byt es, and unpack f our
unsigned char act er s.
4. Unpack t he f ir st int eger , skip f our byt es, unpack an int eger , skip back eight
byt es, and unpack anot her int eger . (This, ef f ect ivel y, unpacks t he f ir st ,
t hir d, and second int eger s in t hat or der .)
5. Unpack a st r ing of bit s in l ow-t o-high or der , back up t o t he beginning, and
unpack t he same st r ing of bit s in high-t o-l ow or der .
3. The answer s ar e as f ol l ows:
1. 1
2. 3
4. defined t est s whet her a par t icul ar val ue is equival ent t o t he special "undef ined"
val ue. undef set s a scal ar var iabl e, ar r ay el ement , or ar r ay var iabl e t o be equal
t o t he special undef ined val ue.
5. The answer s ar e as f ol l ows:
1. ("new", "2", "3", "4", "5")
2. ("1", "2", "test1", "test2", "3", "4", "5")
3. ("1", "2", "3", "4", "test1", "test2")
4. ("1", "2", "4", "5")
5. ("1", "2", "3")
6. The answer s ar e as f ol l ows:
1. This r et ur ns ever y l ist el ement t hat does not st ar t wit h an excl amat ion
mar k.
2. This r et ur ns ever y l ist el ement t hat cont ains a wor d t hat consist s ent ir el y
of digit s.
3. This r et ur ns ever y nonempt y l ist el ement .
4. This r et ur ns ever y l ist el ement .
7. unshift adds one or mor e el ement s t o t he l ef t end of a l ist . shift r emoves an
el ement f r om t he l ef t end of a l ist .
8. The answer s ar e as f ol l ows:
1. splice (@array, 0, 1);
2. splice (@array, @array-1, 1);
3. splice (@array, scalar(@array), 0, @sublist);
4. splice (@array, 0, 0, @sublist);
9. You can cr eat e a st ack using push t o add el ement s and pop t o r emove t hem (or by
using shift and unshift in t he same way).
10. You can cr eat e a queue using push t o add el ement s and shift t o r emove t hem (or
by using unshift and pop in t he same way).
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$string1 = <STDIN>;
chop ($string1);
$len1 = length ($string1);
$string2 = <STDIN>;
chop ($string2);
$len2 = length ($string2);
if ($len1 % 8 != 0) {
$string1 = "0" x (8 - $len1 % 8) . $string1;
$len1 += 8 - $len1 % 8;
}
if ($len2 % 8 != 0) {
$string2 = "0" x (8 - $len2 % 8) . $string2;
$len2 += 8 - $len2 % 8;
}
if ($len1 > $len2) {
$string2 = "0" x ($len1 - $len2) . $string2;
} else {
$string1 = "0" x ($len2 - $len1) . $string1;
$len1 += ($len2 - $len1);
}
$bytes1 = pack ("b*", $string1);
$bytes2 = pack ("b*", $string2);
$carry = 0;
$count = $len1 - 1;
while ($count >= 0) {
$bit1 = vec ($bytes1, $count, 1);
$bit2 = vec ($bytes2, $count, 1);
$result = ($bit1 + $bit2 + $carry) & 1;
$carry = ($bit1 + $bit2 + $carry) >> 1;
vec ($bytes1, $count, 1) = $result;
$count-;
}
$resultstring = unpack ("b*", $bytes1);
$resultstring = $carry . $resultstring if ($carry > 0);
print ("$resultstring\n");
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$string1 = <STDIN>;
chop ($string1);
$len1 = length ($string1);
$string2 = <STDIN>;
chop ($string2);
$len2 = length ($string2);
if ($len1 % 8 != 0) {
$string1 = "0" x (8 - $len1 % 8) . $string1;
$len1 += 8 - $len1 % 8;
}
if ($len2 % 8 != 0) {
$string2 = "0" x (8 - $len2 % 8) . $string2;
$len2 += 8 - $len2 % 8;
}
if ($len1 > $len2) {
$string2 = "0" x ($len1 - $len2) . $string2;
} else {
$string1 = "0" x ($len2 - $len1) . $string1;
$len1 += ($len2 - $len1);
}
$bytes1 = pack ("h*", $string1);
$bytes2 = pack ("h*", $string2);
$carry = 0;
$count = $len1 - 1;
while ($count >= 0) {
$nybble1 = vec ($bytes1, $count, 4);
$nybble2 = vec ($bytes2, $count, 4);
$result = ($nybble1 + $nybble2 + $carry) & 15;
$carry = ($nybble1 + $nybble2 + $carry) >> 4;
vec ($bytes1, $count, 4) = $result;
$count-;
}
$resultstring = unpack ("h*", $bytes1);
$resultstring = $carry . $resultstring if ($carry > 0);
print ("$resultstring\n");
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$value = <STDIN>;
$value *= 100;
$value = int ($value + 0.5);
$value = sprintf ("%.2f", $value / 100);
print ("$value\n");
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$passwd = crypt ("bluejays", "ez");
$try = 1;
while (1) {
print ("Enter the secret password:\n");
system ("stty -echo");
$guess = <STDIN>;
system ("stty echo");
if (crypt ($guess, substr ($passwd, 0, 2))
eq $passwd) {
print ("Correct!\n");
last;
}
if ($try == 3) {
die ("Sorry! Goodbye!\n");
}
print ("Try again - ");
$try++;
}
5. This pr ogr am is act ual l y r eading t he l ow-or der bit of t he bit vect or . To r ead t he
high-or der bit , use vec ($packed, 7, 1).
6. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
# This program uses a very dumb sorting algorithm.
@list = (41, 26, 11, 9, 8); # sample list to sort
for ($outer = 0; $outer < @list; $outer++) {
for ($inner = 0; $inner < @list; $inner++) {
if ($list[$inner] > $list[$inner+1]) {
$x = splice (@list, $inner, 1);
splice (@list, $inner+1, 0, $x);
}
}
}
7. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
# assume %oldarray is assigned here
while (($subscript, $value) = each (%oldarray)) {
if (defined ($newarray{$value})) {
print STDERR ("$value already defined\n");
} else {
$newarray{$value} = $subscript;
}
}
8. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
while ($line = <STDIN>) {
@words = split (/\s+/, $line);
@shortwords = grep (/^.{1,5}$/, @words);
print ("@shortwords\n");
}
9. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$line = <STDIN>;
$line =~ s/^\s+//;
while (1) {
last if ($line eq "");
($word, $line) = split (/\s+/, $line, 2);
print ("$word\n");
}
10. This subr out ine is t r ying t o r emove an el ement f r om a l ist using unshift. The
subr out ine shoul d use shift, not unshift.
Answers for Day 15, "System Functions"
Quiz
1. The answer s ar e as f ol l ows:
1. endpwent, getpwent, getpwnam, getpwuid, and setpwent.
2. endhostent, gethostbyaddr, gethostbyname, gethostent, and sethostent.
3. endnetent, getnetbyaddr, getnetbyname, getnetent, and setnetent.
4. endservent, getservbyname, getservbyport, getservent, and setservent.
2. Ser ver pr ocesses cal l socket, bind, listen, and accept, in t hat or der . Cl ient
pr ocesses cal l socket, bind, and connect, in t hat or der .
3. The answer s ar e as f ol l ows:
1. getpwuid sear ches f or an ent r y in /etc/passwd t hat mat ches a specif ic user
ID.
2. setprotoent r ewinds t he /etc/protocols f il e.
3. gethostbyaddr sear ches t he /etc/hosts f il e f or a par t icul ar net wor k
(Int er net ) addr ess.
4. getgrent r et r ieves t he next ent r y f r om t he /etc/group f il e.
5. getservbyport sear ches t he /etc/services f il e f or an ent r y cor r esponding
t o a par t icul ar por t number .
4. To send inf or mat ion using a socket , use an out put f unct ion such as print or
printf, and specif y t he f il e var iabl e associat ed wit h t he socket .
5. You can obt ain al l t he user IDs on your syst em by using getpwent t o r ead t he
/etc/passwd f il e. This f il e cont ains one ent r y per user ID, and t he user ID is par t of
t he ent r y.
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
while (($gname, $password, $groupid, $userids)
= getgrent()) {
$garray{$gname} = $userids;
}
foreach $gname (sort keys (%garray)) {
print ("Group $gname:\n");
@userids = split (/\s+/, $garray{$gname});
foreach $userid (sort (@userids)) {
print ("\t$userid\n");
}
}
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
while (($name, $d1, $d2, $d3, $d4, $d5, $d6, $homedir) =
getpwent()) {
$dirlist{$name} = $homedir;
}
foreach $name (sort keys (%dirlist)) {
printf ("userid %-15s has home directory %s\n",
$name, $dirlist{$name});
}
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
while (@retval = getpwent()) {
$retval[8] = "<null>" if ($retval[8] eq "");
$shellarray{$retval[8]} += 1;
}
foreach $shell (sort count keys (%shellarray)) {
printf ("%-25s %5d %s\n", $shell, $shellarray{$shell},
($shellarray{$shell} == 1 ?
"occurrence" : "occurrences"));
}
sub count {
$shellarray{$b} <=> $shellarray{$a};
}
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$otherid = fork();
if ($otherid == 0) {
# child process
$otherid = getppid();
}
$| = 1; # eliminate print buffers
print ("The process id of the other process is $otherid.\n");
5. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$port = 2000;
while (getservbyport($port, "tcp")) {
$port++;
}
($d1, $d2, $prototype) = getprotobyname ("tcp");
# in the following, replace "silver" with the name
# of your machine
($d1, $d2, $d3, $d4, $rawaddr) = gethostbyname ("silver");
$serveraddr = pack ("Sna4x8", 2, $port, $rawaddr);
socket (SSOCKET, 2, 1, $prototype) || die ("No socket");
bind (SSOCKET, $serveraddr) || die ("Can't bind");
listen (SSOCKET, 5) || die ("Can't listen");
while (1) {
($clientaddr = accept (SOCKET, SSOCKET))
|| die ("Can't accept");
if (fork() == 0) {
select (SOCKET);
$| = 1;
open (MYFILE, "/u/jqpublic/testfile");
while ($line = <MYFILE>) {
print SOCKET ($line);
}
close (MYFILE);
close (SOCKET);
exit (0);
}
}
6. getnetent r et ur ns an addr ess as an ar r ay of f our byt es, not as a r eadabl e addr ess.
To conver t t he addr ess r et ur ned by getnetent t o r eadabl e f or m, cal l unpack.
Answers for Day 16, "Command-Line Options"
Quiz
1. The answer s ar e as f ol l ows:
1. The -0 opt ion specif ies t he end of f il e char act er f or t he input l ine.
2. The -s opt ion enabl es you t o specif y opt ions f or your pr ogr am.
3. The -w opt ion t el l s t he Per l int er pr et er t o war n you if it sees somet hing
t hat it t hinks is er r oneous.
4. The -x opt ion t el l s t he Per l int er pr et er t hat your pr ogr am is t o be
ext r act ed f r om a f il e.
5. The -n opt ion indicat es t hat each l ine of t he f il es specif ied on t he command
l ine is t o be r ead.
2. The answer s ar e as f ol l ows:
1. The input end-of -l ine char act er becomes eit her newl ine or t he char act er
specif ied by -l. The out put end-of -l ine char act er becomes eit her nul l or t he
char act er specif ied by -0.
2. The input end-of -l ine char act er becomes eit her t he char act er specif ied by -l
or t he char act er specif ied by -0; if neit her opt ion has a val ue suppl ied wit h
it , t he input l ine char act er becomes nul l . The out put end-of -l ine char act er
becomes eit her nul l or t he char act er specif ied by -0.
3. The -n opt ion t el l s t he Per l int er pr et er t o r ead each l ine of t he input f il e, but
does not expl icit l y t el l it t o wr it e out it s input . The -i opt ion copies t he input f il e
t o a t empor ar y f il e, and t hen opens t he input f il e f or wr it ing. If you do not
expl icit l y wr it e t o t he f il e your sel f , not hing get s wr it t en t o it .
4. This is a t r ick quest ion: It doesn't . You'l l have t o make sur e t hat your Per l
comment s ar e not C pr epr ocessor commands.
5. The opt ions f or t he int er pr et er appear bef or e t he Per l pr ogr am name in t he
command l ine, or in t he header comment f or t he pr ogr am. The opt ions f or t he
pr ogr am appear af t er t he pr ogr am name.
Exercises
1. Her e is one possibl e sol ut ion:
$ perl -i -p -l072 -e ";" testfile
Not e t hat -e ";" indicat es an empt y pr ogr am. (Ot her wise, t he Per l int er pr et er
woul d assume t hat testfile was t he pr ogr am, not t he input f il e.)
2. Her e is one possibl e sol ut ion:
$ perl -ne "print if (/\bthe\b/);" file1 file2 ...
3. Her e is one possibl e sol ut ion:
$ perl -nae 'print ("$F[1]\n");' file1 file2 ...
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl -s
print ("Hello\n") if ($H == 1);
print ("Goodbye\n") if ($G == 1);
5. Her e is one possibl e sol ut ion:
$ perl -i -pe "tr/a-z/A-Z/;" file1 file2 ...
6. This command l ine wipes out al l of your input f il es. Use t he -p opt ion inst ead of
t he -n opt ion.
7. The -i opt ion can be specif ied wit h a val ue (f or cr eat ing a backup ver sion of t he
f il e). The Per l int er pr et er t hinks t hat pe is t he suf f ix t o append t o t he f il ename,
and does not r eal ize t hat t hese ar e supposed t o be opt ions. (I get t r ipped up by t his
pr obl em al l t he t ime.)
Answers for Day 17, "System Variables"
Quiz
1. The pat t er n-mat ching oper at or , t he subst it ut ion oper at or , t he t r ansl at ion
oper at or , t he <> oper at or (if it appear s in a while or for condit ional expr ession),
t he chop f unct ion, t he print f unct ion, and t he study f unct ion.
2. The answer s ar e as f ol l ows:
1. The $= var iabl e cont ains t he page l engt h of a par t icul ar out put f il e.
2. The $/ var iabl e cont ains t he input end-of -l ine char act er .
3. The $? var iabl e cont ains t he r et ur n code r et ur ned by a command cal l ed by
t he system f unct ion or encl osed in back quot es.
4. The $! var iabl e cont ains t he er r or code gener at ed by a syst em l ibr ar y
r out ine.
5. The @_ var iabl e cont ains t he l ist of ar gument s passed t o a subr out ine by t he
cal l ing pr ogr am or cal l ing subr out ine.
3. ARGV is t he f il e var iabl e used by t he <> oper at or t o r ead f r om t he l ist of input f il es
specif ied on t he command l ine. $ARGV is t he name of t he cur r ent f il e being r ead by
t he <> oper at or . @ARGV is t he l ist of ar gument s (or f il es) specif ied on t he command
l ine.
4. @INC cont ains t he dir ect or ies t o sear ch when l ooking f or f il es t o be incl uded. %INC
l ist s t he f il es r equest ed by t he require f unct ion t hat have al r eady been f ound.
5. $0 is t he name of t he pr ogr am you ar e r unning. $1 is def ined when a pat t er n is
mat ched, and is t he f ir st subpat t er n encl osed in par ent heses in t he mat ched
pat t er n.
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl -i
while (<>) {
s/[ \t]+/ /g;
tr/A-Z/a-z/;
print;
}
Al l of t hese st at ement s use t he syst em var iabl e $_ by def aul t .
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl -i
while ($line = <>) {
while ($line =~ / +/g) {
$line = $' . " " . $';
}
print ($line);
}
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
@dirlist = split (/:/, $ENV{"PATH"});
foreach $dir (@dirlist) {
print ("$dir\n");
}
Not e t hat if your machine uses a char act er ot her t han : t o separ at e ent r ies in t he
val ue of your PATH envir onment var iabl e, you shoul d use t his char act er inst ead.
4. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$SIG{"INT"} = stopnum;
$num = 1;
while (1) {
print ("$num\n");
$num++;
}
sub stopnum {
print ("\nInterrupted.\n");
exit (0);
}
5. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
$total = 0;
while ($line = <DATA>) {
@nums = split (/\s+/, $line);
foreach $num (@nums) {
$total += $num;
}
}
print ("The total is $total.\n");
__END__
4 17 26
11
9 5
6. The subst it ut ion oper at or mat ches a pat t er n, so it over wr it es t he val ue of $'. To
f ix t his, copy $' int o a scal ar var iabl e of your own bef or e sear ching f or ext r a
spaces.
Answers for Day 18, "References in
Perl 5"
Quiz
1. The cor r ect way t o wr it e t his is $pointer->{$i}. You ar e der ef er encing mor e t han
once in t he l ine shown in t he quest ion.
2. Make t he l ine
my($a,$b)
l ook l ike t his:
my (\$a,\$b)
Then use @$a and @$b t o access t hese ar r ays by r ef er ence.
3. Ther e is no dif f er ence as f ar as accessing t he var iabl e in $i is concer ned.
4. The wor d Help.
5. The ${variable} can be used t o cr eat e symbol ic r ef er ences. The t hr ee l ines coul d
be r ewr it t en by el iminat ing ${} const r uct s and using t he val ues inst ead.
Exercises
1. Her e is one possibl e sol ut ion:
$p1 = @a;
$p2 = %a;
$p3 = sub { return @_ ; };
printf "\n Array reference = $p1";
printf "\n Hash reference = $p2";
printf "\n Subroutine reference = $p3";
2. Use t he code in t he given hint t o const r uct your f unct ion wit h one except ion: you
use an ar r ay f or @list. Then you can cal l each f unct ion by using t he index in t he
@list:
&$list[$index]();
3. Har d l inks ar e maint ained by Per l and have t o be gr eat er t han zer o f or a var iabl e
t o exist . Sof t l inks can point t o not hing and ar e cr eat ed by a user pr ogr am.
4. Add t he f ol l owing l ines t o t he end of t he code:
printf "\n Address = $this, $that";
printf "\n Difference of Address = %f \n" $this - $that";
The addr esses ar e not dif f er ent because t hey point t o t he same f unct ion.
Answers for Day 19, "Object-Oriented Programming in Perl"
Quiz
1. The f ol l owing is cor r ect :
Balloon::new();
Balloon->new();
new Balloon;
2. This causes a memor y l eak. The memor y al l ocat ed f or $y has an ext r a r ef er ence.
The r ef er ence count f or $y is set when $x is set t o it . Af t er t he bl ock of code ends,
t he $y r ef er ence count r emains nonzer o. As a r esul t , t he memor y $y hangs ar ound
unt il t he pr ogr am exit s.
3. A cl ass is onl y a package t hat pr ovides met hods, an object is a r ef er ence, and a
met hod is a subr out ine wit h t he f ir st ar gument as t he name of t he cl ass.
4. Use BaseClassName:: expl icit l y in f r ont of t he f unct ion name t o f or ce Per l t o use
t he base cl ass.
Exercises
1. Cr eat e a f il e cal l ed Zeller.pm l ike t his:
package Zeller;
require Exporter;
@EXPORT = (Zeller);
sub Zeller {
my ($month,$day,$year) = @_;
<<< Insert code from sample here>>>
}
1;
2. Then use t he f il e in your Per l scr ipt l ike t his:
use Zeller;
$z = Zeller(7,21,1962);
print "\n Day of the week = $z";
3. Check if t he number of incoming par amet er s is not t hr ee. Use t he cal l t o 'date
+\%D'. The answer wil l r et ur n in mm/dd/yy f or mat . Spl it t he r esponse on '/' t o get
t he mont h.
$count = scalar (@_);
if ($count != 3) {
$dt = 'date +\%D';
($month,$day,$year) = split($_,'/');
else {
my ($month,$day,$year) = @_;
}
$z = Zeller($month,$day,$year);
4. Her e is one possibl e sol ut ion:
#!/usr/bin/perl
print 'find . -depth -print ';
5. Add t he f ol l owing l ines of code t o t he beginning of t he f unct ion:
if (scalar(@_) == 0) {
print "\n ================================= \n";
print " Making a black cup of coffee. ";
print "\n ================================= \n";
return;
}
Answers for Day 20, "Miscellaneous Features of Perl"
Quiz
1. The answer s ar e as f ol l ows:
1. __LINE__ cont ains t he cur r ent l ine number of t he execut ing pr ogr am or
subr out ine.
2. __FILE__ cont ains t he cur r ent f il e being execut ed.
3. __END__ indicat es t he end of t he Per l pr ogr am.
2. The answer s ar e as f ol l ows:
1. It's time to say $var
2. "It's time to say hello"; (incl uding t he quot es and t he semicol on)
3. hello
3. ("one", "two", "three", "", "five")
4. Ther e ar e t wo ways:
H Wit h t he #include pr epr ocessor command.
H Adding t he f il e's dir ect or y t o @INC and t hen passing t he f il ename t o require.
Exercises
1. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
@filelist = <*>;
foreach $file (sort (@filelist)) {
print ("$file\n");
}
2. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
unshift (@INC, "/u/jqpublic/perlfiles");
require ("sum.pl");
@numlist = <STDIN>;
chop (@numlist);
$total = &sum (@numlist);
print ("The total is $total.\n");
3. Her e is one possibl e sol ut ion:
#!/usr/local/bin/perl
package pack1;
$var = <STDIN>;
chop ($var);
package pack2;
$var = <STDIN>;
chop ($var);
package main;
$total = $pack1'var + $pack2'var;
print ("The total is $total.\n");
4. In t his case, <$filepattern> is t r eat ed as a scal ar var iabl e cont aining t he name of
a f il e var iabl e, not as a scal ar var iabl e cont aining a f il e l ist pat t er n. (To obt ain
t he l at t er , use <${filepattern}>.)
5. Ther e shoul d be no space bet ween t he << and t he EOF. The space af t er t he << means
t hat t he end-of -st r ing char act er st r ing is assumed t o be nul l ; t her ef or e, print
onl y pr int s t he f ir st of t he t wo l ines in t he st r ing.
Answers for Day 21, "The Perl Debugger"
Quiz
1. The answer s ar e as f ol l ows:
1. Tr ace mode cont r ol s whet her l ines ar e displ ayed as t hey ar e execut ed. If
t r ace mode is on, l ines ar e displ ayed; if it is of f , t hey ar e not .
2. A st ack t r ace is a displ ay of t he cur r ent subr out ine being execut ed, pl us a
l ist ing of t he subr out ine t hat cal l ed t his one, and so on back t o t he
or iginal main pr ogr am.
3. A br eakpoint is a l ine in t he pr ogr am bef or e which execut ion is hal t ed and
f ur t her debugging commands ar e r equest ed.
4. A l ine act ion is a st at ement t hat is execut ed whenever a par t icul ar l ine of
t he pr ogr am is r eached.
2. The X command displ ays onl y var iabl es in t he cur r ent package. The V command can
displ ay var iabl es in any package.
3. The // command sear ches f or war d in t he f il e f or a l ine mat ching t he specif ied
pat t er n; t he ?? command sear ches backwar d.
4. The > command def ines a l ine act ion t hat is t o be execut ed bef or e t he debugger
execut es any f ur t her st at ement s. The < command def ines a l ine act ion t hat is t o be
per f or med af t er t he debugger has f inished execut ing t he next st at ement or gr oup
of st at ement s.
5. The s command st eps int o a subr out ine when it encount er s one; t he n command
execut es t he subr out ine wit hout st epping int o it , st opping at t he st at ement
f ol l owing t he subr out ine.
6. The answer s ar e as f ol l ows:
1. This displ ays t he next window of st at ement s, cont inuing wher e t he l ast l
command l ef t of f .
2. This displ ays just l ine 26.
3. This displ ays l ines 5-7.
4. This displ ays l ines 5-12.
5. This displ ays t he window of st at ement s sur r ounding t he cur r ent l ine.

Appendix B
ASCII Character Set
G Page 1
G Page 2
G Page 3
G Page 4
G Page 5

Vous aimerez peut-être aussi