Learning Perl - Amazon S3 · 2019-02-26 · Perl Cookbook Perl Debugger Pocket Reference Perl in a...

Post on 08-Jul-2020

26 views 0 download

Transcript of Learning Perl - Amazon S3 · 2019-02-26 · Perl Cookbook Perl Debugger Pocket Reference Perl in a...

Learning Perl

Other Perl resources from O’Reilly

Related titles Advanced Perl ProgrammingIntermediate PerlMastering PerlPerl 6 and Parrot EssentialsPerl Best PracticesPerl Cookbook!

Perl Debugger PocketReference

Perl in a NutshellPerl Testing: A Developer’s

Notebook!

Practical mod-perl

Perl BooksResource Center

perl.oreilly.com is a complete catalog of O’Reilly’s books on Perland related technologies, including sample chapters and codeexamples.

Perl.com is the central web site for the Perl community. It is theperfect starting place for finding out everything there is to knowabout Perl.

Conferences O’Reilly brings diverse innovators together to nurture the ideasthat spark revolutionary industries. We specialize in document-ing the latest tools and systems, translating the innovator’sknowledge into useful skills for those in the trenches. Visitconferences.oreilly.com for our upcoming events.

Safari Bookshelf (safari.oreilly.com) is the premier online refer-ence library for programmers and IT professionals. Conductsearches across more than 1,000 books. Subscribers can zero inon answers to time-critical questions in a matter of seconds.Read the books on your Bookshelf from cover to cover or sim-ply flip to the page you need. Try it today with a free trial.

,perlroadmap.24755 Page ii Tuesday, June 17, 2008 8:15 AM

FIFTH EDITION

Learning Perl

5DQGDO�/��6FKZDUW]��7RP�3KRHQL[��DQG�EULDQ�G�IR\

Tomcat ™

The Definitive Guide

Jason Brittain and Ian F. Darwin

Beijing • Cambridge • Farnham • Köln • Sebastopol • Taipei • Tokyo

main.title Page iii Monday, May 19, 2008 11:21 AM

Learning Perl, Fifth EditionE\�5DQGDO�/��6FKZDUW]��7RP�3KRHQL[��DQG�EULDQ�G�IR\

&RS\ULJKW��������2¦5HLOO\�0HGLD��$OO�ULJKWV�UHVHUYHG�3ULQWHG�LQ�WKH�8QLWHG�6WDWHV�RI�$PHULFD�

3XEOLVKHG�E\�2¦5HLOO\�0HGLD��,QF��������*UDYHQVWHLQ�+LJKZD\�1RUWK��6HEDVWRSRO��&$�������

2¦5HLOO\�ERRNV�PD\�EH�SXUFKDVHG�IRU�HGXFDWLRQDO��EXVLQHVV��RU�VDOHV�SURPRWLRQDO�XVH��2QOLQH�HGLWLRQVDUH�DOVR�DYDLODEOH�IRU�PRVW�WLWOHV��KWWS���VDIDUL�RUHLOO\�FRP���)RU�PRUH�LQIRUPDWLRQ��FRQWDFW�RXU�FRUSRUDWH�LQVWLWXWLRQDO�VDOHV�GHSDUWPHQW�����������������RU�FRUSRUDWH#RUHLOO\�FRP�

Editor: $QG\�2UDPProduction Editor: /RUDQDK�'LPDQWCopyeditor: /RUDQDK�'LPDQWProofreader: 6DGD�3UHLVFK

Indexer: (OOHQ�7URXWPDQ�=DLJCover Designer: .DUHQ�0RQWJRPHU\Interior Designer: 'DYLG�)XWDWRIllustrator: -HVVDP\Q�5HDG

Printing History:1RYHPEHU������ )LUVW�(GLWLRQ�-XO\������ 6HFRQG�(GLWLRQ�-XO\������ 7KLUG�(GLWLRQ�-XO\������ )RXUWK�(GLWLRQ�-XO\������ )LIWK�(GLWLRQ�

1XWVKHOO�+DQGERRN��WKH�1XWVKHOO�+DQGERRN�ORJR��DQG�WKH�2¦5HLOO\�ORJR�DUH�UHJLVWHUHG�WUDGHPDUNV�RI2¦5HLOO\�0HGLD�� ,QF��/HDUQLQJ�3HUO�� WKH� LPDJH�RI� D� OODPD�� DQG� UHODWHG� WUDGH�GUHVV� DUH� WUDGHPDUNV�RI2¦5HLOO\�0HGLD��,QF�

0DQ\�RI�WKH�GHVLJQDWLRQV�XVHG�E\�PDQXIDFWXUHUV�DQG�VHOOHUV�WR�GLVWLQJXLVK�WKHLU�SURGXFWV�DUH�FODLPHG�DVWUDGHPDUNV��:KHUH�WKRVH�GHVLJQDWLRQV�DSSHDU�LQ�WKLV�ERRN��DQG�2¦5HLOO\�0HGLD��,QF��ZDV�DZDUH�RI�DWUDGHPDUN�FODLP��WKH�GHVLJQDWLRQV�KDYH�EHHQ�SULQWHG�LQ�FDSV�RU�LQLWLDO�FDSV�

:KLOH�HYHU\�SUHFDXWLRQ�KDV�EHHQ�WDNHQ�LQ�WKH�SUHSDUDWLRQ�RI�WKLV�ERRN��WKH�SXEOLVKHU�DQG�DXWKRUV�DVVXPHQR�UHVSRQVLELOLW\�IRU�HUURUV�RU�RPLVVLRQV��RU�IRU�GDPDJHV�UHVXOWLQJ�IURP�WKH�XVH�RI�WKH�LQIRUPDWLRQ�FRQ�WDLQHG�KHUHLQ�

,6%1�������������������

>0@

����������

Table of Contents

Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi

1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14XHVWLRQV�DQG�$QVZHUV �:KDW�'RHV�£3HUO¤�6WDQG�)RU" �+RZ�&DQ�,�*HW�3HUO" �+RZ�'R�,�0DNH�D�3HUO�3URJUDP" ��$�:KLUOZLQG�7RXU�RI�3HUO ��([HUFLVHV ��

2. Scalar Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191XPEHUV ��6WULQJV ��3HUO¦V�%XLOW�LQ�:DUQLQJV ��6FDODU�9DULDEOHV ��2XWSXW�ZLWK�SULQW ��7KH�LI�&RQWURO�6WUXFWXUH ��*HWWLQJ�8VHU�,QSXW ��7KH�FKRPS�2SHUDWRU ��7KH�ZKLOH�&RQWURO�6WUXFWXUH ��7KH�XQGHI�9DOXH ��7KH�GHILQHG�)XQFWLRQ ��([HUFLVHV ��

3. Lists and Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39$FFHVVLQJ�(OHPHQWV�RI�DQ�$UUD\ ��6SHFLDO�$UUD\�,QGLFHV ��/LVW�/LWHUDOV ��/LVW�$VVLJQPHQW ��,QWHUSRODWLQJ�$UUD\V�LQWR�6WULQJV ��7KH�IRUHDFK�&RQWURO�6WUXFWXUH ��6FDODU�DQG�/LVW�&RQWH[W ��

v

�67',1!�LQ�/LVW�&RQWH[W ��([HUFLVHV ��

4. Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55'HILQLQJ�D�6XEURXWLQH ��,QYRNLQJ�D�6XEURXWLQH ��5HWXUQ�9DOXHV ��$UJXPHQWV ��3ULYDWH�9DULDEOHV�LQ�6XEURXWLQHV ��9DULDEOH�/HQJWK�3DUDPHWHU�/LVWV ��1RWHV�RQ�/H[LFDO��P\��9DULDEOHV ��7KH�XVH�VWULFW�3UDJPD ��7KH�UHWXUQ�2SHUDWRU ��1RQVFDODU�5HWXUQ�9DOXHV ��3HUVLVWHQW��3ULYDWH�9DULDEOHV ��([HUFLVHV ��

5. Input and Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71,QSXW�IURP�6WDQGDUG�,QSXW ��,QSXW�IURP�WKH�'LDPRQG�2SHUDWRU ��7KH�,QYRFDWLRQ�$UJXPHQWV ��2XWSXW�WR�6WDQGDUG�2XWSXW ��)RUPDWWHG�2XWSXW�ZLWK�SULQWI ��)LOHKDQGOHV ��2SHQLQJ�D�)LOHKDQGOH ��)DWDO�(UURUV�ZLWK�GLH ��8VLQJ�)LOHKDQGOHV ��5HRSHQLQJ�D�6WDQGDUG�)LOHKDQGOH ��2XWSXW�ZLWK�VD\ ��([HUFLVHV ��

6. Hashes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93:KDW�,V�D�+DVK" ��+DVK�(OHPHQW�$FFHVV ��+DVK�)XQFWLRQV ���7\SLFDO�8VH�RI�D�+DVK ���7KH��(19�KDVK ���([HUFLVHV ���

7. In the World of Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107:KDW�$UH�5HJXODU�([SUHVVLRQV" ���8VLQJ�6LPSOH�3DWWHUQV ���&KDUDFWHU�&ODVVHV ���

vi | Table of Contents

([HUFLVHV ���

8. Matching with Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1170DWFKHV�ZLWK�P�� ���2SWLRQ�0RGLILHUV ���$QFKRUV ���7KH�%LQGLQJ�2SHUDWRU�� a ���,QWHUSRODWLQJ�LQWR�3DWWHUQV ���7KH�0DWFK�9DULDEOHV ���*HQHUDO�4XDQWLILHUV ���3UHFHGHQFH ���$�3DWWHUQ�7HVW�3URJUDP ���([HUFLVHV ���

9. Processing Text with Regular Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1356XEVWLWXWLRQV�ZLWK�V��� ���7KH�VSOLW�2SHUDWRU ���7KH�MRLQ�)XQFWLRQ ���P���LQ�/LVW�&RQWH[W ���0RUH�3RZHUIXO�5HJXODU�([SUHVVLRQV ���([HUFLVHV ���

10. More Control Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1497KH�XQOHVV�&RQWURO�6WUXFWXUH ���7KH�XQWLO�&RQWURO�6WUXFWXUH ���([SUHVVLRQ�0RGLILHUV ���7KH�1DNHG�%ORFN�&RQWURO�6WUXFWXUH ���7KH�HOVLI�&ODXVH ���$XWRLQFUHPHQW�DQG�$XWRGHFUHPHQW ���7KH�IRU�&RQWURO�6WUXFWXUH ���/RRS�&RQWUROV ���7KH�7HUQDU\�2SHUDWRU��"� ���/RJLFDO�2SHUDWRUV ���([HUFLVHV ���

11. Perl Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169)LQGLQJ�0RGXOHV ���,QVWDOOLQJ�0RGXOHV ���8VLQJ�6LPSOH�0RGXOHV ���([HUFLVH ���

12. File Tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179)LOH�7HVW�2SHUDWRUV ���

Table of Contents | vii

7KH�VWDW�DQG�OVWDW�)XQFWLRQV ���7KH�ORFDOWLPH�)XQFWLRQ ���%LWZLVH�2SHUDWRUV ���([HUFLVHV ���

13. Directory Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1910RYLQJ�$URXQG�WKH�'LUHFWRU\�7UHH ���*OREELQJ ���$Q�$OWHUQDWH�6\QWD[�IRU�*OREELQJ ���'LUHFWRU\�+DQGOHV ���5HFXUVLYH�'LUHFWRU\�/LVWLQJ ���0DQLSXODWLQJ�)LOHV�DQG�'LUHFWRULHV ���5HPRYLQJ�)LOHV ���5HQDPLQJ�)LOHV ���/LQNV�DQG�)LOHV ���0DNLQJ�DQG�5HPRYLQJ�'LUHFWRULHV ���0RGLI\LQJ�3HUPLVVLRQV ���&KDQJLQJ�2ZQHUVKLS ���&KDQJLQJ�7LPHVWDPSV ���([HUFLVHV ���

14. Strings and Sorting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209)LQGLQJ�D�6XEVWULQJ�ZLWK�LQGH[ ���0DQLSXODWLQJ�D�6XEVWULQJ�ZLWK�VXEVWU ���)RUPDWWLQJ�'DWD�ZLWK�VSULQWI ���$GYDQFHG�6RUWLQJ ���([HUFLVHV ���

15. Smart Matching and given-when . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2217KH�6PDUW�0DWFK�2SHUDWRU ���6PDUW�0DWFK�3UHFHGHQFH ���7KH�JLYHQ�6WDWHPHQW ���ZKHQ�ZLWK�0DQ\�,WHPV ���([HUFLVHV ���

16. Process Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2337KH�V\VWHP�)XQFWLRQ ���7KH�H[HF�)XQFWLRQ ���7KH�(QYLURQPHQW�9DULDEOHV ���8VLQJ�%DFNTXRWHV�WR�&DSWXUH�2XWSXW ���3URFHVVHV�DV�)LOHKDQGOHV ���*HWWLQJ�'RZQ�DQG�'LUW\�ZLWK�)RUN ���6HQGLQJ�DQG�5HFHLYLQJ�6LJQDOV ���

viii | Table of Contents

([HUFLVHV ���

17. Some Advanced Perl Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2497UDSSLQJ�(UURUV�ZLWK�HYDO ���3LFNLQJ�,WHPV�IURP�D�/LVW�ZLWK�JUHS ���7UDQVIRUPLQJ�,WHPV�IURP�D�/LVW�ZLWK�PDS ���8QTXRWHG�+DVK�.H\V ���6OLFHV ���([HUFLVH ���

A. Exercise Answers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261

B. Beyond the Llama . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315

Table of Contents | ix

Preface

:HOFRPH�WR�WKH�ILIWK�HGLWLRQ�RI�/HDUQLQJ�3HUO��XSGDWHG�IRU�3HUO������DQG�LWV�ODWHVW�IHD�WXUHV��7KLV�ERRN�LV�JRRG�HYHQ�LI�\RX�DUH�VWLOO�XVLQJ�3HUO������DOWKRXJK��LW¦V�EHHQ�D�ORQJWLPH�VLQFH�LW�ZDV�UHOHDVHG��KDYH�\RX�WKRXJKW�DERXW�XSJUDGLQJ"��

,I� \RX¦UH� ORRNLQJ� IRU� WKH�EHVW�ZD\� WR� VSHQG�\RXU� ILUVW���� WR����KRXUV�ZLWK� WKH�3HUOSURJUDPPLQJ�ODQJXDJH��\RX¦YH�IRXQG�LW��,Q�WKH�SDJHV�WKDW�IROORZ��\RX¦OO�ILQG�D�FDUHIXOO\SDFHG�LQWURGXFWLRQ�WR�WKH�ODQJXDJH�WKDW�LV�WKH�ZRUNKRUVH�RI�WKH�,QWHUQHW��DV�ZHOO�DV�WKHODQJXDJH�RI�FKRLFH�IRU�V\VWHP�DGPLQLVWUDWRUV��ZHE�KDFNHUV��DQG�FDVXDO�SURJUDPPHUVDURXQG�WKH�ZRUOG�

:H�FDQ¦W� JLYH�\RX�DOO�RI�3HUO� LQ� MXVW� D� IHZ�KRXUV��7KH�ERRNV� WKDW�SURPLVH� WKDW� DUHSUREDEO\�ILEELQJ�D�ELW��,QVWHDG��ZH¦YH�FDUHIXOO\�VHOHFWHG�D�XVHIXO�VXEVHW�RI�3HUO�IRU�\RXWR�OHDUQ��JRRG�IRU�SURJUDPV�IURP���WR�����OLQHV�ORQJ��ZKLFK�HQG�XS�EHLQJ�DERXW����RI�WKH�SURJUDPV�LQ�XVH�RXW�WKHUH��$QG�ZKHQ�\RX¦UH�UHDG\�WR�JR�RQ��\RX�FDQ�JHW�,QWHU�PHGLDWH�3HUO��ZKLFK�SLFNV�XS�ZKHUH�WKLV�ERRN�OHDYHV�RII��:H¦YH�DOVR�LQFOXGHG�D�QXPEHURI�SRLQWHUV�IRU�IXUWKHU�HGXFDWLRQ�

(DFK�FKDSWHU�LV�VPDOO�HQRXJK�VR�\RX�FDQ�UHDG�LW�LQ�DQ�KRXU�RU�WZR��(DFK�FKDSWHU�HQGVZLWK�D�VHULHV�RI�H[HUFLVHV�WR�KHOS�\RX�SUDFWLFH�ZKDW�\RX¦YH�MXVW�OHDUQHG��ZLWK�WKH�DQVZHUVLQ�$SSHQGL[�$�IRU�\RXU�UHIHUHQFH��7KXV�� WKLV�ERRN� LV� LGHDOO\�VXLWHG� IRU�D�FODVVURRP£,QWURGXFWLRQ�WR�3HUO¤�FRXUVH��:H�NQRZ�WKLV�GLUHFWO\�EHFDXVH�WKH�PDWHULDO�IRU�WKLV�ERRNZDV�OLIWHG�DOPRVW�ZRUG�IRU�ZRUG�IURP�RXU�IODJVKLS�£/HDUQLQJ�3HUO¤�FRXUVH��GHOLYHUHGWR�WKRXVDQGV�RI�VWXGHQWV�DURXQG�WKH�ZRUOG��+RZHYHU��ZH¦YH�GHVLJQHG�WKH�ERRN�IRU�VHOI�VWXG\�DV�ZHOO�

3HUO�OLYHV�DV�WKH�£WRROER[�IRU�8QL[�¤�EXW�\RX�GRQ¦W�KDYH�WR�EH�D�8QL[�JXUX¢RU�HYHQ�D8QL[�XVHU¢WR�UHDG�WKLV�ERRN��8QOHVV�RWKHUZLVH�QRWHG��HYHU\WKLQJ�ZH¦UH�VD\LQJ�DSSOLHVHTXDOO\�ZHOO� WR�:LQGRZV�$FWLYH3HUO� IURP�$FWLYH6WDWH� DQG�SUHWW\�PXFK� HYHU\�RWKHUPRGHUQ�LPSOHPHQWDWLRQ�RI�3HUO�

$OWKRXJK�\RX�GRQ¦W�QHHG�WR�NQRZ�D�VLQJOH�ELW�DERXW�3HUO�WR�EHJLQ�UHDGLQJ�WKLV�ERRN�ZH�UHFRPPHQG�WKDW�\RX�DOUHDG\�KDYH� IDPLOLDULW\�ZLWK�EDVLF�SURJUDPPLQJ�FRQFHSWVVXFK� DV� YDULDEOHV�� ORRSV�� VXEURXWLQHV�� DQG� DUUD\V�� DQG� WKH� DOO�LPSRUWDQW� £HGLWLQJ� DVRXUFH�FRGH� ILOH�ZLWK�\RXU� IDYRULWH� WH[W�HGLWRU�¤�:H�GRQ¦W�VSHQG�DQ\� WLPH�WU\LQJ� WRH[SODLQ�WKRVH�FRQFHSWV��$OWKRXJK�ZH¦UH�SOHDVHG�WKDW�ZH¦YH�KDG�PDQ\�UHSRUWV�RI�SHRSOH

xi

SLFNLQJ�XS�/HDUQLQJ�3HUO�DQG�VXFFHVVIXOO\�JUDVSLQJ�3HUO�DV�WKHLU�ILUVW�SURJUDPPLQJ�ODQ�JXDJH��RI�FRXUVH��ZH�FDQ¦W�SURPLVH�WKH�VDPH�UHVXOWV�IRU�HYHU\RQH�

Typographical Conventions7KH�IROORZLQJ�IRQW�FRQYHQWLRQV�DUH�XVHG�LQ�WKLV�ERRN�

Constant width8VHG�IRU�PHWKRG�QDPHV��IXQFWLRQ�QDPHV��YDULDEOHV��DQG�DWWULEXWHV��,W�LV�DOVR�XVHGIRU�FRGH�H[DPSOHV�

Constant width bold8VHG�WR�LQGLFDWH�XVHU�LQSXW�

Constant width italic8VHG�WR�LQGLFDWH�D�UHSODFHDEOH�LWHP�LQ�FRGH��H�J���filename��ZKHUH�\RX�DUH�VXSSRVHGWR�VXEVWLWXWH�DQ�DFWXDO�ILOHQDPH��

,WDOLF8VHG�IRU�ILOHQDPHV��85/V��KRVWQDPHV��FRPPDQGV�LQ�WH[W��LPSRUWDQW�ZRUGV�RQ�ILUVWPHQWLRQ��DQG�HPSKDVLV�

)RRWQRWHV8VHG�WR�DWWDFK�SDUHQWKHWLFDO�QRWHV�WKDW�\RX�VKRXOG�QRW�UHDG�RQ�\RXU�ILUVW��RU�SHUKDSVVHFRQG�RU�WKLUG��UHDGLQJ�RI�WKLV�ERRN��6RPHWLPHV�OLHV�DUH�VSRNHQ�WR�VLPSOLI\�WKHSUHVHQWDWLRQ��DQG�WKH�IRRWQRWHV�UHVWRUH�WKH�OLH�WR�WUXWK��2IWHQ��WKH�PDWHULDO�LQ�WKHIRRWQRWH�ZLOO�EH�DGYDQFHG�PDWHULDO�QRW�HYHQ�GLVFXVVHG�DQ\ZKHUH�HOVH�LQ�WKH�ERRN�

How to Contact Us:H�KDYH�WHVWHG�DQG�YHULILHG�DOO�WKH�LQIRUPDWLRQ�LQ�WKLV�ERRN�WR�WKH�EHVW�RI�RXU�DELOLWLHV�EXW�\RX�PD\�ILQG�WKDW�IHDWXUHV�KDYH�FKDQJHG�RU�WKDW�ZH�KDYH�OHW�HUURUV�VOLS�WKURXJK�WKHSURGXFWLRQ�RI�WKH�ERRN��3OHDVH�OHW�XV�NQRZ�RI�DQ\�HUURUV�WKDW�\RX�ILQG��DV�ZHOO�DV�VXJ�JHVWLRQV�IRU�IXWXUH�HGLWLRQV��E\�ZULWLQJ�WR�

2¦5HLOO\�0HGLD��,QF������*UDYHQVWHLQ�+LJKZD\�1RUWK6HEDVWRSRO��&$��������������������LQ�WKH�8�6��RU�&DQDGD���������������LQWHUQDWLRQDO�ORFDO���������������ID[�

<RX�FDQ�DOVR�VHQG�PHVVDJHV�HOHFWURQLFDOO\��7R�EH�SXW�RQ�RXU�PDLOLQJ�OLVW�RU�WR�UHTXHVWD�FDWDORJ��VHQG�HPDLO�WR�

LQIR#RUHLOO\�FRP

xii | Preface

7R�DVN�WHFKQLFDO�TXHVWLRQV�RU�WR�FRPPHQW�RQ�WKH�ERRN��VHQG�HPDLO�WR�

ERRNTXHVWLRQV#RUHLOO\�FRP

:H�KDYH�D�ZHE�VLWH�IRU�WKH�ERRN��ZKHUH�ZH¦OO�OLVW�H[DPSOHV��HUUDWD��DQG�DQ\�SODQV�IRUIXWXUH� HGLWLRQV�� ,W� DOVR�RIIHUV� D�GRZQORDGDEOH� VHW�RI� WH[W� ILOHV� �DQG�D� FRXSOH�RI�3HUOSURJUDPV��WKDW�DUH�XVHIXO��EXW�QRW�UHTXLUHG��ZKHQ�GRLQJ�VRPH�RI�WKH�H[HUFLVHV��<RX�FDQDFFHVV�WKLV�SDJH�DW�

KWWS���ZZZ�RUHLOO\�FRP�FDWDORJ��������������

)RU�PRUH�LQIRUPDWLRQ�DERXW�WKLV�ERRN�DQG�RWKHUV��VHH�WKH�2¦5HLOO\�ZHE�VLWH�

KWWS���ZZZ�RUHLOO\�FRP

Using Code Examples7KLV�ERRN�LV�KHUH�WR�KHOS�\RX�JHW�\RXU�MRE�GRQH��,Q�JHQHUDO��\RX�PD\�XVH�WKH�FRGH�LQWKLV�ERRN�LQ�\RXU�SURJUDPV�DQG�GRFXPHQWDWLRQ��<RX�GR�QRW�QHHG�WR�FRQWDFW�XV�IRUSHUPLVVLRQ�XQOHVV�\RX¦UH�UHSURGXFLQJ�D�VLJQLILFDQW�SRUWLRQ�RI�WKH�FRGH��)RU�H[DPSOH�ZULWLQJ�D�SURJUDP�WKDW�XVHV�VHYHUDO�FKXQNV�RI�FRGH�IURP�WKLV�ERRN�GRHV�QRW�UHTXLUHSHUPLVVLRQ��6HOOLQJ�RU�GLVWULEXWLQJ�D�&'�520�RI�H[DPSOHV�IURP�2¦5HLOO\�ERRNV�GRHVUHTXLUH�SHUPLVVLRQ��$QVZHULQJ�D�TXHVWLRQ�E\�FLWLQJ�WKLV�ERRN�DQG�TXRWLQJ�H[DPSOHFRGH�GRHV�QRW�UHTXLUH�SHUPLVVLRQ��,QFRUSRUDWLQJ�D�VLJQLILFDQW�DPRXQW�RI�H[DPSOH�FRGHIURP�WKLV�ERRN�LQWR�\RXU�SURGXFW¦V�GRFXPHQWDWLRQ�GRHV�UHTXLUH�SHUPLVVLRQ��:H�DS�SUHFLDWH��EXW�GR�QRW�UHTXLUH��DWWULEXWLRQ��$Q�DWWULEXWLRQ�XVXDOO\�LQFOXGHV�WKH�WLWOH��DX�WKRU��SXEOLVKHU��DQG�,6%1��)RU�H[DPSOH��£/HDUQLQJ�3HUO��)LIWK�HGLWLRQ��E\�5DQGDO�/�6FKZDUW]�� 7RP� 3KRHQL[�� DQG� EULDQ� G� IR\�� &RS\ULJKW� ����� 2¦5HLOO\� 0HGLD�� ,QF��������������������¤�,I�\RX�IHHO�\RXU�XVH�RI�FRGH�H[DPSOHV�IDOOV�RXWVLGH�IDLU�XVH�RU�WKHSHUPLVVLRQ�JLYHQ�DERYH��IHHO�IUHH�WR�FRQWDFW�XV�DW�SHUPLVVLRQV#RUHLOO\�FRP�

Safari® Enabled:KHQ�\RX�VHH�D�6DIDUL��(QDEOHG�LFRQ�RQ�WKH�FRYHU�RI�\RXU�IDYRULWH�WHFK�QRORJ\�ERRN��WKDW�PHDQV�WKH�ERRN�LV�DYDLODEOH�RQOLQH�WKURXJK�WKH�2¦5HLOO\1HWZRUN�6DIDUL�%RRNVKHOI�

6DIDUL�RIIHUV�D�VROXWLRQ�WKDW¦V�EHWWHU�WKDQ�H�ERRNV��,W¦V�D�YLUWXDO�OLEUDU\�WKDW�OHWV�\RX�HDVLO\VHDUFK�WKRXVDQGV�RI�WRS�WHFK�ERRNV��FXW�DQG�SDVWH�FRGH�VDPSOHV��GRZQORDG�FKDSWHUV�DQG�ILQG�TXLFN�DQVZHUV�ZKHQ�\RX�QHHG�WKH�PRVW�DFFXUDWH��FXUUHQW�LQIRUPDWLRQ��7U\�LWIRU�IUHH�DW�KWWS���VDIDUL�RUHLOO\�FRP�

Preface | xiii

History of This Book)RU�WKH�FXULRXV��KHUH¦V�KRZ�5DQGDO�WHOOV�WKH�VWRU\�RI�KRZ�WKLV�ERRN�FDPH�DERXW�

$IWHU�,�KDG�ILQLVKHG�WKH�ILUVW�3URJUDPPLQJ�3HUO�ERRN�ZLWK�/DUU\�:DOO��LQ��������,�ZDVDSSURDFKHG�E\�7DRV�0RXQWDLQ�6RIWZDUH�LQ�6LOLFRQ�9DOOH\�WR�SURGXFH�D�WUDLQLQJ�FRXUVH�7KLV�LQFOXGHG�KDYLQJ�PH�GHOLYHU�WKH�ILUVW�GR]HQ�RU�VR�FRXUVHV�DQG�WUDLQ�WKHLU�VWDII�WRFRQWLQXH�RIIHULQJ�WKH�FRXUVH��,�ZURWH�WKH�FRXUVH�IRU�WKHP �DQG�GHOLYHUHG�LW�DV�SURPLVHG�

2Q�WKH�WKLUG�RU�IRXUWK�GHOLYHU\�RI�WKDW�FRXUVH��LQ�ODWH��������VRPHRQH�FDPH�XS�WR�PHDQG�VDLG��£<RX�NQRZ��,�UHDOO\�OLNH�3URJUDPPLQJ�3HUO��EXW�WKH�ZD\�WKH�PDWHULDO�LV�SUH�VHQWHG�LQ�WKLV�FRXUVH�LV�VR�PXFK�HDVLHU�WR�IROORZ¢\RX�RXJKWD�ZULWH�D�ERRN�OLNH�WKLVFRXUVH�¤�,W�VRXQGHG�OLNH�DQ�RSSRUWXQLW\�WR�PH��VR�,�VWDUWHG�WKLQNLQJ�DERXW�LW�

,�ZURWH�WR�7LP�2¦5HLOO\�ZLWK�D�SURSRVDO�EDVHG�RQ�DQ�RXWOLQH�WKDW�ZDV�VLPLODU�WR�WKHFRXUVH�,�ZDV�SUHVHQWLQJ�IRU�7DRV¢DOWKRXJK�,�KDG�UHDUUDQJHG�DQG�PRGLILHG�D�IHZ�RI�WKHFKDSWHUV�EDVHG�RQ�REVHUYDWLRQV�LQ�WKH�FODVVURRP��,�WKLQN�WKDW�ZDV�P\�IDVWHVW�SURSRVDODFFHSWDQFH�LQ�KLVWRU\¢,�JRW�D�PHVVDJH�IURP�7LP�ZLWKLQ����PLQXWHV�VD\LQJ��£:H¦YHEHHQ�ZDLWLQJ�IRU�\RX�WR�SLWFK�D�VHFRQG�ERRN¢3URJUDPPLQJ�3HUO�LV�VHOOLQJ�OLNH�JDQJ�EXVWHUV�¤�7KDW�VWDUWHG�WKH�HIIRUW�RYHU�WKH�QH[W����PRQWKV�WR�ILQLVK�WKH�ILUVW�HGLWLRQ�RI/HDUQLQJ�3HUO�

'XULQJ� WKDW� WLPH�� ,�ZDV�VWDUWLQJ� WR�VHH�DQ�RSSRUWXQLW\� WR� WHDFK�3HUO�FODVVHV�RXWVLGH6LOLFRQ�9DOOH\���VR�,�FUHDWHG�D�FODVV�EDVHG�RQ�WKH�WH[W�,�ZDV�ZULWLQJ�IRU�/HDUQLQJ�3HUO��,JDYH�D�GR]HQ�FODVVHV�IRU�YDULRXV�FOLHQWV��LQFOXGLQJ�P\�SULPDU\�FRQWUDFWRU��,QWHO�2UHJRQ��DQG�XVHG�WKH�IHHGEDFN�WR�ILQH�WXQH�WKH�ERRN�GUDIW�HYHQ�IXUWKHU�

7KH� ILUVW� HGLWLRQ�KLW� WKH� VWUHHWV� RQ� WKH� ILUVW� GD\�RI�1RYHPEHU� ����®� DQG�EHFDPH� DVPDVKLQJ�VXFFHVV��IUHTXHQWO\�HYHQ�RXWSDFLQJ�3URJUDPPLQJ�3HUO�ERRN�VDOHV�

7KH�EDFN�FRYHU�MDFNHW�RI�WKH�ILUVW�ERRN�VDLG�£ZULWWHQ�E\�D�OHDGLQJ�3HUO�WUDLQHU�¤�:HOO�WKDW�EHFDPH�D�VHOI�IXOILOOLQJ�SURSKHV\��:LWKLQ�D�IHZ�PRQWKV��,�ZDV�VWDUWLQJ�WR�JHW�HPDLOIURP�SHRSOH�DOO�RYHU�WKH�8QLWHG�6WDWHV�DVNLQJ�PH�WR�WHDFK�DW�WKHLU�VLWH��,Q�WKH�IROORZLQJVHYHQ�\HDUV��P\�FRPSDQ\�EHFDPH�WKH�OHDGLQJ�ZRUOGZLGH�RQ�VLWH�3HUO�WUDLQLQJ�FRPSDQ\�DQG�,�KDG�SHUVRQDOO\�UDFNHG�XS��OLWHUDOO\��D�PLOOLRQ�IUHTXHQW�IOLHU�PLOHV��,W�GLGQ¦W�KXUWWKDW�WKH�:HE�VWDUWHG�WDNLQJ�RII�DERXW�WKHQ��DQG�WKH�ZHEPDVWHUV�DQG�ZHEPLVWUHVVHVSLFNHG�3HUO�DV� WKH� ODQJXDJH�RI�FKRLFH� IRU�FRQWHQW�PDQDJHPHQW�� LQWHUDFWLRQ�WKURXJK&*,��DQG�PDLQWHQDQFH�

,Q�WKH�FRQWUDFW��,�UHWDLQHG�WKH�ULJKWV�WR�WKH�H[HUFLVHV��KRSLQJ�VRPHGD\�WR�UHXVH�WKHP�LQ�VRPH�RWKHU�ZD\��OLNHLQ�WKH�PDJD]LQH�FROXPQV�,�ZDV�ZULWLQJ�DW�WKH�WLPH��7KH�H[HUFLVHV�DUH�WKH�RQO\�WKLQJV�WKDW�OHDSW�IURP�WKH�7DRVFRXUVH�WR�WKH�ERRN�

� 0\�7DRV�FRQWUDFW�KDG�D�QR�FRPSHWH�FODXVH��VR�,�KDG�WR�VWD\�RXW�RI�6LOLFRQ�9DOOH\�ZLWK�DQ\�VLPLODU�FRXUVHV�ZKLFK�,�UHVSHFWHG�IRU�PDQ\�\HDUV�

® ,�UHPHPEHU�WKDW�GDWH�YHU\�ZHOO�EHFDXVH�LW�ZDV�DOVR�WKH�GD\�,�ZDV�DUUHVWHG�DW�P\�KRPH�IRU�FRPSXWHU�UHODWHG�DFWLYLWLHV�DURXQG�P\�,QWHO�FRQWUDFW��D�VHULHV�RI�IHORQ\�FKDUJHV�IRU�ZKLFK�,�ZDV�ODWHU�FRQYLFWHG�

xiv | Preface

)RU�WZR�\HDUV��,�ZRUNHG�FORVHO\�ZLWK�7RP�3KRHQL[�LQ�KLV�UROH�DV�OHDG�WUDLQHU�DQG�FRQWHQWPDQDJHU�IRU�6WRQHKHQJH��JLYLQJ�KLP�FKDUWHU�WR�H[SHULPHQW�ZLWK�WKH�£/ODPD¤�FRXUVH�E\PRYLQJ�WKLQJV�DURXQG�DQG�EUHDNLQJ�WKLQJV�XS��:KHQ�ZH�KDG�FRPH�XS�ZLWK�ZKDW�ZHWKRXJKW�ZDV�WKH�EHVW�PDMRU�UHYLVLRQ�RI�WKH�FRXUVH��,�FRQWDFWHG�2¦5HLOO\�DQG�VDLG��£,W¦VWLPH�IRU�D�QHZ�ERRN�¤�$QG�WKDW�EHFDPH�WKH�WKLUG�HGLWLRQ�

7ZR�\HDUV�DIWHU�ZULWLQJ�WKH�WKLUG�HGLWLRQ�RI�WKH�/ODPD��7RP�DQG�,�GHFLGHG�LW�ZDV�WLPHWR�SXVK�RXU� IROORZ�RQ�£DGYDQFHG¤�FRXUVH�RXW� LQWR� WKH�ZRUOG�DV�D�ERRN�� IRU�SHRSOHZULWLQJ�SURJUDPV�WKDW�DUH�£����WR��������OLQHV�RI�FRGH�¤�$QG�WRJHWKHU�ZH�FUHDWHG�WKHILUVW�$OSDFD�ERRN��UHOHDVHG�LQ������

%XW�IHOORZ�LQVWUXFWRU�EULDQ�G�IR\�ZDV�MXVW�JHWWLQJ�EDFN�IURP�WKH�FRQIOLFW�LQ�WKH�*XOI��DQGKDG�QRWLFHG�WKDW�ZH�FRXOG�XVH�VRPH�UHZULWLQJ�LQ�ERWK�ERRNV�EHFDXVH�RXU�FRXUVHZDUHVWLOO�QHHGHG�WR�WUDFN�WKH�FKDQJLQJ�QHHGV�RI�WKH�W\SLFDO�VWXGHQW��6R��KH�SLWFKHG�WKH�LGHDWR�2¦5HLOO\�WR�WDNH�RQ�UHZULWLQJ�ERWK�WKH�/ODPD�DQG�WKH�$OSDFD�RQH�ILQDO�WLPH�EHIRUH3HUO����ZH�KRSH���7KLV�ILIWK�HGLWLRQ�RI�WKH�/ODPD�UHIOHFWV�WKRVH�FKDQJHV��EULDQ�ZDV�UHDOO\WKH�OHDG�ZULWHU��ZRUNLQJ�ZLWK�P\�RFFDVLRQDO�JXLGDQFH��DQG�KDV�GRQH�D�EULOOLDQW�MRE�RIWKH�XVXDO�£KHUGLQJ�FDWV¤�WKDW�D�PXOWLSOH�ZULWHU�WHDP�JHQHUDOO\�IHHOV�OLNH�

2Q�'HFHPEHU�����������WKH�SHUO�SRUWHUV�UHOHDVHG�3HUO�������D�VLJQLILFDQW�QHZ�YHUVLRQRI� 3HUO� ZLWK� VHYHUDO� QHZ� IHDWXUHV�� 7KH� SUHYLRXV� YHUVLRQ�� ����� KDG� IRFXVHG� RQ� WKHXQGHUSLQQLQJV�RI�3HUO�DQG�LWV�8QLFRGH�VXSSRUW��7KH�ODWHVW�YHUVLRQ��VWDUWLQJ�IURP�WKHVWDEOH�����IRXQGDWLRQ��ZDV�DEOH�WR�DGG�FRPSOHWHO\�QHZ�IHDWXUHV��VRPH�RI�ZKLFK�LW�ERU�URZHG�IURP�WKH�GHYHORSPHQW�RI�3HUO����QRW�\HW�UHOHDVHG���6RPH�RI�WKHVH�IHDWXUHV��VXFKDV�QDPHG�FDSWXUHV�LQ�UHJXODU�H[SUHVVLRQV��DUH�PXFK�EHWWHU�WKDQ�WKH�ROG�ZD\V�RI�GRLQJWKLQJV��WKXV�SHUIHFW�IRU�3HUO�EHJLQQHUV��:H�KDGQ¦W�WKRXJKW�DERXW�D�ILIWK�HGLWLRQ�RI�WKLVERRN��EXW�3HUO������ZDV�VR�PXFK�EHWWHU�WKDW�ZH�FRXOGQ¦W�UHVLVW�

6RPH�RI�WKH�GLIIHUHQFHV�\RX�PD\�QRWLFH�IURP�SULRU�HGLWLRQV�

� 7KH�WH[W�LV�XSGDWHG�IRU�WKH�ODWHVW�YHUVLRQ��3HUO�������DQG�VRPH�RI�WKH�FRGH�RQO\ZRUNV�ZLWK�WKDW�YHUVLRQ��:H�QRWH�LQ�WKH�WH[W�ZKHQ�ZH�DUH�WDONLQJ�DERXW�D�3HUO�����IHDWXUH��DQG�ZH�PDUN�WKRVH�FRGH�VHFWLRQV�ZLWK�D�VSHFLDO�use�VWDWHPHQW�WKDW�HQVXUHV\RX¦UH�XVLQJ�WKH�ULJKW�YHUVLRQ�

use 5.010; # this script requires Perl 5.10 or greater

,I�\RX�GRQ¦W�VHH�WKDW�use 5.010�LQ�D�FRGH�H[DPSOH��LW�VKRXOG�ZRUN�DOO�WKH�ZD\�EDFNWR�3HUO������7R�VHH�ZKLFK�YHUVLRQ�RI�3HUO�\RX�KDYH��WU\�WKH�-v�FRPPDQG�OLQH�VZLWFK�

prompt% perl -v

+HUH�DUH�VRPH�RI�WKH�QHZ�IHDWXUHV�IURP�3HUO������WKDW�ZH�FRYHU��DQG�ZKHUH�DSSURSULDWH�ZH�VWLOO�VKRZ�\RX�WKH�ROG�ZD\V�RI�GRLQJ�WKH�VDPH�WKLQJ�

� 7KHUH�LV�PRUH�LQIRUPDWLRQ�LQ�WKH�UHJXODU�H[SUHVVLRQ�FKDSWHUV��FRYHULQJ�WKH�QHZIHDWXUHV�IURP�3HUO�������7KHVH�LQFOXGH�UHODWLYH�EDFN�UHIHUHQFHV��&KDSWHU�����QHZFKDUDFWHU�FODVVHV��&KDSWHU�����DQG�QDPHG�FDSWXUHV��&KDSWHU����

Preface | xv

� 3HUO������LQFOXGHV�D�VZLWFK�VWDWHPHQW��ZKLFK�LW�FDOOV�given-when��:H�FRYHU� LW� LQ&KDSWHU����DORQJ�ZLWK�WKH�VPDUW�PDWFK�RSHUDWRU�

� 6XEURXWLQHV�QRZ�KDYH�VWDWLF�YDULDEOHV�MXVW�OLNH�&�GRHV��DOWKRXJK�3HUO�FDOOV�WKHPstate� YDULDEOHV�� 7KH\� SHUVLVW� EHWZHHQ� FDOOV� WR� WKH� VXEURXWLQH� DQG� DUH� OH[LFDOO\VFRSHG��:H�FRYHU�WKDW�LQ�&KDSWHU���

Acknowledgments)URP�5DQGDO��,�ZDQW�WR�WKDQN�WKH�6WRQHKHQJH�WUDLQHUV�SDVW�DQG�SUHVHQW��-RVHSK�+DOO�7RP�3KRHQL[��&KLS�6DO]HQEHUJ��EULDQ�G�IR\��DQG�7DG�0F&OHOODQ��IRU�WKHLU�ZLOOLQJQHVVWR�JR�RXW�DQG�WHDFK�LQ�IURQW�RI�FODVVURRPV�ZHHN�DIWHU�ZHHN�DQG�WR�FRPH�EDFN�ZLWK�WKHLUQRWHV�DERXW�ZKDW¦V�ZRUNLQJ��DQG�ZKDW¦V�QRW���VR�ZH�FRXOG�ILQH�WXQH�WKH�PDWHULDO�IRUWKLV�ERRN��,�HVSHFLDOO\�ZDQW�WR�VLQJOH�RXW�P\�FRDXWKRU�DQG�EXVLQHVV�DVVRFLDWH��7RP3KRHQL[��IRU�KDYLQJ�VSHQW�PDQ\��PDQ\�KRXUV�ZRUNLQJ�WR�LPSURYH�6WRQHKHQJH¦V�/ODPDFRXUVH�DQG�WR�SURYLGH�WKH�ZRQGHUIXO�FRUH�WH[W�IRU�PRVW�RI�WKLV�ERRN��$QG�EULDQ�G�IR\IRU�EHLQJ�WKH�OHDG�ZULWHU�RI�WKH�IRXUWK�HGLWLRQ��LQFOXGLQJ�WDNLQJ�WKDW�HWHUQDO�WR�GR�LWHPRXW�RI�P\�LQER[�VR�WKDW�LW�ZRXOG�ILQDOO\�KDSSHQ�

,�DOVR�ZDQW�WR�WKDQN�HYHU\RQH�DW�2¦5HLOO\��HVSHFLDOO\�RXU�YHU\�SDWLHQW�HGLWRU�DQG�RYHUVHHURQ�WKH�SUHYLRXV�HGLWLRQ��$OOLVRQ�5DQGDO��QR�UHODWLRQ��EXW�VKH�KDV�D�QLFHO\�VSHOOHG�ODVWQDPH���DQG�7LP�2¦5HLOO\�KLPVHOI�IRU�WDNLQJ�D�FKDQFH�RQ�PH�LQ�WKH�ILUVW�SODFH�ZLWK�WKH&DPHO�DQG�/ODPD�ERRNV�

,�DP�DOVR�DEVROXWHO\�LQGHEWHG�WR�WKH�WKRXVDQGV�RI�SHRSOH�ZKR�KDYH�SXUFKDVHG�WKH�SDVWHGLWLRQV�RI�WKH�/ODPD�VR�WKDW�,�FRXOG�XVH�WKH�PRQH\�WR�VWD\�£RII�WKH�VWUHHWV�DQG�RXW�RIMDLO�¤�DQG�WR�WKRVH�VWXGHQWV�LQ�P\�FODVVURRPV�ZKR�KDYH�WUDLQHG�PH�WR�EH�D�EHWWHU�WUDLQHU�DQG�WR�WKH�VWXQQLQJ�DUUD\�RI�)RUWXQH������FOLHQWV�ZKR�KDYH�SXUFKDVHG�RXU�FODVVHV�LQWKH�SDVW�DQG�ZLOO�FRQWLQXH�WR�GR�VR�LQWR�WKH�IXWXUH�

$V�DOZD\V��D�VSHFLDO�WKDQNV�WR�/\OH�DQG�-DFN��IRU�WHDFKLQJ�PH�QHDUO\�HYHU\WKLQJ�,�NQRZDERXW�ZULWLQJ��,�ZRQ¦W�HYHU�IRUJHW�\RX�JX\V�

)URP�7RP�� ,¦YH�JRW�WR�HFKR�5DQGDO¦V�WKDQNV�WR�HYHU\RQH�DW�2¦5HLOO\��)RU�WKH�WKLUGHGLWLRQ�RI�WKLV�ERRN��/LQGD�0XL�ZDV�RXU�HGLWRU��DQG�,�VWLOO�WKDQN�KHU��IRU�KHU�SDWLHQFHLQ�SRLQWLQJ�RXW�ZKLFK�MRNHV�DQG�IRRWQRWHV�ZHUH�PRVW�H[FHVVLYH��VKH�LV�LQ�QR�ZD\�WREODPH�IRU�WKH�RQHV�WKDW�UHPDLQ���%RWK�VKH�DQG�5DQGDO�KDYH�JXLGHG�PH�WKURXJK�WKHZULWLQJ�SURFHVV��DQG�,�DP�JUDWHIXO��2Q�WKH�IRXUWK�HGLWLRQ��$OOLVRQ�5DQGDO�VWHSSHG�LQ�DVHGLWRU��DQG�P\�WKDQNV�JR�WR�KHU�DV�ZHOO�

,�DOVR�HFKR�5DQGDO�ZLWK�UHJDUG�WR�WKH�RWKHU�6WRQHKHQJH�WUDLQHUV��ZKR�KDUGO\�HYHU�FRP�SODLQHG�ZKHQ�,�XQH[SHFWHGO\�XSGDWHG�WKH�FRXUVH�PDWHULDOV�WR�WU\�RXW�D�QHZ�WHDFKLQJWHFKQLTXH��<RX�IRONV�KDYH�FRQWULEXWHG�PDQ\�GLIIHUHQW�YLHZSRLQWV�RQ�WHDFKLQJ�PHWKRGVWKDW�,�ZRXOG�QHYHU�KDYH�VHHQ�

xvi | Preface

)RU�PDQ\�\HDUV��,�ZRUNHG�DW�WKH�2UHJRQ�0XVHXP�RI�6FLHQFH�DQG�,QGXVWU\��206,���DQG,¦G�OLNH�WR�WKDQN�WKH�IRONV�WKHUH�IRU�OHWWLQJ�PH�KRQH�P\�WHDFKLQJ�VNLOOV�DV�,�OHDUQHG�WREXLOG�D�MRNH�RU�WZR�LQWR�HYHU\�DFWLYLW\��H[SORVLRQ��RU�GLVVHFWLRQ�

7R�WKH�PDQ\�IRONV�RQ�8VHQHW�ZKR�KDYH�JLYHQ�PH�\RXU�DSSUHFLDWLRQ�DQG�HQFRXUDJHPHQWIRU�P\�FRQWULEXWLRQV�WKHUH��WKDQNV��$V�DOZD\V��,�KRSH�WKLV�KHOSV�

$OVR�WR�P\�PDQ\�VWXGHQWV��ZKR�KDYH�VKRZQ�PH�ZLWK�WKHLU�TXHVWLRQV��DQG�EHIXGGOHGORRNV��ZKHQ�,�QHHGHG�WR�WU\�D�QHZ�ZD\�RI�H[SUHVVLQJ�D�FRQFHSW��,�KRSH�WKDW�WKH�SUHVHQWHGLWLRQ�KHOSV�WR�UHOLHYH�DQ\�UHPDLQLQJ�SX]]OHPHQW�

2I�FRXUVH��GHHS�WKDQNV�DUH�GXH�HVSHFLDOO\�WR�P\�FRDXWKRU�5DQGDO�IRU�JLYLQJ�PH�WKHIUHHGRP�WR�WU\�YDULRXV�ZD\V�RI�SUHVHQWLQJ�WKH�PDWHULDO�ERWK�LQ�WKH�FODVVURRP�DQG�KHUHLQ�WKH�ERRN��DV�ZHOO�DV�IRU�WKH�SXVK�WR�PDNH�WKLV�PDWHULDO�LQWR�D�ERRN�LQ�WKH�ILUVW�SODFH�$QG�ZLWKRXW�IDLO��,�PXVW�VD\�WKDW�,�DP�LQGHHG�LQVSLUHG�E\�\RXU�RQJRLQJ�ZRUN�WR�HQVXUHWKDW�QR�RQH�HOVH�EHFRPHV�HQVQDUHG�E\�WKH�OHJDO�WURXEOHV�WKDW�KDYH�VWROHQ�VR�PXFK�RI\RXU�WLPH�DQG�HQHUJ\��\RX¦UH�D�ILQH�H[DPSOH�

7R�P\�ZLIH��-HQQD��WKDQNV�IRU�EHLQJ�D�FDW�SHUVRQ��DQG�HYHU\WKLQJ�WKHUHDIWHU�

)URP�EULDQ��,�KDYH�WR�WKDQN�5DQGDO�ILUVW��VLQFH�,�OHDUQHG�3HUO�IURP�WKH�ILUVW�HGLWLRQ�RIWKLV�ERRN��DQG�WKHQ�KDG�WR�OHDUQ�LW�DJDLQ�ZKHQ�KH�DVNHG�PH�WR�VWDUW�WHDFKLQJ�IRU�6WRQH�KHQJH�LQ�������7HDFKLQJ�LV�RIWHQ�WKH�EHVW�ZD\�WR�OHDUQ��6LQFH�WKHQ�5DQGDO�KDV�PHQWRUHGPH�QRW�RQO\�LQ�3HUO��EXW�LQ�VHYHUDO�RWKHU�WKLQJV�KH�WKRXJKW�,�QHHGHG�WR�OHDUQ��OLNH�WKHWLPH�KH�GHFLGHG�WKDW�ZH�FRXOG�XVH�6PDOOWDON�LQVWHDG�RI�3HUO�IRU�D�GHPRQVWUDWLRQ�DW�DZHE�FRQIHUHQFH��,¦P�DOZD\V�DPD]HG�DW�WKH�EUHDGWK�RI�KLV�NQRZOHGJH��+H¦V�WKH�RQH�ZKRWROG�PH�WR�VWDUW�ZULWLQJ�DERXW�3HUO��1RZ�,¦P�KHOSLQJ�RXW�RQ�WKH�ERRN�ZKHUH�,�VWDUWHG�,¦P�KRQRUHG��5DQGDO�

,¦YH�SUREDEO\�RQO\�DFWXDOO\�VHHQ�7RP�3KRHQL[�IRU�OHVV�WKDQ�WZR�ZHHNV�LQ�WKH�HQWLUH�WLPH,¦YH�ZRUNHG�IRU�6WRQHKHQJH��EXW�,¦YH�EHHQ�WHDFKLQJ�KLV�YHUVLRQ�RI�RXU�/HDUQLQJ�3HUOFRXUVH�IRU�\HDUV��7KDW�YHUVLRQ�WXUQHG�LQWR�WKH�WKLUG�HGLWLRQ�RI�WKLV�ERRN��7HDFKLQJ�7RP¦VQHZ�YHUVLRQ��,�IRXQG�QHZ�ZD\V�WR�H[SODLQ�DOPRVW�HYHU\WKLQJ��DQG�OHDUQHG�HYHQ�PRUHFRUQHUV�RI�3HUO�

:KHQ�,�FRQYLQFHG�5DQGDO�WKDW�,�VKRXOG�KHOS�RXW�RQ�WKH�/ODPD�XSGDWH��,�ZDV�DQRLQWHGDV�WKH�PDNHU�RI�WKH�SURSRVDO�WR�WKH�SXEOLVKHU��WKH�NHHSHU�RI�WKH�RXWOLQH��DQG�WKH�YHUVLRQFRQWURO�ZUDQJOHU��2XU�HGLWRU�RQ�WKH�IRXUWK�HGLWLRQ��$OOLVRQ�5DQGDO��KHOSHG�PH�JHW�VHWXS�LQ�DOO�RI�WKRVH�UROHV�DQG�HQGXUHG�P\�IUHTXHQW�HPDLOV�ZLWKRXW�FRPSODLQLQJ�

6SHFLDO�QRQ�3HUO�WKDQNV�WR�6WDFH\��%XVWHU��0LPL��5RVFRH��$PHOLD��/LOD��DQG�HYHU\RQHHOVH�ZKR�WULHG� WR�GLVWUDFW�PH�ZKLOH� ,�ZDV�EXV\�EXW�VWLOO� WDONHG�WR�PH�HYHQ�WKRXJK�,FRXOGQ¦W�FRPH�RXW�WR�SOD\�

)URP�$OO�RI�8V��7KDQNV�WR�RXU�UHYLHZHUV�'DYLG�+��$GOHU��$QG\�$UPVWURQJ��'DYH�&URVV�&KULV�'HYHUV��3DXO�)HQZLFN��6WHSKHQ�%��-HQNLQV��0DWWKHZ�0XVJURYH��6WHYH�3HWHUV��DQG:LO�:KHDWRQ�IRU�SURYLGLQJ�FRPPHQWV�RQ�WKH�GUDIW�RI�WKLV�ERRN�

Preface | xvii

7KDQNV�DOVR� WR�RXU�PDQ\� VWXGHQWV�ZKR�KDYH� OHW�XV�NQRZ�ZKDW�SDUWV�RI� WKH�FRXUVHPDWHULDO�KDYH�QHHGHG�LPSURYHPHQW�RYHU�WKH�\HDUV��,W¦V�EHFDXVH�RI�\RX�WKDW�ZH¦UH�DOO�VRSURXG�RI�LW�WRGD\�

7KDQNV�WR�WKH�PDQ\�3HUO�0RQJHUV�ZKR�KDYH�PDGH�XV�IHHO�DW�KRPH�DV�ZH¦YH�YLVLWHG�\RXUFLWLHV��/HW¦V�GR�LW�DJDLQ�VRPHWLPH�

$QG�ILQDOO\��RXU�VLQFHUHVW�WKDQNV�WR�RXU�IULHQG�/DUU\�:DOO��IRU�KDYLQJ�WKH�ZLVGRP�WRVKDUH�KLV�UHDOO\�FRRO�DQG�SRZHUIXO�WR\V�ZLWK�WKH�UHVW�RI�WKH�ZRUOG�VR�WKDW�ZH�FDQ�DOO�JHWRXU�ZRUN�GRQH�MXVW�D�OLWWOH�ELW�IDVWHU��HDVLHU��DQG�ZLWK�PRUH�IXQ�

xviii | Preface

CHAPTER 1

Introduction

:HOFRPH�WR�WKH�/ODPD�ERRN�

7KLV�LV�WKH�ILIWK�HGLWLRQ�RI�D�ERRN�WKDW�KDV�EHHQ�HQMR\HG�E\�KDOI�D�PLOOLRQ�UHDGHUV�VLQFH������$W�OHDVW��ZH�KRSH�WKH\¦YH�HQMR\HG�LW��,W¦V�D�VXUH�WKLQJ�WKDW�ZH¦YH�HQMR\HG�ZULWLQJLW�

Questions and Answers<RX�SUREDEO\�KDYH�VRPH�TXHVWLRQV�DERXW�3HUO��DQG�PD\EH�HYHQ�VRPH�DERXW�WKLV�ERRN�HVSHFLDOO\�LI�\RX¦YH�DOUHDG\�IOLSSHG�WKURXJK�LW�WR�VHH�ZKDW¦V�FRPLQJ��6R��ZH¦OO�XVH�WKLVFKDSWHU�WR�DQVZHU�WKHP�

Is This the Right Book for You?,I�\RX¦UH�DQ\WKLQJ�OLNH�XV��\RX¦UH�SUREDEO\�VWDQGLQJ�LQ�D�ERRNVWRUH�ULJKW�QRZ���ZRQ�GHULQJ�ZKHWKHU�\RX�VKRXOG�JHW�WKLV�/ODPD�ERRN�DQG�OHDUQ�3HUO��RU�PD\EH�WKDW�ERRN�RYHUWKHUH�DQG�OHDUQ�VRPH�ODQJXDJH�QDPHG�DIWHU�D�VQDNH��RU�D�EHYHUDJH��RU�D�OHWWHU�RI�WKHDOSKDEHW�®�<RX¦YH�JRW�DERXW�WZR�PLQXWHV�EHIRUH�WKH�ERRNVWRUH�PDQDJHU�FRPHV�RYHU�WRWHOO�\RX�WKDW�WKLV�LVQ¦W�D�OLEUDU\��DQG�\RX�QHHG�WR�EX\�VRPHWKLQJ�RU�JHW�RXW��0D\EH�\RXZDQW�WR�XVH�WKHVH�WZR�PLQXWHV�WR�VHH�D�TXLFN�3HUO�SURJUDP��VR�\RX¦OO�NQRZ�VRPHWKLQJ

7R�EH�VXUH��WKH�ILUVW�HGLWLRQ�ZDV�ZULWWHQ�E\�5DQGDO�/��6FKZDUW]��WKH�VHFRQG�E\�5DQGDO�DQG�7RP�&KULVWLDQVHQ�WKHQ�RQH�E\�5DQGDO�DQG�7RP�3KRHQL[��DQG�QRZ�E\�5DQGDO��7RP�3KRHQL[��DQG�EULDQ�G�IR\��6R��ZKHQHYHU�ZHVD\�£ZH¤�LQ�WKLV�HGLWLRQ��ZH�PHDQ�WKDW�ODVW�JURXS��1RZ��LI�\RX¦UH�ZRQGHULQJ�KRZ�ZH�FDQ�VD\�WKDW�ZH¦YHHQMR\HG�ZULWLQJ�LW��LQ�WKH�SDVW�WHQVH��ZKHQ�ZH¦UH�VWLOO�RQ�WKH�ILUVW�SDJH��WKDW¦V�HDV\��ZH�VWDUWHG�DW�WKH�HQG��DQGZRUNHG�RXU�ZD\�EDFNZDUG��,W�VRXQGV�OLNH�D�VWUDQJH�ZD\�WR�GR�LW��ZH�NQRZ��%XW��KRQHVWO\��RQFH�ZH�ILQLVKHGZULWLQJ�WKH�LQGH[��WKH�UHVW�ZDV�KDUGO\�DQ\�WURXEOH�DW�DOO�

� $FWXDOO\��LI�\RX¦UH�OLNH�XV��\RX¦UH�VWDQGLQJ�LQ�D�OLEUDU\��QRW�D�ERRNVWRUH��%XW�ZH¦UH�WLJKWZDGV�

® %HIRUH� \RX�ZULWH� WR� WHOO� XV� WKDW� LW¦V� D� FRPHG\� WURXSH�� QRW� D� VQDNH��ZH� VKRXOG� UHDOO\� H[SODLQ� WKDW�ZH¦UHG\VOH[LFDOO\�WKLQNLQJ�RI�&25%$�

8QOHVV�LW�LV�

1

DERXW�KRZ�SRZHUIXO�3HUO�LV�DQG�ZKDW�LW�FDQ�GR��,Q�WKDW�FDVH��\RX�VKRXOG�FKHFN�RXW�£$:KLUOZLQG�7RXU�RI�3HUO�¤�ODWHU�LQ�WKLV�FKDSWHU�

Why Are There So Many Footnotes?7KDQN�\RX�IRU�QRWLFLQJ��7KHUH�DUH�D�ORW�RI�IRRWQRWHV�LQ�WKLV�ERRN��,JQRUH�WKHP��7KH\¦UHQHHGHG�EHFDXVH�3HUO�LV�FKRFN�IXOO�RI�H[FHSWLRQV�WR�LWV�UXOHV��7KLV�LV�D�JRRG�WKLQJ��DV�UHDOOLIH�LV�FKRFN�IXOO�RI�H[FHSWLRQV�WR�UXOHV�

%XW�LW�PHDQV�WKDW�ZH�FDQ¦W�KRQHVWO\�VD\��£7KH�IL]]ELQ�RSHUDWRU�IUREQLFDWHV�WKH�KRR]L�VWDWLF�YDULDEOHV¤�ZLWKRXW�D�IRRWQRWH�JLYLQJ�WKH�H[FHSWLRQV� �:H¦UH�SUHWW\�KRQHVW��VR�ZHKDYH�WR�ZULWH�WKH�IRRWQRWHV��%XW�\RX�FDQ�EH�KRQHVW�ZLWKRXW�UHDGLQJ�WKHP���,W¦V�IXQQ\KRZ�WKDW�ZRUNV�RXW��

0DQ\�RI�WKH�H[FHSWLRQV�KDYH�WR�GR�ZLWK�SRUWDELOLW\��3HUO�EHJDQ�RQ�8QL[�V\VWHPV��DQGLW�VWLOO�KDV�GHHS�URRWV�LQ�8QL[��%XW�ZKHUHYHU�SRVVLEOH��ZH¦YH�WULHG�WR�VKRZ�ZKHQ�VRPH�WKLQJ�PD\�EHKDYH�XQH[SHFWHGO\��ZKHWKHU�WKDW¦V�EHFDXVH�LW¦V�UXQQLQJ�RQ�D�QRQ�8QL[V\VWHP��RU�IRU�DQRWKHU�UHDVRQ��:H�KRSH�WKDW�UHDGHUV�ZKR�NQRZ�QRWKLQJ�DERXW�8QL[ZLOO�QHYHUWKHOHVV�ILQG�WKLV�ERRN�D�JRRG�LQWURGXFWLRQ�WR�3HUO���$QG�WKH\¦OO�OHDUQ�D�OLWWOHDERXW�8QL[�DORQJ�WKH�ZD\��DW�QR�H[WUD�FKDUJH��

$QG�PDQ\�RI�WKH�RWKHU�H[FHSWLRQV�KDYH�WR�GR�ZLWK�WKH�ROG�£�����¤�UXOH��%\�WKDW�ZHPHDQ�WKDW�����RI�WKH�EHKDYLRU�RI�3HUO�FDQ�EH�GHVFULEHG�LQ�����RI�WKH�GRFXPHQWDWLRQ�DQG�WKH�RWKHU�����RI�WKH�EHKDYLRU�WDNHV�XS�WKH�RWKHU�����RI�WKH�GRFXPHQWDWLRQ��6RWR�NHHS�WKLV�ERRN�VPDOO��ZH¦OO�WDON�DERXW�WKH�PRVW�FRPPRQ��HDV\�WR�WDON�DERXW�EHKDYLRULQ�WKH�PDLQ�WH[W��DQG�KLQW�LQ�WKH�GLUHFWLRQ�RI�WKH�RWKHU�VWXII�LQ�WKH�IRRWQRWHV��ZKLFK�DUHLQ�D�VPDOOHU�IRQW��VR�ZH�FDQ�VD\�PRUH�LQ�WKH�VDPH�VSDFH����2QFH�\RX¦YH�UHDG�WKH�ERRNDOO�WKH�ZD\�WKURXJK�ZLWKRXW�UHDGLQJ�WKH�IRRWQRWHV��\RX¦OO�SUREDEO\�ZDQW�WR�ORRN�EDFNDW�VRPH�VHFWLRQV�IRU�UHIHUHQFH��$W�WKDW�SRLQW��RU�LI�\RX�EHFRPH�XQEHDUDEO\�FXULRXV�DORQJWKH�ZD\��JR�DKHDG�DQG�UHDG�WKH�QRWHV��$�ORW�RI�WKHP�DUH�MXVW�FRPSXWHU�MRNHV�DQ\ZD\�

What About the Exercises and Their Answers?7KH�H[HUFLVHV�DUH�DW�WKH�HQG�RI�HDFK�FKDSWHU�EHFDXVH��EHWZHHQ�WKH�WKUHH�RI�XV��ZH¦YHSUHVHQWHG�WKLV�VDPH�FRXUVH�PDWHULDO�WR�VHYHUDO�WKRXVDQG�VWXGHQWV�®�:H�KDYH�FDUHIXOO\FUDIWHG�WKHVH�H[HUFLVHV�WR�JLYH�\RX�WKH�FKDQFH�WR�PDNH�PLVWDNHV�DV�ZHOO�

,W¦V�QRW�WKDW�ZH�ZDQW�\RX�WR�PDNH�PLVWDNHV��EXW�\RX�QHHG�WR�KDYH�WKH�FKDQFH��7KDW¦VEHFDXVH�\RX�DUH�JRLQJ�WR�PDNH�PRVW�RI�WKHVH�PLVWDNHV�GXULQJ�\RXU�3HUO�SURJUDPPLQJ

([FHSW�RQ�7XHVGD\V��GXULQJ�D�SRZHU�RXWDJH��ZKHQ�\RX�KROG�\RXU�HOERZ�DW�D�IXQQ\�DQJOH�GXULQJ�WKH�HTXLQR[�RU�ZKHQ�use integer�LV�LQ�HIIHFW�LQVLGH�D�ORRS�EORFN�EHLQJ�FDOOHG�E\�D�SURWRW\SHG�VXEURXWLQH�SULRU�WR�3HUOYHUVLRQ�����

� :H�HYHQ�GLVFXVVHG�GRLQJ�WKH�HQWLUH�ERRN�DV�D�IRRWQRWH�WR�VDYH�WKH�SDJH�FRXQW��EXW�IRRWQRWHV�RQ�IRRWQRWHVVWDUWHG�WR�JHW�D�ELW�FUD]\�

® 1RW�DOO�DW�RQFH�

2 | Chapter 1:ಗIntroduction

FDUHHU��DQG�LW�PD\�DV�ZHOO�EH�QRZ��$Q\�PLVWDNH�WKDW�\RX�PDNH�ZKLOH�UHDGLQJ�WKLV�ERRN\RX�ZRQ¦W�PDNH�DJDLQ�ZKHQ�\RX¦UH�ZULWLQJ�D�SURJUDP�RQ�D�GHDGOLQH��$QG�ZH¦UH�DOZD\VKHUH�WR�KHOS�\RX�RXW�LI�VRPHWKLQJ�JRHV�ZURQJ��LQ�WKH�IRUP�RI�$SSHQGL[�$��ZKLFK�KDVRXU�DQVZHUV�IRU�HDFK�H[HUFLVH�DQG�D�OLWWOH�WH[W�WR�JR�ZLWK�LW��H[SODLQLQJ�WKH�PLVWDNHV�\RXPDGH�DQG�D�IHZ�\RX�GLGQ¦W��&KHFN�RXW�WKH�DQVZHUV�ZKHQ�\RX¦UH�GRQH�ZLWK�WKH�H[HUFLVHV�

7U\�QRW�WR�SHHN�DW�WKH�DQVZHU�XQWLO�\RX¦YH�JLYHQ�WKH�SUREOHP�D�JRRG�WU\��WKRXJK��<RX¦OOOHDUQ�EHWWHU�LI�\RX�ILJXUH�LW�RXW�UDWKHU�WKDQ�UHDG�DERXW�LW��'RQ¦W�NQRFN�\RXU�KHDG�UH�SHDWHGO\�DJDLQVW�WKH�ZDOO�LI�\RX�GRQ¦W�ILJXUH�RXW�D�VROXWLRQ��PRYH�RQWR�WKH�QH[W�FKDSWHUDQG�GRQ¦W�ZRUU\�WRR�PXFK�DERXW�LW�

(YHQ�LI�\RX�QHYHU�PDNH�DQ\�PLVWDNHV��\RX�VKRXOG�ORRN�DW�WKH�DQVZHUV�ZKHQ�\RX¦UH�GRQH�WKH�DFFRPSDQ\LQJ�WH[W�ZLOO�SRLQW�RXW�VRPH�GHWDLOV�RI�WKH�SURJUDP�WKDW�PLJKW�QRW�EHREYLRXV�DW�ILUVW�

,I� \RX� ZDQW� DGGLWLRQDO� H[HUFLVHV�� FKHFN� RXW� /HDUQLQJ� 3HUO� 6WXGHQW� :RUNERRN�2¦5HLOO\���ZKLFK�DGGV�VHYHUDO�H[HUFLVHV�IRU�HDFK�FKDSWHU�

What Do Those Numbers at the Start of the Exercise Mean?(DFK�H[HUFLVH�KDV�D�QXPEHU�LQ�VTXDUH�EUDFNHWV�LQ�IURQW�RI�WKH�H[HUFLVH�WH[W��ORRNLQJVRPHWKLQJ�OLNH�WKLV�

�� >�@�:KDW�GRHV�WKH�QXPEHU���LQVLGH�VTXDUH�EUDFNHWV�PHDQ�ZKHQ�LW�DSSHDUV�DW�WKHVWDUW�RI�DQ�H[HUFLVH¦V�WH[W"

7KDW�QXPEHU�LV�RXU��YHU\�URXJK��HVWLPDWH�RI�KRZ�PDQ\�PLQXWHV�\RX�FDQ�H[SHFW�WR�VSHQGRQ�WKDW�SDUWLFXODU�H[HUFLVH��,W¦V�URXJK��VR�GRQ¦W�EH�WRR�VXUSULVHG�LI�\RX¦UH�DOO�GRQH��ZLWKZULWLQJ��WHVWLQJ��DQG�GHEXJJLQJ��LQ�KDOI�WKDW�WLPH��RU�QRW�GRQH�LQ�WZLFH�WKDW�ORQJ��2QWKH�RWKHU�KDQG��LI�\RX¦UH�UHDOO\�VWXFN��ZH�ZRQ¦W�WHOO�DQ\RQH�WKDW�\RX�SHHNHG�DW�$SSHQ�GL[�$�WR�VHH�ZKDW�RXU�DQVZHU�ORRNHG�OLNH�

What If I’m a Perl Course Instructor?,I�\RX¦UH�D�3HUO�LQVWUXFWRU�ZKR�KDV�GHFLGHG�WR�XVH�WKLV�DV�\RXU�WH[WERRN��DV�PDQ\�KDYHRYHU�WKH�\HDUV���\RX�VKRXOG�NQRZ�WKDW�ZH¦YH�WULHG�WR�PDNH�HDFK�VHW�RI�H[HUFLVHV�VKRUWHQRXJK�WKDW�PRVW�VWXGHQWV�FRXOG�GR�WKH�ZKROH�VHW�LQ����PLQXWHV�WR�DQ�KRXU��ZLWK�DOLWWOH�WLPH�OHIW�RYHU�IRU�D�EUHDN��6RPH�FKDSWHUV¦�H[HUFLVHV�VKRXOG�EH�TXLFNHU�DQG�VRPHORQJHU��7KDW¦V�EHFDXVH�RQFH�ZH�KDG�ZULWWHQ�DOO�RI�WKRVH�OLWWOH�QXPEHUV�LQ�VTXDUH�EUDFN�HWV��ZH�GLVFRYHUHG�WKDW�ZH�GRQ¦W�NQRZ�KRZ�WR�DGG��OXFNLO\�ZH�NQRZ�KRZ�WR�PDNHFRPSXWHUV�GR�LW�IRU�XV��

$V�ZH�PHQWLRQHG��ZH�DOVR�KDYH�D�FRPSDQLRQ�ERRN��/HDUQLQJ�3HUO�6WXGHQW�:RUNERRN�ZKLFK�KDV�DGGLWLRQDO�H[HUFLVHV�IRU�HDFK�FKDSWHU��,I�\RX�JHW�WKH�YHUVLRQ�RI�WKH�ZRUNERRNIRU�WKH�IRXUWK�HGLWLRQ��\RX�ZLOO�KDYH�WR�DGMXVW�WKH�FKDSWHU�RUGHU�EHFDXVH�ZH�DGGHG�DFKDSWHU�DQG�PRYHG�DQRWKHU�FKDSWHU�LQ�WKLV�HGLWLRQ�

Questions and Answers | 3

What Does “Perl” Stand For?3HUO�LV�VRPHWLPHV�FDOOHG�WKH�£3UDFWLFDO�([WUDFWLRQ�DQG�5HSRUW�/DQJXDJH�¤�DOWKRXJK�LWKDV�DOVR�EHHQ�FDOOHG�D�£3DWKRORJLFDOO\�(FOHFWLF�5XEELVK�/LVWHU�¤�DPRQJ�RWKHU�H[SDQ�VLRQV��,W¦V�DFWXDOO\�D�EDFNURQ\P��QRW�DQ�DFURQ\P��VLQFH�/DUU\�:DOO¢3HUO¦V�FUHDWRU¢FDPH�XS�ZLWK�WKH�QDPH�ILUVW�DQG�WKH�H[SDQVLRQ�ODWHU��7KDW¦V�ZK\�£3HUO¤�LVQ¦W�LQ�DOO�FDSV�7KHUH¦V�QR�SRLQW�LQ�DUJXLQJ�ZKLFK�H[SDQVLRQ�LV�FRUUHFW��/DUU\�HQGRUVHV�ERWK�

<RX�PD\�DOVR�VHH�£SHUO¤�ZLWK�D�ORZHUFDVH�S�LQ�VRPH�ZULWLQJ��,Q�JHQHUDO��£3HUO¤�ZLWK�DFDSLWDO�3�UHIHUV�WR�WKH�ODQJXDJH�DQG�£SHUO¤�ZLWK�D�ORZHUFDVH�S�UHIHUV�WR�WKH�DFWXDO�LQWHU�SUHWHU�WKDW�FRPSLOHV�DQG�UXQV�\RXU�SURJUDPV�

Why Did Larry Create Perl?/DUU\�FUHDWHG�3HUO�LQ�WKH�PLG�����V�ZKHQ�KH�ZDV�WU\LQJ�WR�SURGXFH�VRPH�UHSRUWV�IURPD�8VHQHW�QHZV¡OLNH�KLHUDUFK\�RI�ILOHV�IRU�D�EXJ�UHSRUWLQJ�V\VWHP��DQG�DZN�UDQ�RXW�RIVWHDP��/DUU\��EHLQJ�WKH�OD]\�SURJUDPPHU�WKDW�KH�LV� �GHFLGHG�WR�RYHUNLOO�WKH�SUREOHPZLWK�D�JHQHUDO�SXUSRVH�WRRO�WKDW�KH�FRXOG�XVH�LQ�DW�OHDVW�RQH�RWKHU�SODFH��7KH�UHVXOW�ZDV3HUO�YHUVLRQ�]HUR�

Why Didn’t Larry Just Use Some Other Language?7KHUH¦V�QR�VKRUWDJH�RI�FRPSXWHU�ODQJXDJHV��LV�WKHUH"�%XW��DW�WKH�WLPH��/DUU\�GLGQ¦W�VHHDQ\WKLQJ�WKDW�UHDOO\�PHW�KLV�QHHGV��,I�RQH�RI�WKH�RWKHU� ODQJXDJHV�RI�WRGD\�KDG�EHHQDYDLODEOH�EDFN�WKHQ��SHUKDSV�/DUU\�ZRXOG�KDYH�XVHG�RQH�RI�WKRVH��+H�QHHGHG�VRPHWKLQJZLWK�WKH�TXLFNQHVV�RI�FRGLQJ�DYDLODEOH�LQ�VKHOO�RU�DZN�SURJUDPPLQJ��DQG�ZLWK�VRPH�RIWKH�SRZHU�RI�PRUH�DGYDQFHG�WRROV�OLNH�JUHS��FXW��VRUW��DQG�VHG���ZLWKRXW�KDYLQJ�WR�UHVRUWWR�D�ODQJXDJH�OLNH�&�

3HUO��� WULHV� WR� ILOO� WKH�JDS�EHWZHHQ� ORZ�OHYHO�SURJUDPPLQJ��VXFK�DV� LQ�&�RU�&���RUDVVHPEO\��DQG�KLJK�OHYHO�SURJUDPPLQJ��VXFK�DV�£VKHOO¤�SURJUDPPLQJ���/RZ�OHYHO�SUR�JUDPPLQJ�LV�XVXDOO\�KDUG�WR�ZULWH�DQG�XJO\��EXW�IDVW�DQG�XQOLPLWHG��LW¦V�KDUG�WR�EHDW�WKHVSHHG�RI�D�ZHOO�ZULWWHQ�ORZ�OHYHO�SURJUDP�RQ�D�JLYHQ�PDFKLQH��$QG�WKHUH¦V�QRW�PXFK\RX�FDQ¦W�GR�WKHUH��+LJK�OHYHO�SURJUDPPLQJ��DW�WKH�RWKHU�H[WUHPH��WHQGV�WR�EH�VORZ�KDUG��XJO\��DQG�OLPLWHG��WKHUH�DUH�PDQ\�WKLQJV�\RX�FDQ¦W�GR�DW�DOO�ZLWK�WKH�VKHOO�RU�EDWFKSURJUDPPLQJ�LI�WKHUH¦V�QR�FRPPDQG�RQ�\RXU�V\VWHP�WKDW�SURYLGHV�WKH�QHHGHG�IXQF�WLRQDOLW\��3HUO�LV�HDV\��QHDUO\�XQOLPLWHG��PRVWO\�IDVW��DQG�NLQG�RI�XJO\�

/HW¦V�WDNH�DQRWKHU�ORRN�DW�WKRVH�IRXU�FODLPV�ZH�MXVW�PDGH�DERXW�3HUO�

:H¦UH�QRW�LQVXOWLQJ�/DUU\�E\�VD\LQJ�KH¦V�OD]\��OD]LQHVV�LV�D�YLUWXH��7KH�ZKHHOEDUURZ�ZDV�LQYHQWHG�E\�VRPHRQHZKR�ZDV�WRR�OD]\�WR�FDUU\�WKLQJV��ZULWLQJ�ZDV�LQYHQWHG�E\�VRPHRQH�ZKR�ZDV�WRR�OD]\�WR�PHPRUL]H��3HUO�ZDVLQYHQWHG�E\�VRPHRQH�ZKR�ZDV�WRR�OD]\�WR�JHW�WKH�MRE�GRQH�ZLWKRXW�LQYHQWLQJ�D�ZKROH�QHZ�FRPSXWHU�ODQJXDJH�

� 'RQ¦W�ZRUU\�LI�\RX�GRQ¦W�NQRZ�ZKDW�WKHVH�DUH��$OO�WKDW�PDWWHUV�LV�WKDW�WKH\�ZHUH�WKH�SURJUDPV�/DUU\�KDG�LQKLV�8QL[�WRROER[��EXW�WKH\�ZHUHQ¦W�XS�WR�WKH�WDVNV�DW�KDQG�

4 | Chapter 1:ಗIntroduction

)LUVW��3HUO�LV�HDV\��$V�\RX¦OO�VHH��WKRXJK��WKLV�PHDQV�LW¦V�HDV\�WR�XVH��,W¦V�QRW�HVSHFLDOO\HDV\�WR�OHDUQ��,I�\RX�GULYH�D�FDU��\RX�VSHQW�PDQ\�ZHHNV�RU�PRQWKV�OHDUQLQJ�KRZ��DQGWKHQ�LW¦V�HDV\�WR�GULYH��:KHQ�\RX¦YH�EHHQ�SURJUDPPLQJ�3HUO�IRU�DERXW�DV�PDQ\�KRXUVDV�LW�WRRN�\RX�WR�OHDUQ�WR�GULYH��3HUO�ZLOO�EH�HDV\�IRU�\RX�

3HUO�LV�QHDUO\�XQOLPLWHG��7KHUH�DUH�YHU\�IHZ�WKLQJV�\RX�FDQ¦W�GR�ZLWK�3HUO��<RX�ZRXOGQ¦WZDQW�WR�ZULWH�D�LQWHUUXSW�PLFURNHUQHO�OHYHO�GHYLFH�GULYHU�LQ�3HUO��HYHQ�WKRXJK�WKDW¦VEHHQ�GRQH���EXW�PRVW�WKLQJV�WKDW�RUGLQDU\�IRONV�QHHG�PRVW�RI�WKH�WLPH�DUH�JRRG�WDVNVIRU�3HUO��IURP�TXLFN�OLWWOH�RQH�RII�SURJUDPV�WR�PDMRU�LQGXVWULDO�VWUHQJWK�DSSOLFDWLRQV�

3HUO�LV�PRVWO\�IDVW��7KDW¦V�EHFDXVH�QRERG\�LV�GHYHORSLQJ�3HUO�ZKR�GRHVQ¦W�DOVR�XVH�LW¢VR�ZH�DOO�ZDQW�LW�WR�EH�IDVW��,I�VRPHRQH�ZDQWV�WR�DGG�D�IHDWXUH�WKDW�ZRXOG�EH�UHDOO\�FRRO�EXW�WKDW�ZRXOG�VORZ�GRZQ�RWKHU�SURJUDPV��/DUU\�LV�DOPRVW�FHUWDLQ�WR�UHIXVH�WKH�QHZIHDWXUH�XQWLO�ZH�ILQG�D�ZD\�WR�PDNH�LW�TXLFN�HQRXJK�

3HUO�LV�NLQG�RI�XJO\��7KLV�LV�WUXH��7KH�V\PERO�RI�3HUO�KDV�EHFRPH�WKH�FDPHO��IURP�WKHFRYHU�RI�WKH�YHQHUDEOH�&DPHO�ERRN��DOVR�NQRZQ�DV�3URJUDPPLQJ�3HUO�E\�/DUU\�:DOO�7RP�&KULVWLDQVHQ��DQG�-RQ�2UZDQW�>2¦5HLOO\@���D�FRXVLQ�RI�WKLV�/ODPD��DQG�KHU�VLVWHU�WKH�$OSDFD���&DPHOV�DUH�NLQG�RI�XJO\��WRR��%XW�WKH\�ZRUN�KDUG��HYHQ�LQ�WRXJK�FRQGLWLRQV�&DPHOV�DUH�WKHUH�WR�JHW�WKH�MRE�GRQH�GHVSLWH�DOO�GLIILFXOWLHV��HYHQ�ZKHQ�WKH\�ORRN�EDGDQG�VPHOO�ZRUVH�DQG�VRPHWLPHV�VSLW�DW�\RX��3HUO�LV�D�OLWWOH�OLNH�WKDW�

Is Perl Easy or Hard?3HUO�LV�HDV\�WR�XVH��EXW�VRPHWLPHV�KDUG�WR�OHDUQ��7KLV�LV�D�JHQHUDOL]DWLRQ��RI�FRXUVH��,QGHVLJQLQJ�3HUO��/DUU\�PDGH�PDQ\�WUDGHRIIV��:KHQ�KH¦V�KDG�WKH�FKDQFH�WR�PDNH�VRPH�WKLQJ�HDVLHU�IRU�WKH�SURJUDPPHU�DW�WKH�H[SHQVH�RI�EHLQJ�PRUH�GLIILFXOW�IRU�WKH�VWXGHQW�KH¦V�GHFLGHG�LQ�WKH�SURJUDPPHU¦V�IDYRU�QHDUO\�HYHU\�WLPH��7KDW¦V�EHFDXVH�\RX¦OO�OHDUQ3HUO�RQO\�RQFH��EXW�\RX¦OO�XVH�LW�DJDLQ�DQG�DJDLQ� �3HUO�KDV�DQ\�QXPEHU�RI�FRQYHQLHQFHVWKDW�OHW�WKH�SURJUDPPHU�VDYH�WLPH��)RU�H[DPSOH��PRVW�IXQFWLRQV�ZLOO�KDYH�D�GHIDXOW�IUHTXHQWO\��WKH�GHIDXOW�LV�WKH�ZD\�WKDW�\RX¦OO�ZDQW�WR�XVH�WKH�IXQFWLRQ��6R�\RX¦OO�VHH�OLQHVRI�3HUO�FRGH�OLNH�WKHVH��

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

:ULWWHQ�RXW�LQ�IXOO��ZLWKRXW�XVLQJ�3HUO¦V�GHIDXOWV�DQG�VKRUWFXWV��WKDW�VQLSSHW�ZRXOG�EHURXJKO\����RU����WLPHV�ORQJHU��VR�LW�ZRXOG�WDNH�PXFK�ORQJHU�WR�UHDG�DQG�ZULWH��,W�ZRXOGEH�KDUGHU�WR�PDLQWDLQ�DQG�GHEXJ��WRR��ZLWK�PRUH�YDULDEOHV��,I�\RX�DOUHDG\�NQRZ�VRPH

,I�\RX¦UH�JRLQJ�WR�XVH�D�SURJUDPPLQJ�ODQJXDJH�IRU�RQO\�D�IHZ�PLQXWHV�HDFK�ZHHN�RU�PRQWK��\RX¦G�SUHIHU�RQHWKDW�LV�HDVLHU�WR�OHDUQ��VLQFH�\RX¦OO�KDYH�IRUJRWWHQ�QHDUO\�DOO�RI�LW�IURP�RQH�XVH�WR�WKH�QH[W��3HUO�LV�IRU�SHRSOHZKR�DUH�SURJUDPPHUV�IRU�DW�OHDVW����PLQXWHV�SHU�GD\��DQG�SUREDEO\�PRVW�RI�WKDW�LQ�3HUO�

� :H�ZRQ¦W�H[SODLQ�LW�DOO�KHUH��EXW�WKLV�H[DPSOH�SXOOV�VRPH�GDWD�IURP�DQ�LQSXW�ILOH�RU�ILOHV�LQ�RQH�IRUPDW�DQGZULWHV�VRPH�RI�LW�RXW�LQ�DQRWKHU�IRUPDW��$OO�RI�LWV�IHDWXUHV�DUH�FRYHUHG�LQ�WKLV�ERRN�

What Does “Perl” Stand For? | 5

3HUO��DQG�\RX�GRQ¦W�VHH�WKH�YDULDEOHV�LQ�WKDW�FRGH��WKDW¦V�SDUW�RI�WKH�SRLQW��7KH\¦UH�DOOEHLQJ�XVHG�E\�GHIDXOW��%XW�WR�KDYH�WKLV�HDVH�DW�WKH�SURJUDPPHU¦V�WDVNV�PHDQV�SD\LQJWKH�SULFH�ZKHQ�\RX¦UH�OHDUQLQJ��\RX�KDYH�WR�OHDUQ�WKRVH�GHIDXOWV�DQG�VKRUWFXWV�

$�JRRG�DQDORJ\�LV�WKH�SURSHU�DQG�IUHTXHQW�XVH�RI�FRQWUDFWLRQV�LQ�(QJOLVK��6XUH��£ZLOOQRW¤�PHDQV�WKH�VDPH�DV�£ZRQ¦W�¤�%XW�PRVW�SHRSOH�VD\�£ZRQ¦W¤�UDWKHU�WKDQ�£ZLOO�QRW¤EHFDXVH�LW�VDYHV�WLPH��DQG�EHFDXVH�HYHU\ERG\�NQRZV�LW�DQG�LW�PDNHV�VHQVH��6LPLODUO\�3HUO¦V� £FRQWUDFWLRQV¤� DEEUHYLDWH� FRPPRQ� £SKUDVHV¤� VR� WKDW� WKH\� FDQ� EH� £VSRNHQ¤TXLFNHU�DQG�XQGHUVWRRG�E\�WKH�PDLQWDLQHU�DV�D�VLQJOH� LGLRP��UDWKHU�WKDQ�D�VHULHV�RIXQUHODWHG�VWHSV�

2QFH�\RX�EHFRPH�IDPLOLDU�ZLWK�3HUO��\RX�PD\�ILQG�\RXUVHOI�VSHQGLQJ�OHVV�WLPH�WU\LQJWR�JHW�VKHOO�TXRWLQJ��RU�&�GHFODUDWLRQV��ULJKW��DQG�PRUH�WLPH�VXUILQJ�WKH�:HE�EHFDXVH3HUO� LV� D� JUHDW� WRRO� IRU� OHYHUDJH��3HUO¦V� FRQFLVH� FRQVWUXFWV� DOORZ�\RX� WR� FUHDWH� �ZLWKPLQLPDO�IXVV��VRPH�YHU\�FRRO�RQH�XS�VROXWLRQV�RU�JHQHUDO�WRROV��$OVR��\RX�FDQ�GUDJWKRVH�WRROV�DORQJ�WR�\RXU�QH[W�MRE�EHFDXVH�3HUO�LV�KLJKO\�SRUWDEOH�DQG�UHDGLO\�DYDLODEOH�VR�\RX¦OO�KDYH�HYHQ�PRUH�WLPH�WR�VXUI�

3HUO�LV�D�YHU\�KLJK�OHYHO�ODQJXDJH��7KDW�PHDQV�WKDW�WKH�FRGH�LV�TXLWH�GHQVH��D�3HUO�SUR�JUDP�PD\�EH�DURXQG�D�TXDUWHU�WR�WKUHH�TXDUWHUV�DV�ORQJ�DV�WKH�FRUUHVSRQGLQJ�SURJUDPLQ�&��7KLV�PDNHV�3HUO�IDVWHU�WR�ZULWH��IDVWHU�WR�UHDG��IDVWHU�WR�GHEXJ��DQG�IDVWHU�WR�PDLQ�WDLQ��,W�GRHVQ¦W�WDNH�PXFK�SURJUDPPLQJ�EHIRUH�\RX�UHDOL]H�WKDW��ZKHQ�WKH�HQWLUH�VXE�URXWLQH�LV�VPDOO�HQRXJK�WR�ILW�RQVFUHHQ�DOO�DW�RQFH��\RX�GRQ¦W�KDYH�WR�NHHS�VFUROOLQJ�EDFNDQG�IRUWK�WR�VHH�ZKDW¦V�JRLQJ�RQ��$OVR��VLQFH�WKH�QXPEHU�RI�EXJV�LQ�D�SURJUDP�LV�URXJKO\SURSRUWLRQDO�WR�WKH�OHQJWK�RI�WKH�VRXUFH�FRGH ��UDWKHU�WKDQ�EHLQJ�SURSRUWLRQDO�WR�WKHSURJUDP¦V�IXQFWLRQDOLW\���WKH�VKRUWHU�VRXUFH�LQ�3HUO�ZLOO�PHDQ�IHZHU�EXJV�RQ�DYHUDJH�

/LNH�DQ\�ODQJXDJH��3HUO�FDQ�EH�£ZULWH�RQO\¤¢LW¦V�SRVVLEOH�WR�ZULWH�SURJUDPV�WKDW�DUHLPSRVVLEOH�WR�UHDG��%XW�ZLWK�SURSHU�FDUH��\RX�FDQ�DYRLG�WKLV�FRPPRQ�DFFXVDWLRQ��<HV�VRPHWLPHV�3HUO�ORRNV�OLNH�OLQH�QRLVH�WR�WKH�XQLQLWLDWHG��EXW�WR�WKH�VHDVRQHG�3HUO�SUR�JUDPPHU��LW�ORRNV�OLNH�WKH�QRWHV�RI�D�JUDQG�V\PSKRQ\��,I�\RX�IROORZ�WKH�JXLGHOLQHV�RIWKLV�ERRN��\RXU�SURJUDPV�VKRXOG�EH�HDV\�WR�UHDG�DQG�HDV\�WR�PDLQWDLQ��DQG�WKH\�SURE�DEO\�ZRQ¦W�ZLQ�7KH�2EIXVFDWHG�3HUO�&RQWHVW�

How Did Perl Get to Be So Popular?$IWHU�SOD\LQJ�ZLWK�3HUO�D�ELW��DGGLQJ�VWXII�KHUH�DQG�WKHUH��/DUU\�UHOHDVHG�LW�WR�WKH�FRP�PXQLW\�RI�8VHQHW�UHDGHUV��FRPPRQO\�NQRZQ�DV�£WKH�1HW�¤�7KH�XVHUV�RQ�WKLV�UDJWDJIXJLWLYH�IOHHW�RI�V\VWHPV�DURXQG�WKH�ZRUOG��WHQV�RI�WKRXVDQGV�RI�WKHP��JDYH�KLP�IHHG�EDFN��DVNLQJ�IRU�ZD\V�WR�GR�WKLV��WKDW��RU�WKH�RWKHU�WKLQJ��PDQ\�RI�ZKLFK�/DUU\�KDG�QHYHUHQYLVLRQHG�KLV�OLWWOH�3HUO�KDQGOLQJ�

%XW�DV�D�UHVXOW��3HUO�JUHZ��DQG�JUHZ��DQG�JUHZ��,W�JUHZ�LQ�IHDWXUHV��,W�JUHZ�LQ�SRUWDELOLW\�:KDW�ZDV�RQFH�D�OLWWOH�ODQJXDJH�DYDLODEOH�RQ�RQO\�D�FRXSOH�RI�8QL[�V\VWHPV�QRZ�KDV

:LWK�D�VKDUS�MXPS�ZKHQ�DQ\�RQH�VHFWLRQ�RI�WKH�SURJUDP�H[FHHGV�WKH�VL]H�RI�\RXU�VFUHHQ�

6 | Chapter 1:ಗIntroduction

WKRXVDQGV�RI�SDJHV�RI�IUHH�RQOLQH�GRFXPHQWDWLRQ��GR]HQV�RI�ERRNV��VHYHUDO�PDLQVWUHDP8VHQHW�QHZVJURXSV��DQG�D�GR]HQ�QHZVJURXSV�DQG�PDLOLQJ�OLVWV�RXWVLGH�WKH�PDLQVWUHDP�¢ZLWK�DQ�XQFRXQWDEOH�QXPEHU�RI�UHDGHUV��DQG�LPSOHPHQWDWLRQV�RQ�QHDUO\�HYHU\�V\VWHPLQ�XVH�WRGD\¢DQG�GRQ¦W�IRUJHW�WKLV�/ODPD�ERRN�DV�ZHOO�

What’s Happening with Perl Now?/DUU\�:DOO�GRHVQ¦W�ZULWH�WKH�FRGH�WKHVH�GD\V��EXW�KH�VWLOO�JXLGHV�WKH�GHYHORSPHQW�DQGPDNHV�WKH�ELJ�GHFLVLRQV��3HUO�LV�PRVWO\�PDLQWDLQHG�E\�D�KDUG\�JURXS�RI�SHRSOH�FDOOHGWKH�3HUO���3RUWHUV��<RX�FDQ�VXEVFULEH�WR�WKHLU�PDLOLQJ�OLVW�DW�SHUO��SRUWHUV#SHUO�RUJ�WRIROORZ�WKHLU�ZRUN�DQG�GLVFXVVLRQV�

$V�ZH�ZULWH�WKLV��0DUFK��������WKHUH�LV�D�ORW�KDSSHQLQJ�ZLWK�3HUO��)RU�WKH�SDVW�FRXSOHRI�\HDUV��PDQ\�SHRSOH�KDYH�EHHQ�ZRUNLQJ�RQ�WKH�QH[W�PDMRU�YHUVLRQ�RI�3HUO��3HUO���

'RQ¦W�WKURZ�DZD\�\RXU�3HUO����ZKLFK�LV�VWLOO�WKH�FXUUHQW�DQG�VWDEOH�YHUVLRQ��:H�GRQ¦WH[SHFW�D�VWDEOH�YHUVLRQ�RI�3HUO���IRU�D�ZKLOH�\HW��3HUO���GRHV�HYHU\WKLQJ�LW�DOZD\V�GLG�DQG�DOZD\V�ZLOO��3HUO���ZRQ¦W�GLVDSSHDU�ZKHQ�3HUO���VKRZV�XS��DQG�SHRSOH�PD\�HQG�XSXVLQJ�ERWK�IRU�VHYHUDO�\HDUV��7KH�3HUO���3RUWHUV�PDLQWDLQ�3HUO���MXVW�OLNH�WKH\�DOZD\VKDYH�DQG�VRPH�RI�WKH�JRRG�LGHDV�IURP�3HUO���KDYH�PDGH�LW�LQWR�3HUO����:H¦UH�XSGDWLQJWKLV�ERRN�EHFDXVH�3HUO������MXVW�FDPH�RXW��DQG�LW�ORRNV�OLNH�WKH�3HUO���3RUWHUV�DUH�DOUHDG\ZRUNLQJ�RQ�3HUO������

,Q�������/DUU\�ILUVW�SURSRVHG�WKH�QH[W�PDMRU�UHOHDVH�RI�3HUO�DV�WKH�3HUO�FRPPXQLW\¦VUHZULWH�RI�3HUO��,Q�WKH�\HDUV�WKDW�IROORZHG��D�QHZ�LQWHUSUHWHU�FDOOHG�3DUURW�FDPH�WR�OLIH�EXW�QRW�PXFK�HOVH�KDSSHQHG�IRU�WKH�XVHUV��,Q�������$XWULMXV�7DQJ�VWDUWHG�SOD\LQJ�ZLWK�3XJV��3HUO�8VHU�*ROILQJ�6\VWHP��DV�D�IHDWKHUZHLJKW�LPSOHPHQWDWLRQ�RI�3HUO���LQ�+DVNHOO�'HYHORSHUV�IURP�WKH�3HUO�DQG�+DVNHOO�VLGHV�RI�WKH�ZRUOG�UXVKHG�WR�KHOS��3DUURW��WKHYLUWXDO�PDFKLQH�WKDW�ZLOO�UXQ�3HUO����LV�FRPLQJ�DORQJ�QLFHO\�QRZ��DQG�WKDW¦V�ZKHUH�PRVWRI�WKH�ZRUN�LV�KDSSHQLQJ��<RX�FDQ�VHH�PRUH�DERXW�3HUO���DW�KWWS���SHUOVL[�RUJ�DQG�KWWS���ZZZ�SXJVFRGH�RUJ��)RU�WKLV�ERRN��ZH¦UH�QRW�JRLQJ�WR�ZRUU\�DERXW�3HUO����WKRXJK�

What’s Perl Really Good For?3HUO�LV�JRRG�IRU�TXLFN�DQG�GLUW\�SURJUDPV�WKDW�\RX�ZKLS�XS�LQ�WKUHH�PLQXWHV��3HUO�LVDOVR�JRRG�IRU�ORQJ�DQG�H[WHQVLYH�SURJUDPV�WKDW�ZLOO�WDNH�D�GR]HQ�SURJUDPPHUV�WKUHH\HDUV�WR�ILQLVK��2I�FRXUVH��\RX¦OO�SUREDEO\�ILQG�\RXUVHOI�ZULWLQJ�PDQ\�SURJUDPV�WKDWWDNH�\RX�OHVV�WKDQ�DQ�KRXU�WR�FRPSOHWH��IURP�WKH�LQLWLDO�SODQ�WR�WKH�IXOO\�WHVWHG�FRGH�

What Does “Perl” Stand For? | 7

3HUO�LV�RSWLPL]HG�IRU�SUREOHPV�WKDW�DUH�DERXW�����ZRUNLQJ�ZLWK�WH[W�DQG�DERXW����HYHU\WKLQJ�HOVH��7KDW�GHVFULSWLRQ�VHHPV�WR� ILW�PRVW�SURJUDPPLQJ�WDVNV�WKDW�SRS�XSWKHVH�GD\V��,Q�D�SHUIHFW�ZRUOG��HYHU\�SURJUDPPHU�FRXOG�NQRZ�HYHU\�ODQJXDJH��\RX¦GDOZD\V�EH�DEOH�WR�FKRRVH�WKH�EHVW�ODQJXDJH�IRU�HDFK�SURMHFW��0RVW�RI�WKH�WLPH��\RX¦GFKRRVH�3HUO� �$OWKRXJK�WKH�:HE�ZDVQ¦W�HYHQ�D�WZLQNOH�LQ�7LP�%HUQHUV�/HH¦V�H\H�ZKHQ/DUU\�FUHDWHG�3HUO��LW�ZDV�D�PDUULDJH�PDGH�RQ�WKH�1HW��6RPH�FODLP�WKDW�WKH�GHSOR\PHQWRI�3HUO�LQ�WKH�HDUO\�����V�SHUPLWWHG�SHRSOH�WR�PRYH�ORWV�RI�FRQWHQW�LQWR�+70/�IRUPDWYHU\�UDSLGO\��DQG�WKH�:HE�FRXOGQ¦W�H[LVW�ZLWKRXW�FRQWHQW��2I�FRXUVH��3HUO�LV�WKH�GDUOLQJODQJXDJH�IRU�VPDOO�&*,�VFULSWLQJ��SURJUDPV�UXQ�E\�D�ZHE�VHUYHU��DV�ZHOO¢VR�PXFK�VRWKDW�PDQ\�RI�WKH�XQLQIRUPHG�VWLOO�PDNH�VWDWHPHQWV�OLNH�£,VQ¦W�&*,�MXVW�3HUO"¤�RU�£:K\ZRXOG�\RX�XVH�3HUO�RWKHU�WKDQ�IRU�&*,"¤�:H�ILQG�WKRVH�VWDWHPHQWV�DPXVLQJ�

What Is Perl Not Good For?6R��LI�LW¦V�JRRG�IRU�VR�PDQ\�WKLQJV��ZKDW�LV�3HUO�QRW�JRRG�IRU"�:HOO��\RX�VKRXOGQ¦W�FKRRVH3HUO�LI�\RX¦UH�WU\LQJ�WR�PDNH�DQ�RSDTXH�ELQDU\��7KDW¦V�D�SURJUDP�WKDW�\RX�FRXOG�JLYHDZD\�RU�VHOO�WR�VRPHRQH�ZKR�WKHQ�FDQ¦W�VHH�\RXU�VHFUHW�DOJRULWKPV�LQ�WKH�VRXUFH��DQGWKXV�FDQ¦W�KHOS�\RX�PDLQWDLQ�RU�GHEXJ�\RXU�FRGH�HLWKHU��:KHQ�\RX�JLYH�VRPHRQH�\RXU3HUO�SURJUDP��\RX¦OO�QRUPDOO\�EH�JLYLQJ�WKHP�WKH�VRXUFH��QRW�DQ�RSDTXH�ELQDU\�

,I�\RX¦UH�ZLVKLQJ�IRU�DQ�RSDTXH�ELQDU\��WKRXJK��ZH�KDYH�WR�WHOO�\RX�WKDW�WKH\�GRQ¦W�H[LVW�,I�VRPHRQH�FDQ�LQVWDOO�DQG�UXQ�\RXU�SURJUDP��WKH\�FDQ�WXUQ�LW�EDFN�LQWR�VRXUFH�FRGH�*UDQWHG��WKLV�ZRQ¦W�QHFHVVDULO\�EH�WKH�VDPH�VRXUFH�WKDW�\RX�VWDUWHG�ZLWK��EXW�LW�ZLOO�EHVRPH�NLQG�RI�VRXUFH�FRGH��7KH�UHDO�ZD\�WR�NHHS�\RXU�VHFUHW�DOJRULWKP�D�VHFUHW�LV��DODV�WR�DSSO\�WKH�SURSHU�QXPEHU�RI�DWWRUQH\V��WKH\�FDQ�ZULWH�D�OLFHQVH�WKDW�VD\V��£<RX�FDQGR�WKLV�ZLWK�WKH�FRGH��EXW�\RX�FDQ¦W�GR�WKDW��$QG�LI�\RX�EUHDN�RXU�UXOHV��ZH¦YH�JRW�WKHSURSHU�QXPEHU�RI�DWWRUQH\V�WR�HQVXUH�WKDW�\RX¦OO�UHJUHW�LW�¤

How Can I Get Perl?<RX�SUREDEO\�DOUHDG\�KDYH�LW��$W�OHDVW��ZH�ILQG�3HUO�ZKHUHYHU�ZH�JR��,W�VKLSV�ZLWK�PDQ\V\VWHPV��DQG�V\VWHP�DGPLQLVWUDWRUV�RIWHQ�LQVWDOO�LW�RQ�HYHU\�PDFKLQH�DW�WKHLU�VLWH��%XWLI�\RX�FDQ¦W�ILQG�LW�DOUHDG\�RQ�\RXU�V\VWHP��\RX�FDQ�VWLOO�JHW�LW�IRU�IUHH�

3HUO�LV�GLVWULEXWHG�XQGHU�WZR�GLIIHUHQW�OLFHQVHV��)RU�PRVW�SHRSOH��EHFDXVH�\RX¦OO�PHUHO\EH�XVLQJ�LW��HLWKHU�OLFHQVH�LV�DV�JRRG�DV�WKH�RWKHU��,I�\RX¦OO�EH�PRGLI\LQJ�3HUO��KRZHYHU�\RX¦OO�ZDQW�WR�UHDG�WKH�OLFHQVHV�PRUH�FORVHO\�EHFDXVH�WKH\�SXW�VRPH�VPDOO�UHVWULFWLRQVRQ�GLVWULEXWLQJ� WKH�PRGLILHG� FRGH��)RU�SHRSOH�ZKR�ZRQ¦W�PRGLI\�3HUO�� WKH� OLFHQVHVHVVHQWLDOO\�VD\��£,W¦V�IUHH¢KDYH�IXQ�ZLWK�LW�¤

'RQ¦W�MXVW�WDNH�RXU�ZRUG�IRU�LW��WKRXJK��,I�\RX�ZDQW�WR�NQRZ�ZKHWKHU�3HUO�LV�EHWWHU�WKDQ�ODQJXDJH�;��OHDUQWKHP�ERWK�DQG�WU\�WKHP�ERWK��WKHQ�VHH�ZKLFK�RQH�\RX�XVH�PRVW�RIWHQ��7KDW¦V�WKH�RQH�WKDW¦V�EHVW�IRU�\RX��,QWKH�HQG��\RX¦OO�XQGHUVWDQG�3HUO�EHWWHU�EHFDXVH�RI�\RXU�VWXG\�RI�ODQJXDJH�;��DQG�YLFH�YHUVD��VR�LW�ZLOO�EH�WLPHZHOO�VSHQW�

8 | Chapter 1:ಗIntroduction

,Q�IDFW��LW¦V�QRW�RQO\�IUHH��EXW�LW�UXQV�UDWKHU�QLFHO\�RQ�QHDUO\�HYHU\WKLQJ�WKDW�FDOOV�LWVHOI8QL[�DQG�KDV�D�&�FRPSLOHU��<RX�GRZQORDG�LW��W\SH�D�FRPPDQG�RU�WZR��DQG�LW�VWDUWVFRQILJXULQJ�DQG�EXLOGLQJ�LWVHOI��2U��EHWWHU�\HW��\RX�JHW�\RXU�V\VWHP�DGPLQLVWUDWRU�WRW\SH�WKRVH�WZR�FRPPDQGV�DQG�LQVWDOO�LW�IRU�\RX� �%HVLGHV�8QL[�DQG�8QL[�OLNH�V\VWHPV�SHRSOH�KDYH�DOVR�EHHQ�DGGLFWHG�HQRXJK�WR�3HUO�WR�SRUW�LW�WR�RWKHU�V\VWHPV��VXFK�DV�0DF26�;��906��26����HYHQ�06�'26��DQG�HYHU\�PRGHUQ�VSHFLHV�RI�:LQGRZV¢DQG�SURE�DEO\�HYHQ�PRUH�E\�WKH�WLPH�\RX�UHDG�WKLV���0DQ\�RI�WKHVH�SRUWV�RI�3HUO�FRPH�ZLWK�DQLQVWDOODWLRQ�SURJUDP�WKDW¦V�HYHQ�HDVLHU�WR�XVH�WKDQ�WKH�SURFHVV�IRU� LQVWDOOLQJ�3HUO�RQ8QL[��&KHFN�IRU�OLQNV�LQ�WKH�£SRUWV¤�VHFWLRQ�RQ�&3$1�

What Is CPAN?&3$1�LV�WKH�&RPSUHKHQVLYH�3HUO�$UFKLYH�1HWZRUN��\RXU�RQH�VWRS�VKRS�IRU�3HUO��,W�KDVWKH�VRXUFH�FRGH�IRU�3HUO� LWVHOI�� UHDG\�WR�LQVWDOO�SRUWV�RI�3HUO� WR�DOO�VRUWV�RI�QRQ�8QL[V\VWHPV�®�H[DPSOHV��GRFXPHQWDWLRQ��H[WHQVLRQV�WR�3HUO��DQG�DUFKLYHV�RI�PHVVDJHV�DERXW3HUO��,Q�VKRUW��&3$1�LV�FRPSUHKHQVLYH�

&3$1�LV�UHSOLFDWHG�RQ�KXQGUHGV�RI�PLUURU�PDFKLQHV�DURXQG�WKH�ZRUOG��VWDUW�DW�KWWS���VHDUFK�FSDQ�RUJ��RU�KWWS���NREHVHDUFK�FSDQ�RUJ��WR�EURZVH�RU�VHDUFK�WKH�DUFKLYH��,I�\RXGRQ¦W�KDYH�DFFHVV�WR�WKH�1HW��\RX�PLJKW�ILQG�D�&'�520�RU�'9'�520�ZLWK�DOO�RI�WKHXVHIXO�SDUWV�RI�&3$1�RQ� LW�� FKHFN�ZLWK�\RXU� ORFDO� WHFKQLFDO�ERRNVWRUH��/RRN� IRU� DUHFHQWO\�PLQWHG�DUFKLYH��WKRXJK��%HFDXVH�&3$1�FKDQJHV�GDLO\��DQ�DUFKLYH�IURP�WZR\HDUV�DJR�LV�DQ�DQWLTXH��%HWWHU�\HW��JHW�D�NLQG�IULHQG�ZLWK�1HW�DFFHVV�WR�EXUQ�\RX�RQHZLWK�WRGD\¦V�&3$1�

How Can I Get Support for Perl?:HOO��\RX�JHW�WKH�FRPSOHWH�VRXUFH¢VR�\RX�JHW�WR�IL[�WKH�EXJV�\RXUVHOI�

7KDW�GRHVQ¦W� VRXQG�VR�JRRG��GRHV� LW"�%XW� LW� UHDOO\� LV�D�JRRG�WKLQJ��6LQFH� WKHUH¦V�QR£VRXUFH�FRGH�HVFURZ¤�RQ�3HUO��DQ\RQH�FDQ�IL[�D�EXJ¢LQ�IDFW��E\�WKH�WLPH�\RX¦YH�IRXQGDQG�YHULILHG�D�EXJ��VRPHRQH�HOVH�SUREDEO\�DOUHDG\�KDV�D�IL[�IRU�LW��7KHUH�DUH�WKRXVDQGVRI�SHRSOH�DURXQG�WKH�ZRUOG�ZKR�KHOS�PDLQWDLQ�3HUO�

1RZ��ZH¦UH�QRW�VD\LQJ�WKDW�3HUO�KDV�D�ORW�RI�EXJV��%XW�LW¦V�D�SURJUDP��DQG�HYHU\�SURJUDPKDV�DW�OHDVW�RQH�EXJ��7R�VHH�ZK\�LW¦V�VR�XVHIXO�WR�KDYH�WKH�VRXUFH�WR�3HUO��LPDJLQH�WKDWLQVWHDG�RI�XVLQJ�3HUO��\RX�OLFHQVHG�D�SURJUDPPLQJ�ODQJXDJH�FDOOHG�)RUHKHDG�IURP�D

,I�V\VWHP�DGPLQLVWUDWRUV�FDQ¦W�LQVWDOO�VRIWZDUH��ZKDW�JRRG�DUH�WKH\"�,I�\RX�KDYH�WURXEOH�FRQYLQFLQJ�\RXU�DGPLQWR�LQVWDOO�3HUO��RIIHU�WR�EX\�D�SL]]D��:H¦YH�QHYHU�PHW�D�V\V�DGPLQ�ZKR�FRXOG�VD\�QR�WR�D�IUHH�SL]]D��RU�DW�OHDVWFRXQWHU�RIIHU�ZLWK�VRPHWKLQJ�MXVW�DV�HDV\�WR�JHW�

� $QG�QR��DV�ZH�ZULWH�WKLV��LW�ZRQ¦W�ILW�LQ�\RXU�%ODFNEHUU\¢LW¦V�MXVW�WRR�GDUQ�ELJ��HYHQ�VWULSSHG�GRZQ��:H¦YHKHDUG�UXPRUV�WKDW�LW�UXQV�RQ�:LQ&(�WKRXJK�

® ,W¦V�QHDUO\�DOZD\V�EHWWHU�WR�FRPSLOH�3HUO�IURP�WKH�VRXUFH�RQ�8QL[�V\VWHPV��2WKHU�V\VWHPV�PD\�QRW�KDYH�D�&FRPSLOHU�DQG�RWKHU�WRROV�QHHGHG�IRU�FRPSLODWLRQ��VR�&3$1�KDV�ELQDULHV�IRU�WKHVH�

How Can I Get Perl? | 9

JLDQW�� SRZHUIXO� FRUSRUDWLRQ� RZQHG� E\� D� ]LOOLRQDLUH�ZLWK� D� EDG� KDLUFXW�� �7KLV� LV� DOOK\SRWKHWLFDO��(YHU\RQH�NQRZV�WKHUH¦V�QR�VXFK�SURJUDPPLQJ�ODQJXDJH�DV�)RUHKHDG��1RZ�WKLQN�RI�ZKDW�\RX�FDQ�GR�ZKHQ�\RX�ILQG�D�EXJ�LQ�)RUHKHDG��)LUVW��\RX�FDQ�UHSRUWLW��VHFRQG��\RX�FDQ�KRSH¢KRSH�WKDW�WKH\�IL[�WKH�EXJ��KRSH�WKDW�WKH\�IL[�LW�VRRQ��KRSHWKDW�WKH\�ZRQ¦W�FKDUJH�WRR�PXFK�IRU�WKH�QHZ�YHUVLRQ��<RX�FDQ�KRSH�WKDW�WKH�QHZ�YHUVLRQGRHVQ¦W�DGG�QHZ�IHDWXUHV�ZLWK�QHZ�EXJV��DQG�KRSH�WKDW�WKH�JLDQW�FRPSDQ\�GRHVQ¦W�JHWEURNHQ�XS�LQ�DQ�DQWLWUXVW�ODZVXLW�

%XW�ZLWK�3HUO��\RX¦YH�JRW�WKH�VRXUFH��,Q�WKH�UDUH�DQG�XQOLNHO\�HYHQW�WKDW�\RX�FDQ¦W�JHW�DEXJ�IL[HG�DQ\�RWKHU�ZD\��\RX�FDQ�KLUH�D�SURJUDPPHU�RU����DQG�JHW�WR�ZRUN��)RU�WKDWPDWWHU��LI�\RX�EX\�D�QHZ�PDFKLQH�WKDW�3HUO�GRHVQ¦W�\HW�UXQ�RQ��\RX�FDQ�SRUW�LW�\RXUVHOI�2U�LI�\RX�QHHG�D�IHDWXUH�WKDW�GRHVQ¦W�\HW�H[LVW��ZHOO��\RX�NQRZ�ZKDW�WR�GR�

Are There Any Other Kinds of Support?6XUH��2QH�RI�RXU�IDYRULWHV�LV�WKH�3HUO�0RQJHUV��7KLV�LV�D�ZRUOGZLGH�DVVRFLDWLRQ�RI�3HUO�XVHUV¦�JURXSV��VHH�KWWS���ZZZ�SP�RUJ��IRU�PRUH�LQIRUPDWLRQ��7KHUH¦V�SUREDEO\�D�JURXSQHDU�\RX�ZLWK�DQ�H[SHUW�RU�VRPHRQH�ZKR�NQRZV�DQ�H[SHUW��,I�WKHUH¦V�QR�JURXS��\RX�FDQHDVLO\�VWDUW�RQH�

2I�FRXUVH��IRU�WKH�ILUVW�OLQH�RI�VXSSRUW��\RX�VKRXOGQ¦W�QHJOHFW�WKH�GRFXPHQWDWLRQ��%H�VLGHV� WKH� PDQSDJHV� � \RX� FDQ� DOVR� ILQG� WKH� GRFXPHQWDWLRQ� RQ� WKH� &3$1� �KWWS���ZZZ�FSDQ�RUJ��DV�ZHOO�DV�RWKHU�VLWHV��VXFK�DV�KWWS���SHUOGRF�SHUO�RUJ��ZKLFK�KDV�+70/DQG�3')�YHUVLRQV�RI�WKH�3HUO�GRFXPHQWDWLRQ��RU�KWWS���IDT�SHUO�RUJ���ZKLFK�KDV�WKH�ODWHVWYHUVLRQ�RI�WKH�SHUOIDT�

$QRWKHU� DXWKRULWDWLYH� VRXUFH� LV� WKH�ERRN�3URJUDPPLQJ�3HUO�� FRPPRQO\� FDOOHG�£WKH&DPHO�ERRN¤�EHFDXVH�RI�LWV�FRYHU�DQLPDO��MXVW�DV�WKLV�ERRN�LV�NQRZQ�DV�£WKH�/ODPDERRN¤���7KH�&DPHO�ERRN�FRQWDLQV�WKH�FRPSOHWH�UHIHUHQFH�LQIRUPDWLRQ��VRPH�WXWRULDOVWXII��DQG�D�EXQFK�RI�PLVFHOODQHRXV�LQIRUPDWLRQ�DERXW�3HUO��7KHUH¦V�DOVR�D�VHSDUDWHSRFNHW�VL]H�3HUO���3RFNHW�5HIHUHQFH��2¦5HLOO\��E\�-RKDQ�9URPDQV�WKDW¦V�FRQYHQLHQW�WRNHHS�DW�KDQG��RU�LQ�\RXU�SRFNHW��

,I�\RX�QHHG�WR�DVN�D�TXHVWLRQ�RI�VRPHRQH��WKHUH�DUH�QHZVJURXSV�RQ�8VHQHW�DQG�DQ\QXPEHU�RI�PDLOLQJ�OLVWV���$W�DQ\�KRXU�RI�WKH�GD\�RU�QLJKW��WKHUH¦V�D�3HUO�H[SHUW�DZDNHLQ�VRPH�WLPH�]RQH��DQVZHULQJ�TXHVWLRQV�RQ�8VHQHW¦V�3HUO�QHZVJURXSV¢WKH�VXQ�QHYHUVHWV�RQ�WKH�3HUO�HPSLUH��7KLV�PHDQV�WKDW�LI�\RX�DVN�D�TXHVWLRQ��\RX¦OO�RIWHQ�JHW�DQ�DQVZHUZLWKLQ�PLQXWHV��,I�\RX�GLGQ¦W�FKHFN�WKH�GRFXPHQWDWLRQ�DQG�)$4�ILUVW��\RX¦OO�JHW�IODPHGZLWKLQ�PLQXWHV�

7KH�RIILFLDO�3HUO�QHZVJURXSV�RQ�8VHQHW�DUH�ORFDWHG�LQ�WKH�FRPS�ODQJ�SHUO� �SDUW�RI�WKHKLHUDUFK\��$V�RI�WKLV�ZULWLQJ��WKHUH�DUH�ILYH�RI�WKHP��EXW�WKH\�FKDQJH�IURP�WLPH�WR�WLPH�

7KH�WHUP�PDQSDJHV�LV�D�8QL[�LVP�PHDQLQJ�GRFXPHQWDWLRQ��,I�\RX¦UH�QRW�RQ�D�8QL[�V\VWHP��WKH�PDQSDJHV�IRU3HUO�VKRXOG�EH�DYDLODEOH�YLD�\RXU�V\VWHP¦V�QDWLYH�GRFXPHQWDWLRQ�V\VWHP�

� 0DQ\�PDLOLQJ�OLVWV�DUH�OLVWHG�DW�KWWS���OLVWV�SHUO�RUJ�

10 | Chapter 1:ಗIntroduction

<RX� �RU� ZKRHYHU� LV� LQ� FKDUJH� RI� 3HUO� DW� \RXU� VLWH�� VKRXOG� JHQHUDOO\� VXEVFULEH� WRFRPS�ODQJ�SHUO�DQQRXQFH�� ZKLFK� LV� D� ORZ�YROXPH� QHZVJURXS� MXVW� IRU� LPSRUWDQWDQQRXQFHPHQWV�DERXW�3HUO��LQFOXGLQJ�HVSHFLDOO\�DQ\�VHFXULW\�UHODWHG�DQQRXQFHPHQWV�$VN�\RXU�ORFDO�H[SHUW�LI�\RX�QHHG�KHOS�ZLWK�8VHQHW�

$OVR��D�IHZ�ZHE�FRPPXQLWLHV�KDYH�VSUXQJ�XS�DURXQG�3HUO�GLVFXVVLRQV��2QH�YHU\�SRSXODURQH��3HUO�0RQDVWHU\��KWWS���ZZZ�SHUOPRQNV�RUJ���KDV�VHHQ�TXLWH�D�ELW�RI�SDUWLFLSDWLRQIURP�PDQ\�3HUO�ERRN�DQG�FROXPQ�DXWKRUV��LQFOXGLQJ�DW�OHDVW�WZR�RI�WKH�DXWKRUV�RI�WKLVERRN�� <RX� FDQ� DOVR� FKHFN� RXW� KWWS���OHDUQ�SHUO�RUJ�� DQG� LWV� DVVRFLDWHG� PDLOLQJ� OLVW�EHJLQQHUV#SHUO�RUJ��)RU�3HUO�QHZV��WU\�KWWS���XVH�SHUO�RUJ���0DQ\�ZHOO�NQRZQ�3HUO�SUR�JUDPPHUV�DOVR�KDYH�EORJV�WKDW�UHJXODUO\�IHDWXUH�3HUO�UHODWHG�SRVWV��PRVW�RI�ZKLFK�\RXFDQ�UHDG�WKURXJK�KWWS���SODQHW�SHUO�RUJ�

,I�\RX�ILQG�\RXUVHOI�QHHGLQJ�D�VXSSRUW�FRQWUDFW�IRU�3HUO��WKHUH�DUH�D�QXPEHU�RI�ILUPV�WKDWDUH�ZLOOLQJ�WR�FKDUJH�DV�PXFK�DV�\RX¦G�OLNH��,Q�PRVW�FDVHV��WKHVH�RWKHU�VXSSRUW�DYHQXHVZLOO�WDNH�FDUH�RI�\RX�IRU�IUHH�

What If I Find a Bug in Perl?7KH�ILUVW�WKLQJ�WR�GR�ZKHQ�\RX�ILQG�D�EXJ�LV�WR�FKHFN�WKH�GRFXPHQWDWLRQ �DJDLQ���3HUOKDV�VR�PDQ\�VSHFLDO�IHDWXUHV�DQG�H[FHSWLRQV�WR�UXOHV�WKDW�\RX�PD\�KDYH�GLVFRYHUHG�DIHDWXUH��QRW�D�EXJ��$OVR��FKHFN�WKDW�\RX�GRQ¦W�KDYH�DQ�ROGHU�YHUVLRQ�RI�3HUO��PD\EH�\RXIRXQG�VRPHWKLQJ�WKDW¦V�EHHQ�IL[HG�LQ�D�PRUH�UHFHQW�YHUVLRQ�

2QFH�\RX¦UH�����FHUWDLQ�WKDW�\RX¦YH�IRXQG�D�UHDO�EXJ��DVN�DURXQG��$VN�VRPHRQH�DWZRUN��DW�\RXU�ORFDO�3HUO�0RQJHUV¦�PHHWLQJ��RU�DW�D�3HUO�FRQIHUHQFH��&KDQFHV�DUH��LW¦VVWLOO�D�IHDWXUH��QRW�D�EXJ�

2QFH�\RX¦UH������FHUWDLQ�WKDW�\RX¦YH�IRXQG�D�UHDO�EXJ��FRRN�XS�D�WHVW�FDVH���:KDW�\RX�KDYHQ¦W�GRQH�VR�DOUHDG\"��7KH�LGHDO�WHVW�FDVH�LV�D�WLQ\�VHOI�FRQWDLQHG�SURJUDP�WKDWDQ\�3HUO�XVHU�FRXOG�UXQ�WR�VHH�WKH�VDPH��PLV�EHKDYLRU�\RX¦YH�IRXQG��2QFH�\RX¦YH�JRWD�WHVW�FDVH�WKDW�FOHDUO\�VKRZV�WKH�EXJ��XVH�WKH�SHUOEXJ�XWLOLW\��ZKLFK�FRPHV�ZLWK�3HUO�WR�UHSRUW�WKH�EXJ��7KDW�ZLOO�QRUPDOO\�VHQG�HPDLO�IURP�\RX�WR�WKH�3HUO�GHYHORSHUV��VRGRQ¦W�XVH�SHUOEXJ�XQWLO�\RX¦YH�JRW�\RXU�WHVW�FDVH�UHDG\�

2QFH�\RX¦YH�VHQW�RII�\RXU�EXJ�UHSRUW��LI�\RX¦YH�GRQH�HYHU\WKLQJ�ULJKW��LW¦V�QRW�XQXVXDOWR�JHW�D�UHVSRQVH�ZLWKLQ�PLQXWHV��7\SLFDOO\��\RX�FDQ�DSSO\�D�VLPSOH�SDWFK�DQG�JHW�ULJKWEDFN�WR�ZRUN��2I�FRXUVH��\RX�PD\��DW�ZRUVW��JHW�QR�UHVSRQVH�DW�DOO��WKH�3HUO�GHYHORSHUVDUH�XQGHU�QR�REOLJDWLRQ�WR�HYHQ�UHDG�\RXU�EXJ�UHSRUWV��%XW�DOO�RI�XV�ORYH�3HUO��VR�QRERG\OLNHV�WR�OHW�D�EXJ�HVFDSH�RXU�QRWLFH�

(YHQ�/DUU\�DGPLWV�WR�FRQVXOWLQJ�WKH�GRFXPHQWDWLRQ�IURP�WLPH�WR�WLPH�

� 0D\EH� HYHQ� WZR� RU� WKUHH� WLPHV��0DQ\� WLPHV��ZH¦YH� JRQH� LQWR� WKH� GRFXPHQWDWLRQ� ORRNLQJ� WR� H[SODLQ� DSDUWLFXODU�XQH[SHFWHG�EHKDYLRU�DQG�IRXQG�VRPH�QHZ�OLWWOH�QXDQFH�WKDW�HQGV�XS�RQ�D�VOLGH�RU�LQ�D�FROXPQ�

How Can I Get Perl? | 11

How Do I Make a Perl Program?,W¦V�DERXW�WLPH�\RX�DVNHG��HYHQ�LI�\RX�GLGQ¦W���3HUO�SURJUDPV�DUH�WH[W�ILOHV��\RX�FDQ�FUHDWHDQG�HGLW�WKHP�ZLWK�\RXU�IDYRULWH�WH[W�HGLWRU���<RX�GRQ¦W�QHHG�DQ\�VSHFLDO�GHYHORSPHQWHQYLURQPHQW��DOWKRXJK�WKHUH�DUH�VRPH�FRPPHUFLDO�RQHV�DYDLODEOH�IURP�YDULRXV�YHQGRUV�:H¦YH�QHYHU�XVHG�DQ\�RI�WKHVH�HQRXJK�WR�UHFRPPHQG�WKHP��

<RX�VKRXOG�JHQHUDOO\�XVH�D�SURJUDPPHUV¦�WH[W�HGLWRU��UDWKHU�WKDQ�DQ�RUGLQDU\�HGLWRU�:KDW¦V� WKH�GLIIHUHQFH"�:HOO��D�SURJUDPPHUV¦� WH[W�HGLWRU�ZLOO� OHW�\RX�GR�WKLQJV� WKDWSURJUDPPHUV� QHHG�� OLNH� LQGHQWLQJ� RU� XQLQGHQWLQJ� D� EORFN� RI� FRGH�� RU� ILQGLQJ� WKHPDWFKLQJ�FORVLQJ�FXUO\�EUDFH�IRU�D�JLYHQ�RSHQLQJ�FXUO\�EUDFH��2Q�8QL[�V\VWHPV��WKH�WZRPRVW�SRSXODU�SURJUDPPHUV¦�HGLWRUV�DUH�HPDFV�DQG�YL��DQG�WKHLU�YDULDQWV�DQG�FORQHV��%%(GLW�DQG�7H[W0DWH�DUH�JRRG�HGLWRUV�IRU�0DF�26�;��DQG�D�ORW�RI�SHRSOH�KDYH�VDLG�QLFHWKLQJV� DERXW�8OWUD(GLW� DQG�3)(� �3URJUDPPHU¦V� )DYRULWH�(GLWRU�� RQ�:LQGRZV��7KHSHUOIDT��PDQSDJH�OLVWV�VHYHUDO�RWKHU�HGLWRUV��WRR��$VN�\RXU�ORFDO�H[SHUW�DERXW�WH[W�HG�LWRUV�RQ�\RXU�V\VWHP�

)RU�WKH�VLPSOH�SURJUDPV�\RX¦OO�ZULWH�IRU�WKH�H[HUFLVHV�LQ�WKLV�ERRN��QRQH�RI�ZKLFK�VKRXOGEH�PRUH�WKDQ�DERXW����RU����OLQHV�RI�FRGH��DQ\�WH[W�HGLWRU�ZLOO�EH�ILQH�

6RPH�EHJLQQHUV�WU\�WR�XVH�D�ZRUG�SURFHVVRU�LQVWHDG�RI�D�WH[W�HGLWRU��:H�UHFRPPHQGDJDLQVW�WKLV¢LW¦V�LQFRQYHQLHQW�DW�EHVW�DQG�LPSRVVLEOH�DW�ZRUVW��%XW�ZH�ZRQ¦W�WU\�WR�VWRS\RX��%H�VXUH�WR�WHOO�WKH�ZRUG�SURFHVVRU�WR�VDYH�\RXU�ILOH�DV�£WH[W�RQO\¤��WKH�ZRUG�SUR�FHVVRU¦V� RZQ� IRUPDW�ZLOO� DOPRVW� FHUWDLQO\� EH� XQXVDEOH��0RVW�ZRUG� SURFHVVRUV�ZLOOSUREDEO\�DOVR�WHOO�\RX�WKDW�\RXU�3HUO�SURJUDP�LV�VSHOOHG�LQFRUUHFWO\�DQG�VKRXOG�XVH�IHZHUVHPLFRORQV�

,Q�VRPH�FDVHV��\RX�PD\�QHHG�WR�FRPSRVH�WKH�SURJUDP�RQ�RQH�PDFKLQH��WKHQ�WUDQVIHULW�WR�DQRWKHU�WR�UXQ�LW��,I�\RX�GR�WKLV��EH�VXUH�WKDW�WKH�WUDQVIHU�XVHV�£WH[W¤�RU�£$6&,,¤PRGH��DQG�QRW�£ELQDU\¤�PRGH��7KLV�VWHS�LV�QHHGHG�EHFDXVH�RI�WKH�GLIIHUHQW�WH[W�IRUPDWVRQ�GLIIHUHQW�PDFKLQHV��:LWKRXW�LW��\RX�PD\�JHW�LQFRQVLVWHQW�UHVXOWV¢VRPH�YHUVLRQV�RI3HUO�DFWXDOO\�DERUW�ZKHQ�WKH\�GHWHFW�D�PLVPDWFK�LQ�WKH�OLQH�HQGLQJV�

A Simple Program$FFRUGLQJ�WR�WKH�ROGHVW�UXOH�LQ�WKH�ERRN��DQ\�ERRN�DERXW�D�FRPSXWHU�ODQJXDJH�WKDW�KDV8QL[�OLNH�URRWV�KDV�WR�VWDUW�ZLWK�VKRZLQJ�WKH�£+HOOR��ZRUOG¤�SURJUDP��6R��KHUH�LW�LV�LQ3HUO�

#!/usr/bin/perlprint "Hello, world!\n";

12 | Chapter 1:ಗIntroduction

/HW¦V�LPDJLQH�WKDW�\RX¦YH�W\SHG�WKDW�LQWR�\RXU�WH[W�HGLWRU���'RQ¦W�ZRUU\�\HW�DERXW�ZKDWWKH�SDUWV�PHDQ�DQG�KRZ� WKH\�ZRUN��:H¦OO� VHH�DERXW� WKRVH� LQ�D�PRPHQW���<RX�FDQJHQHUDOO\�VDYH�WKDW�SURJUDP�XQGHU�DQ\�QDPH�\RX�ZLVK��3HUO�GRHVQ¦W�UHTXLUH�DQ\�VSHFLDONLQG�RI�ILOHQDPH�RU�H[WHQVLRQ��DQG�LW¦V�EHWWHU�QRW�WR�XVH�DQ�H[WHQVLRQ�DW�DOO� �%XW�VRPHV\VWHPV�PD\�UHTXLUH�DQ�H[WHQVLRQ�OLNH��SO[��PHDQLQJ�3HU/�H;HFXWDEOH���VHH�\RXU�V\V�WHP¦V�UHOHDVH�QRWHV�IRU�PRUH�LQIRUPDWLRQ�

<RX�PD\�DOVR�QHHG�WR�GR�VRPHWKLQJ�VR�WKDW�\RXU�V\VWHP�NQRZV�LW¦V�DQ�H[HFXWDEOH�SUR�JUDP��WKDW�LV��D�FRPPDQG���:KDW�\RX¦OO�GR�GHSHQGV�XSRQ�\RXU�V\VWHP��PD\EH�\RXZRQ¦W�KDYH�WR�GR�DQ\WKLQJ�PRUH�WKDQ�VDYH�WKH�SURJUDP�LQ�D�FHUWDLQ�SODFH���<RXU�FXUUHQWGLUHFWRU\�ZLOO�JHQHUDOO\�EH�ILQH���2Q�8QL[�V\VWHPV��\RX�PDUN�D�SURJUDP�DV�EHLQJ�H[H�FXWDEOH�XVLQJ�WKH�FKPRG�FRPPDQG��SHUKDSV�OLNH�WKLV�

$ chmod a+x my_program

7KH�GROODU�VLJQ��DQG�VSDFH��DW�WKH�VWDUW�RI�WKH�OLQH�UHSUHVHQWV�WKH�VKHOO�SURPSW��ZKLFKZLOO�SUREDEO\�ORRN�GLIIHUHQW�RQ�\RXU�V\VWHP��,I�\RX¦UH�XVHG�WR�XVLQJ�FKPRG�ZLWK�D�QXP�EHU�OLNH�755�LQVWHDG�RI�D�V\PEROLF�SDUDPHWHU�OLNH�a+x��WKDW¦V�ILQH�WRR��RI�FRXUVH��(LWKHUZD\��LW�WHOOV�WKH�V\VWHP�WKDW�WKLV�ILOH�LV�QRZ�D�SURJUDP�

1RZ�\RX¦UH�UHDG\�WR�UXQ�LW�

$ ./my_program

7KH�GRW�DQG�VODVK�DW�WKH�VWDUW�RI�WKLV�FRPPDQG�PHDQ�WR�ILQG�WKH�SURJUDP�LQ�WKH�FXUUHQWZRUNLQJ�GLUHFWRU\��7KDW¦V�QRW�QHHGHG�LQ�DOO�FDVHV��EXW�\RX�VKRXOG�XVH�LW�DW�WKH�VWDUW�RIHDFK�FRPPDQG�LQYRFDWLRQ�XQWLO�\RX�IXOO\�XQGHUVWDQG�ZKDW�LW¦V�GRLQJ���,I�HYHU\WKLQJZRUNHG��LW¦V�D�PLUDFOH��0RUH�RIWHQ��\RX¦OO�ILQG�WKDW�\RXU�SURJUDP�KDV�D�EXJ��(GLW�DQGWU\�DJDLQ¢EXW�\RX�GRQ¦W�QHHG�WR�XVH�FKPRG�HDFK�WLPH��DV�WKDW�VKRXOG�£VWLFN¤�WR�WKHILOH���2I�FRXUVH��LI�WKH�EXJ�LV�WKDW�\RX�GLGQ¦W�XVH�FKPRG�FRUUHFWO\��\RX¦OO�SUREDEO\�JHW�D£SHUPLVVLRQ�GHQLHG¤�PHVVDJH�IURP�\RXU�VKHOO��

7KHUH¦V�DQRWKHU�ZD\�WR�ZULWH�WKLV�VLPSOH�SURJUDP�LQ�3HUO�������DQG�ZH�PLJKW�DV�ZHOOJHW�WKDW�RXW�RI�WKH�ZD\�ULJKW�QRZ��,QVWHDG�RI�print��ZH�XVH�say��ZKLFK�GRHV�DOPRVW�WKHVDPH�WKLQJ��EXW�ZLWK�OHVV�W\SLQJ��6LQFH�LW¦V�D�QHZ�IHDWXUH�DQG�\RX�PLJKW�QRW�EH�XVLQJ3HUO������\HW��ZH�LQFOXGH�D�use 5.010�VWDWHPHQW�WKDW�WHOOV�3HUO�WKDW�ZH�XVHG�QHZ�IHDWXUHV�

#!/usr/bin/perl

use 5.010;

:K\�LV�LW�EHWWHU�WR�KDYH�QR�H[WHQVLRQ"�,PDJLQH�WKDW�\RX¦YH�ZULWWHQ�D�SURJUDP�WR�FDOFXODWH�ERZOLQJ�VFRUHV�DQG\RX¦YH�WROG�DOO�RI�\RXU�IULHQGV�WKDW�LW¦V�FDOOHG�ERZOLQJ�SO[��2QH�GD\�\RX�GHFLGH�WR�UHZULWH�LW�LQ�&��'R�\RX�VWLOOFDOO�LW�E\�WKH�VDPH�QDPH��LPSO\LQJ�WKDW�LW¦V�VWLOO�ZULWWHQ�LQ�3HUO"�2U�GR�\RX�WHOO�HYHU\RQH�WKDW�LW�KDV�D�QHZQDPH"��$QG�GRQ¦W�FDOO�LW�ERZOLQJ�F��SOHDVH���7KH�DQVZHU�LV�WKDW�LW¦V�QRQH�RI�WKHLU�EXVLQHVV�ZKDW�ODQJXDJH�LW¦VZULWWHQ�LQ��LI�WKH\¦UH�PHUHO\�XVLQJ�LW��6R��LW�VKRXOG�KDYH�VLPSO\�EHHQ�FDOOHG�ERZOLQJ�LQ�WKH�ILUVW�SODFH�

� ,Q�VKRUW��LW¦V�SUHYHQWLQJ�\RXU�VKHOO�IURP�UXQQLQJ�DQRWKHU�SURJUDP��RU�VKHOO�EXLOW�LQ��RI�WKH�VDPH�QDPH��$FRPPRQ�PLVWDNH�DPRQJ�EHJLQQHUV�LV�WR�QDPH�WKHLU�ILUVW�SURJUDP�test��0DQ\�V\VWHPV�DOUHDG\�KDYH�D�SURJUDP�RU�VKHOO�EXLOW�LQ��ZLWK�WKDW�QDPH��WKDW¦V�ZKDW�WKH�EHJLQQHUV�UXQ�LQVWHDG�RI�WKHLU�SURJUDP�

How Do I Make a Perl Program? | 13

say "Hello World!";

7KLV�SURJUDP�RQO\�UXQV�XQGHU�3HUO�������:KHQ�ZH�LQWURGXFH�3HUO������IHDWXUHV�LQ�WKLVERRN��ZH¦OO�H[SOLFLWO\�VD\�WKH\�DUH�QHZ�IHDWXUHV�LQ�WKH�WH[W�DQG�LQFOXGH�WKDW�use 5.010VWDWHPHQW�WR�UHPLQG�\RX��3HUO�DFWXDOO\�WKLQNV�DERXW�WKH�PLQRU�YHUVLRQ�DV�D�WKUHH�GLJLWQXPEHU��VR�PDNH�VXUH�WKDW�\RX�VD\�use 5.010�DQG�QRW�use 5.10��ZKLFK�3HUO�WKLQNV�LV5.100��D�YHUVLRQ�ZH�GHILQLWHO\�GRQ¦W�KDYH�\HW��

What’s Inside That Program?/LNH�RWKHU�£IUHH�IRUP¤�ODQJXDJHV��3HUO�JHQHUDOO\�OHWV�\RX�XVH�LQVLJQLILFDQW�ZKLWHVSDFH�OLNH�VSDFHV��WDEV��DQG�QHZOLQHV��DW�ZLOO�WR�PDNH�\RXU�SURJUDP�HDVLHU�WR�UHDG��0RVW�3HUOSURJUDPV�XVH�D�IDLUO\�VWDQGDUG�IRUPDW��WKRXJK��PXFK�OLNH�PRVW�RI�ZKDW�ZH�VKRZ�KHUH�:H�VWURQJO\�HQFRXUDJH�\RX�WR�SURSHUO\�LQGHQW�\RXU�SURJUDPV��DV�WKDW�PDNHV�\RXU�SUR�JUDP�HDVLHU�WR�UHDG��D�JRRG�WH[W�HGLWRU�ZLOO�GR�PRVW�RI�WKH�ZRUN�IRU�\RX��*RRG�FRPPHQWVDOVR�PDNH�D�SURJUDP�HDVLHU�WR�UHDG��,Q�SHUO��FRPPHQWV�UXQ�IURP�D�SRXQG�VLJQ��#��WR�WKHHQG�RI�WKH�OLQH���7KHUH�DUH�QR�£EORFN�FRPPHQWV¤�LQ�3HUO� ��:H�GRQ¦W�XVH�PDQ\�FRPPHQWVLQ�WKH�SURJUDPV�LQ�WKLV�ERRN�EHFDXVH�WKH�VXUURXQGLQJ�WH[W�H[SODLQV�WKHLU�ZRUNLQJV��EXW\RX�VKRXOG�XVH�FRPPHQWV�DV�QHHGHG�LQ�\RXU�RZQ�SURJUDPV�

6R�DQRWKHU�ZD\��D�YHU\�VWUDQJH�ZD\��LW�PXVW�EH�VDLG��WR�ZULWH�WKDW�VDPH�£+HOOR��ZRUOG¤SURJUDP�PLJKW�EH�OLNH�WKLV�

#!/usr/bin/perl print # This is a comment"Hello, world!\n" ; # Don't write your Perl code like this!

7KDW�ILUVW�OLQH�LV�DFWXDOO\�D�YHU\�VSHFLDO�FRPPHQW��2Q�8QL[�V\VWHPV���LI�WKH�YHU\�ILUVWWZR�FKDUDFWHUV�RQ�WKH�ILUVW�OLQH�RI�D�WH[W�ILOH�DUH�#!��ZKDW�IROORZV�LV�WKH�QDPH�RI�WKHSURJUDP�WKDW�DFWXDOO\�H[HFXWHV�WKH�UHVW�RI�WKH�ILOH��,Q�WKLV�FDVH��WKH�SURJUDP�LV�VWRUHG�LQWKH�ILOH��XVU�ELQ�SHUO�

7KLV�#!�OLQH�LV�DFWXDOO\�WKH�OHDVW�SRUWDEOH�SDUW�RI�D�3HUO�SURJUDP�EHFDXVH�\RX¦OO�QHHG�WRILQG�RXW�ZKDW�JRHV�WKHUH�IRU�HDFK�PDFKLQH��)RUWXQDWHO\��LW¦V�DOPRVW�DOZD\V�HLWKHU��XVU�ELQ�SHUO�RU��XVU�ORFDO�ELQ�SHUO��,I�WKDW¦V�QRW�LW��\RX¦OO�KDYH�WR�ILQG�ZKHUH�\RXU�V\VWHP�LVKLGLQJ�SHUO��WKHQ�XVH�WKDW�SDWK��2Q�8QL[�V\VWHPV��\RX�PLJKW�XVH�D�VKHEDQJ�OLQH�WKDWILQGV�SHUO�IRU�\RX�

#!/usr/bin/env perl

,I�SHUO�LV�QRW�LQ�DQ\�RI�WKH�GLUHFWRULHV�LQ�\RXU�VHDUFK�SDWK��\RX�PLJKW�KDYH�WR�DVN�\RXUORFDO�V\VWHP�DGPLQLVWUDWRU�RU�VRPHERG\�XVLQJ�WKH�VDPH�V\VWHP�DV�\RX�

%XW� WKHUH� DUH� D� QXPEHU� RI� ZD\V� WR� IDNH� WKHP�� 6HH� WKH� )$4� �DFFHVVLEOH� ZLWK� SHUOGRF� SHUOIDT� RQ� PRVWLQVWDOODWLRQV��

� 0RVW�PRGHUQ�RQHV��DQ\ZD\��7KH�£VKHEDQJ¤�PHFKDQLVP�ZDV�LQWURGXFHG�VRPHZKHUH�LQ�WKH�PLG�����V��DQGWKDW¦V�SUHWW\�DQFLHQW��HYHQ�RQ�WKH�H[WHQVLYHO\�ORQJ�8QL[�WLPHOLQH�

14 | Chapter 1:ಗIntroduction

2Q�QRQ�8QL[�V\VWHPV��LW¦V�WUDGLWLRQDO��DQG�HYHQ�XVHIXO��WR�PDNH�WKH�ILUVW�OLQH�VD\�#!perl��,I�QRWKLQJ�HOVH��LW�WHOOV�\RXU�PDLQWHQDQFH�SURJUDPPHU�DV�VRRQ�DV�KH�JHWV�UHDG\�WRIL[�LW�WKDW�LW¦V�D�3HUO�SURJUDP�

,I�WKDW�#!�OLQH�LV�ZURQJ��\RX¦OO�JHQHUDOO\�JHW�DQ�HUURU�IURP�\RXU�VKHOO��7KLV�PD\�EH�VRPH�WKLQJ�XQH[SHFWHG��OLNH�£ILOH�QRW�IRXQG�¤�,W¦V�QRW�\RXU�SURJUDP�WKDW¦V�QRW�IRXQG��WKRXJK�LW¦V��XVU�ELQ�SHUO�WKDW�ZDVQ¦W�ZKHUH�LW�VKRXOG�KDYH�EHHQ��:H¦G�PDNH�WKH�PHVVDJH�FOHDUHU�EXW�LW¦V�QRW�FRPLQJ�IURP�3HUO��LW¦V�WKH�VKHOO�WKDW¦V�FRPSODLQLQJ���%\�WKH�ZD\��\RX�VKRXOGEH�FDUHIXO�WR�VSHOO�LW�XVU�DQG�QRW�XVHU¢WKH�IRONV�ZKR�LQYHQWHG�8QL[�ZHUH�OD]\�W\SLVWV�VR�WKH\�RPLWWHG�D�ORW�RI�OHWWHUV��

$QRWKHU�SUREOHP�\RX�FRXOG�KDYH�LV�WKDW�\RXU�V\VWHP�GRHVQ¦W�VXSSRUW�WKH�#!�OLQH�DW�DOO�,Q�WKDW�FDVH��\RXU�VKHOO��RU�ZKDWHYHU�\RXU�V\VWHP�XVHV��ZLOO�SUREDEO\�WU\�WR�UXQ�\RXUSURJUDP�DOO�E\� LWVHOI��ZLWK�UHVXOWV�WKDW�PD\�GLVDSSRLQW�RU�DVWRQLVK�\RX��,I�\RX�FDQ¦WILJXUH�RXW�ZKDW�VRPH�VWUDQJH�HUURU�PHVVDJH�LV�WHOOLQJ�\RX��VHDUFK�IRU�LW�LQ�WKH�SHUOGLDJPDQSDJH�

7KH�£PDLQ¤�SURJUDP�FRQVLVWV�RI�DOO�RI�WKH�RUGLQDU\�3HUO�VWDWHPHQWV��QRW�LQFOXGLQJ�DQ\�WKLQJ�LQ�VXEURXWLQHV��ZKLFK�\RX¦OO�VHH�ODWHU���7KHUH¦V�QR�£PDLQ¤�URXWLQH��DV�WKHUH�LV�LQODQJXDJHV�OLNH�&�RU�-DYD��,Q�IDFW��PDQ\�SURJUDPV�GRQ¦W�HYHQ�KDYH�URXWLQHV��LQ�WKH�IRUPRI�VXEURXWLQHV��

7KHUH¦V�DOVR�QR�UHTXLUHG�YDULDEOH�GHFODUDWLRQ�VHFWLRQ��DV� WKHUH� LV� LQ�VRPH�RWKHU� ODQ�JXDJHV��,I�\RX¦YH�DOZD\V�KDG�WR�GHFODUH�\RXU�YDULDEOHV��\RX�PD\�EH�VWDUWOHG�RU�XQVHWWOHGE\�WKLV�DW�ILUVW��%XW�LW�DOORZV�XV�WR�ZULWH�£TXLFN�DQG�GLUW\¤�3HUO�SURJUDPV��,I�\RXU�SURJUDPLV�RQO\�WZR�OLQHV�ORQJ��\RX�GRQ¦W�ZDQW�WR�KDYH�WR�XVH�RQH�RI�WKRVH�OLQHV�MXVW�WR�GHFODUH\RXU�YDULDEOHV��,I�\RX�UHDOO\�ZDQW�WR�GHFODUH�\RXU�YDULDEOHV��WKDW¦V�D�JRRG�WKLQJ��\RX¦OOVHH�KRZ�WR�GR�WKDW�LQ�&KDSWHU���

0RVW�VWDWHPHQWV�DUH�DQ�H[SUHVVLRQ�IROORZHG�E\�D�VHPLFRORQ��+HUH¦V�WKH�RQH�\RX¦YH�VHHQD�IHZ�WLPHV�VR�IDU�

print "Hello, world!\n";

$V�\RX�PD\�KDYH�JXHVVHG�E\�QRZ��WKLV�OLQH�SULQWV�WKH�PHVVDJH�Hello, world!��$W�WKHHQG�RI�WKDW�PHVVDJH�LV�WKH�VKRUWFXW�\n��ZKLFK�LV�SUREDEO\�IDPLOLDU�WR�\RX�LI�\RX¦YH�XVHGDQRWKHU�ODQJXDJH�OLNH�&��&����RU�-DYD��LW�PHDQV�D�QHZOLQH�FKDUDFWHU��:KHQ�WKDW¦V�SULQ�WHG�DIWHU�WKH�PHVVDJH��WKH�SULQW�SRVLWLRQ�GURSV�GRZQ�WR�WKH�VWDUW�RI�WKH�QH[W�OLQH��DO�ORZLQJ�WKH�IROORZLQJ�VKHOO�SURPSW�WR�DSSHDU�RQ�D�OLQH�RI�LWV�RZQ��UDWKHU�WKDQ�EHLQJDWWDFKHG�WR�WKH�PHVVDJH��(YHU\�OLQH�RI�RXWSXW�VKRXOG�HQG�ZLWK�D�QHZOLQH�FKDUDFWHU�:H¦OO�VHH�PRUH�DERXW�WKH�QHZOLQH�VKRUWFXW�DQG�RWKHU�VR�FDOOHG�EDFNVODVK�HVFDSHV�LQ�WKHQH[W�FKDSWHU�

How Do I Compile Perl?-XVW�UXQ�\RXU�3HUO�SURJUDP��7KH�SHUO�LQWHUSUHWHU�FRPSLOHV�DQG�WKHQ�UXQV�\RXU�SURJUDPLQ�RQH�XVHU�VWHS�

How Do I Make a Perl Program? | 15

$ perl my_program

:KHQ�\RX�UXQ�\RXU�SURJUDP��3HUO¦V�LQWHUQDO�FRPSLOHU�ILUVW�UXQV�WKURXJK�\RXU�HQWLUHVRXUFH��WXUQLQJ�LW�LQWR�LQWHUQDO�E\WHFRGH��ZKLFK�LV�DQ�LQWHUQDO�GDWD�VWUXFWXUH�UHSUHVHQWLQJWKH�SURJUDP��3HUO¦V�E\WHFRGH�HQJLQH�WDNHV�RYHU�DQG�DFWXDOO\�UXQV�WKH�E\WHFRGH��,I�WKHUH¦VD�V\QWD[�HUURU�RQ�OLQH������\RX¦OO�JHW�WKDW�HUURU�PHVVDJH�EHIRUH�\RX�VWDUW�UXQQLQJ�OLQH�� �,I�\RX�KDYH�D�ORRS�WKDW�UXQV������WLPHV��LW¦V�FRPSLOHG�MXVW�RQFH��WKH�DFWXDO�ORRS�FDQWKHQ�UXQ�DW�WRS�VSHHG��$QG�WKHUH¦V�QR�UXQWLPH�SHQDOW\�IRU�XVLQJ�DV�PDQ\�FRPPHQWVDQG�DV�PXFK�ZKLWHVSDFH�DV�\RX�QHHG�WR�PDNH�\RXU�SURJUDP�HDV\�WR�XQGHUVWDQG��<RXFDQ�HYHQ�XVH�FDOFXODWLRQV�LQYROYLQJ�RQO\�FRQVWDQWV��DQG�WKH�UHVXOW�LV�D�FRQVWDQW�FRP�SXWHG�RQFH�DV�WKH�SURJUDP�LV�EHJLQQLQJ¢QRW�HDFK�WLPH�WKURXJK�D�ORRS�

7R�EH�VXUH��WKLV�FRPSLODWLRQ�GRHV�WDNH�WLPH¢LW¦V�LQHIILFLHQW�WR�KDYH�D�YROXPLQRXV�3HUOSURJUDP�WKDW�GRHV�RQH�VPDOO�TXLFN�WDVN��RXW�RI�PDQ\�SRWHQWLDO�WDVNV��VD\��DQG�WKHQH[LWV�EHFDXVH�WKH�UXQWLPH�IRU�WKH�SURJUDP�ZLOO�EH�GZDUIHG�E\�WKH�FRPSLOH�WLPH��%XW�WKHFRPSLOHU�LV�YHU\�IDVW��QRUPDOO\�WKH�FRPSLODWLRQ�ZLOO�EH�D�WLQ\�SHUFHQWDJH�RI�WKH�UXQWLPH�

$Q�H[FHSWLRQ�PLJKW�EH�LI�\RX�ZHUH�ZULWLQJ�D�SURJUDP�UXQ�DV�D�&*,�VFULSW��ZKHUH�LW�PD\EH�FDOOHG�KXQGUHGV�RU�WKRXVDQGV�RI�WLPHV�HYHU\�PLQXWH���7KLV�LV�D�YHU\�KLJK�XVDJH�UDWH�,I�LW�ZHUH�FDOOHG�D�IHZ�KXQGUHG�RU�WKRXVDQG�WLPHV�SHU�GD\��OLNH�PRVW�SURJUDPV�RQ�WKH:HE��ZH�SUREDEO\�ZRXOGQ¦W�ZRUU\�WRR�PXFK�DERXW�LW���0DQ\�RI�WKHVH�SURJUDPV�KDYHYHU\�VKRUW�UXQWLPHV��VR�WKH�LVVXH�RI�UHFRPSLODWLRQ�PD\�EHFRPH�VLJQLILFDQW��,I�WKLV�LV�DQLVVXH� IRU�\RX��\RX¦OO�ZDQW� WR� ILQG�D�ZD\�WR�NHHS�\RXU�SURJUDP�LQ�PHPRU\�EHWZHHQLQYRFDWLRQV��7KH�mod_perl�H[WHQVLRQ�WR�WKH�$SDFKH�ZHE�VHUYHU��KWWS���SHUO�DSDFKH�RUJ�RU�3HUO�PRGXOHV�OLNH�CGI::Fast�FDQ�KHOS�\RX�

:KDW�LI�\RX�FRXOG�VDYH�WKH�FRPSLOHG�E\WHFRGH�WR�DYRLG�WKH�RYHUKHDG�RI�FRPSLODWLRQ"2U��HYHQ�EHWWHU��ZKDW�LI�\RX�FRXOG�WXUQ�WKH�E\WHFRGH�LQWR�DQRWKHU�ODQJXDJH��OLNH�&��DQGWKHQ� FRPSLOH� WKDW"�:HOO�� ERWK�RI� WKHVH� WKLQJV� DUH�SRVVLEOH� LQ� VRPH� FDVHV�� EXW� WKH\SUREDEO\�ZRQ¦W�PDNH�PRVW�SURJUDPV�DQ\�HDVLHU�WR�XVH��PDLQWDLQ��GHEXJ��RU�LQVWDOO��DQGWKH\�PD\�HYHQ�PDNH�\RXU�SURJUDP�VORZHU��3HUO���VKRXOG�GR�D�ORW�EHWWHU�LQ�WKLV�UHJDUG�DOWKRXJK�LW�LV�WRR�VRRQ�WR�WHOO��DV�ZH�ZULWH�WKLV��

A Whirlwind Tour of Perl6R��\RX�ZDQW�WR�VHH�D�UHDO�3HUO�SURJUDP�ZLWK�VRPH�PHDW"��,I�\RX�GRQ¦W��MXVW�SOD\�DORQJIRU�QRZ���+HUH�\RX�DUH�

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

8QOHVV�OLQH�WZR�KDSSHQV�WR�EH�D�FRPSLOH�WLPH�RSHUDWLRQ��OLNH�D�BEGIN�EORFN�RU�D�use�LQYRFDWLRQ�

16 | Chapter 1:ಗIntroduction

1RZ��WKH�ILUVW�WLPH�\RX�VHH�3HUO�FRGH�OLNH�WKLV��LW�FDQ�VHHP�SUHWW\�VWUDQJH���,Q�IDFW��HYHU\WLPH�\RX�VHH�3HUO�FRGH�OLNH�WKLV��LW�FDQ�VHHP�SUHWW\�VWUDQJH���%XW�OHW¦V�WDNH�LW�OLQH�E\�OLQH�DQG�VHH�ZKDW�WKLV�H[DPSOH�GRHV���7KHVH�H[SODQDWLRQV�DUH�YHU\�EULHI��WKLV�LV�D�ZKLUOZLQGWRXU��DIWHU�DOO��:H¦OO�VHH�DOO�RI�WKLV�SURJUDP¦V�IHDWXUHV�LQ�PRUH�GHWDLO�GXULQJ�WKH�UHVW�RIWKLV�ERRN��<RX¦UH�QRW�UHDOO\�VXSSRVHG�WR�XQGHUVWDQG�WKH�ZKROH�WKLQJ�XQWLO�ODWHU��

7KH�ILUVW�OLQH�LV�WKH�#!�OLQH��DV�\RX�VDZ�EHIRUH��<RX�PLJKW�QHHG�WR�FKDQJH�WKDW�OLQH�IRU\RXU�V\VWHP��DV�ZH�GLVFXVVHG�HDUOLHU�

7KH� VHFRQG� OLQH� UXQV�DQ�H[WHUQDO� FRPPDQG��QDPHG�ZLWKLQ�EDFNTXRWHV� �` `��� �7KHEDFNTXRWH�NH\�LV�RIWHQ�IRXQG�QH[W�WR�WKH�QXPEHU���RQ�IXOO�VL]HG�$PHULFDQ�NH\ERDUGV�%H�VXUH�QRW�WR�FRQIXVH�WKH�EDFNTXRWH�ZLWK�WKH�VLQJOH�TXRWH��'���7KH�FRPPDQG�ZH�XVHGLV�SHUOGRF��X��I�DWDQ���WU\�W\SLQJ�WKDW�DW�\RXU�FRPPDQG�OLQH�WR�VHH�ZKDW�LWV�RXWSXW�ORRNVOLNH��7KH�SHUOGRF�FRPPDQG�LV�XVHG�RQ�PRVW�V\VWHPV�WR�UHDG�DQG�GLVSOD\�WKH�GRFXPHQ�WDWLRQ�IRU�3HUO�DQG�LWV�DVVRFLDWHG�H[WHQVLRQV�DQG�XWLOLWLHV��VR�LW�VKRXOG�QRUPDOO\�EH�DYDLO�DEOH� �7KLV�FRPPDQG�WHOOV�\RX�VRPHWKLQJ�DERXW�WKH�WULJRQRPHWULF�IXQFWLRQ�atan2��ZH¦UHXVLQJ�LW�KHUH� MXVW�DV�DQ�H[DPSOH�RI�DQ�H[WHUQDO�FRPPDQG�ZKRVH�RXWSXW�ZH�ZLVK�WRSURFHVV�

7KH�RXWSXW�RI� WKDW�FRPPDQG�LQ�WKH�EDFNTXRWHV� LV�VDYHG�LQ�DQ�DUUD\�YDULDEOH�FDOOHG@lines��7KH�QH[W�OLQH�RI�FRGH�VWDUWV�D�ORRS�WKDW�ZLOO�SURFHVV�HDFK�RQH�RI�WKRVH�OLQHV�,QVLGH�WKH�ORRS��WKH�VWDWHPHQWV�DUH�LQGHQWHG��$OWKRXJK�3HUO�GRHVQ¦W�UHTXLUH�WKLV��JRRGSURJUDPPHUV�GR�

7KH�ILUVW�OLQH�LQVLGH�WKH�ORRS�ERG\�LV�WKH�VFDULHVW�RQH��LW�VD\V�s/\w<([^>]+)>/\U$1/g;�:LWKRXW�JRLQJ�LQWR�WRR�PXFK�GHWDLO��ZH¦OO�MXVW�VD\�WKDW�WKLV�FDQ�FKDQJH�DQ\�OLQH�WKDWKDV�D�VSHFLDO�PDUNHU�PDGH�ZLWK�DQJOH�EUDFNHWV��< >���DQG�WKHUH�VKRXOG�EH�DW�OHDVW�RQHRI�WKRVH�LQ�WKH�RXWSXW�RI�WKH�SHUOGRF�FRPPDQG�

7KH�QH[W�OLQH��LQ�D�VXUSULVH�PRYH��SULQWV�RXW�HDFK��SRVVLEO\�PRGLILHG��OLQH��7KH�UHVXOWLQJRXWSXW�VKRXOG�EH�VLPLODU�WR�ZKDW�SHUOGRF��X��I�DWDQ��ZRXOG�GR�RQ�LWV�RZQ��EXW�WKHUHZLOO�EH�D�FKDQJH�ZKHUH�DQ\�RI�WKRVH�PDUNHUV�DSSHDU�

7KXV��LQ�WKH�VSDQ�RI�D�IHZ�OLQHV��ZH¦YH�UXQ�DQRWKHU�SURJUDP��VDYHG�LWV�RXWSXW�LQ�PHPRU\�XSGDWHG�WKH�PHPRU\� LWHPV��DQG�SULQWHG� WKHP�RXW��7KLV�NLQG�RI�SURJUDP�LV�D� IDLUO\FRPPRQ�XVH�RI�3HUO��ZKHUH�RQH�W\SH�RI�GDWD�LV�FRQYHUWHG�WR�DQRWKHU�

Exercises1RUPDOO\�� HDFK� FKDSWHU�ZLOO� HQG�ZLWK� VRPH� H[HUFLVHV��ZLWK� WKH� DQVZHUV� LQ�$SSHQ�GL[�$��%XW�\RX�GRQ¦W�QHHG�WR�ZULWH�WKH�SURJUDPV�QHHGHG�WR�FRPSOHWH�WKLV�VHFWLRQ¢WKRVH�DUH�VXSSOLHG�ZLWKLQ�WKH�FKDSWHU�WH[W�

,I�SHUOGRF�LV�QRW�DYDLODEOH��WKDW�SUREDEO\�PHDQV�WKDW�\RXU�V\VWHP�GRHVQ¦W�KDYH�D�FRPPDQG�OLQH�LQWHUIDFH��DQG\RXU� 3HUO� FDQ¦W� UXQ� FRPPDQGV� �OLNH� SHUOGRF�� LQ� EDFNTXRWHV� RU� YLD� WKH� SLSHG� RSHQ�� ZKLFK� \RX¦OO� VHH� LQ&KDSWHU�����,Q�WKDW�FDVH��\RX�VKRXOG�VLPSO\�VNLS�WKH�H[HUFLVHV�WKDW�XVH�SHUOGRF�

Exercises | 17

,I�\RX�FDQ¦W�JHW�WKHVH�H[HUFLVHV�WR�ZRUN�RQ�\RXU�PDFKLQH��GRXEOH�FKHFN�\RXU�ZRUN�DQGWKHQ�FRQVXOW�\RXU�ORFDO�H[SHUW��5HPHPEHU�WKDW�\RX�PD\�QHHG�WR�WZHDN�HDFK�SURJUDPD�OLWWOH��DV�GHVFULEHG�LQ�WKH�WH[W�

�� >�@�7\SH� LQ� WKH�£+HOOR��ZRUOG¤�SURJUDP�DQG�JHW� LW� WR�ZRUN�� �<RX�PD\�QDPH� LWDQ\WKLQJ�\RX�ZLVK��EXW�D�JRRG�QDPH�PLJKW�EH�ex1-1��IRU�VLPSOLFLW\��VLQFH�LW¦V�H[�HUFLVH���LQ�&KDSWHU����

�� >�@�7\SH� WKH�FRPPDQG�SHUOGRF� �X� �I� DWDQ�� DW� D� FRPPDQG�SURPSW�DQG�QRWH� LWVRXWSXW��,I�\RX�FDQ¦W�JHW�WKDW�WR�ZRUN��ILQG�RXW�IURP�D�ORFDO�DGPLQLVWUDWRU�RU�WKHGRFXPHQWDWLRQ�IRU�\RXU�YHUVLRQ�RI�3HUO�DERXW�KRZ�WR�LQYRNH�SHUOGRF�RU�LWV�HTXLY�DOHQW���<RX¦OO�QHHG�WKLV�IRU�WKH�QH[W�H[HUFLVH�DQ\ZD\��

�� >�@�7\SH�LQ�WKH�VHFRQG�H[DPSOH�SURJUDP��IURP�WKH�SUHYLRXV�VHFWLRQ��DQG�VHH�ZKDWLW�SULQWV���+LQW��EH�FDUHIXO�WR�W\SH�WKRVH�SXQFWXDWLRQ�PDUNV�H[DFWO\�DV�VKRZQ���'R\RX�VHH�KRZ�LW�FKDQJHG�WKH�RXWSXW�RI�WKH�FRPPDQG"

18 | Chapter 1:ಗIntroduction

CHAPTER 2

Scalar Data

,Q�(QJOLVK��DV�LQ�PDQ\�RWKHU�VSRNHQ�ODQJXDJHV��\RX¦UH�XVHG�WR�GLVWLQJXLVKLQJ�EHWZHHQVLQJXODU�DQG�SOXUDO��$V�D�FRPSXWHU�ODQJXDJH�GHVLJQHG�E\�D�KXPDQ�OLQJXLVW��3HUO�LV�VLP�LODU��$V�D�JHQHUDO�UXOH��ZKHQ�3HUO�KDV�MXVW�RQH�RI�VRPHWKLQJ��WKDW¦V�D�VFDODU� �$�VFDODU�LVWKH�VLPSOHVW�NLQG�RI�GDWD�WKDW�3HUO�PDQLSXODWHV��0RVW�VFDODUV�DUH�HLWKHU�D�QXPEHU��OLNH���� RU� ����H���� RU� D� VWULQJ� RI� FKDUDFWHUV� �OLNH� hello�� RU� WKH�*HWW\VEXUJ� $GGUHVV��$OWKRXJK�\RX�PD\�WKLQN�RI�QXPEHUV�DQG�VWULQJV�DV�YHU\�GLIIHUHQW�WKLQJV��3HUO�XVHV�WKHPQHDUO\�LQWHUFKDQJHDEO\�

$�VFDODU�YDOXH�FDQ�EH�DFWHG�XSRQ�ZLWK�RSHUDWRUV��OLNH�DGGLWLRQ�RU�FRQFDWHQDWLRQ���JHQ�HUDOO\�\LHOGLQJ�D�VFDODU�UHVXOW��$�VFDODU�YDOXH�FDQ�EH�VWRUHG�LQWR�D�VFDODU�YDULDEOH��6FDODUVFDQ�EH�UHDG�IURP�ILOHV�DQG�GHYLFHV��DQG�FDQ�EH�ZULWWHQ�RXW�DV�ZHOO�

Numbers$OWKRXJK�D�VFDODU�LV�PRVW�RIWHQ�HLWKHU�D�QXPEHU�RU�D�VWULQJ��LW¦V�XVHIXO�WR�ORRN�DW�QXPEHUVDQG�VWULQJV�VHSDUDWHO\�IRU�WKH�PRPHQW��:H¦OO�FRYHU�QXPEHUV�ILUVW��DQG�WKHQ�PRYH�RQ�WRVWULQJV�

7KLV�KDV�OLWWOH�WR�GR�ZLWK�WKH�VLPLODU�WHUP�IURP�PDWKHPDWLFV�RU�SK\VLFV�LQ�WKDW�D�VFDODU�LV�D�VLQJOH�WKLQJ��WKHUHDUH�QR�£YHFWRUV¤�LQ�3HUO�

� ,I�\RX�KDYH�EHHQ�XVLQJ�RWKHU�SURJUDPPLQJ�ODQJXDJHV��\RX�PD\�WKLQN�RI�hello�DV�D�FROOHFWLRQ�RI�ILYH�FKDUDFWHUV�UDWKHU�WKDQ�DV�D�VLQJOH�WKLQJ��%XW�LQ�3HUO��D�VWULQJ�LV�D�VLQJOH�VFDODU�YDOXH��2I�FRXUVH��\RX�FDQ�DFFHVV�WKH�LQGLYLGXDOFKDUDFWHUV�ZKHQ�\RX�QHHG�WR��\RX¦OO�VHH�KRZ�WR�GR�WKDW�LQ�ODWHU�FKDSWHUV�

19

All Numbers Have the Same Format Internally$V�\RX¦OO�VHH�LQ�WKH�QH[W�IHZ�SDUDJUDSKV��\RX�FDQ�VSHFLI\�ERWK�LQWHJHUV��ZKROH�QXPEHUV�OLNH�����RU�������DQG�IORDWLQJ�SRLQW�QXPEHUV��UHDO�QXPEHUV�ZLWK�GHFLPDO�SRLQWV��OLNH���������RU���������������%XW�LQWHUQDOO\��3HUO�FRPSXWHV�ZLWK�GRXEOH�SUHFLVLRQ�IORDWLQJ�SRLQW�YDOXHV� �7KLV�PHDQV�WKDW�WKHUH�DUH�QR�LQWHJHU�YDOXHV�LQWHUQDO�WR�3HUO¢DQ�LQWHJHUFRQVWDQW�LQ�WKH�SURJUDP�LV�WUHDWHG�DV�WKH�HTXLYDOHQW�IORDWLQJ�SRLQW�YDOXH���<RX�SUREDEO\ZRQ¦W�QRWLFH�WKH�FRQYHUVLRQ��RU�FDUH�PXFK���EXW�\RX�VKRXOG�VWRS�ORRNLQJ�IRU�GLVWLQFWLQWHJHU�RSHUDWLRQV��DV�RSSRVHG�WR�IORDWLQJ�SRLQW�RSHUDWLRQV��EHFDXVH�WKHUH�DUHQ¦W�DQ\��®

Floating-Point Literals$�OLWHUDO�LV�WKH�ZD\�D�YDOXH�LV�UHSUHVHQWHG�LQ�WKH�VRXUFH�FRGH�RI�WKH�3HUO�SURJUDP��$�OLWHUDOLV�QRW�WKH�UHVXOW�RI�D�FDOFXODWLRQ�RU�DQ�,�2�RSHUDWLRQ��LW¦V�GDWD�ZULWWHQ�GLUHFWO\�LQWR�WKHVRXUFH�FRGH�

3HUO¦V�IORDWLQJ�SRLQW�OLWHUDOV�VKRXOG�ORRN�IDPLOLDU�WR�\RX��1XPEHUV�ZLWK�DQG�ZLWKRXWGHFLPDO�SRLQWV�DUH�DOORZHG� �LQFOXGLQJ�DQ�RSWLRQDO�SOXV�RU�PLQXV�SUHIL[���DV�ZHOO�DVWDFNLQJ� RQ� D� SRZHU�RI���� LQGLFDWRU� �H[SRQHQWLDO� QRWDWLRQ�� ZLWK� (� QRWDWLRQ�� )RUH[DPSOH�

1.25255.000255.07.25e45 # 7.25 times 10 to the 45th power (a big number)!6.5e24 # negative 6.5 times 10 to the 24th # (a big negative number)!12e-24 # negative 12 times 10 to the !24th # (a very small negative number)!1.2E-23 # another way to say that - the E may be uppercase

Integer Literals,QWHJHU�OLWHUDOV�DUH�DOVR�VWUDLJKWIRUZDUG��DV�LQ�

02001!40

$�GRXEOH�SUHFLVLRQ� IORDWLQJ�SRLQW�YDOXH� LV�ZKDWHYHU� WKH�&�FRPSLOHU� WKDW�FRPSLOHG�3HUO�XVHG� IRU�D�doubleGHFODUDWLRQ��:KLOH�WKH�VL]H�PD\�YDU\� IURP�PDFKLQH�WR�PDFKLQH��PRVW�PRGHUQ�V\VWHPV�XVH�WKH�,(((����IRUPDW��ZKLFK�VXJJHVWV����GLJLWV�RI�SUHFLVLRQ�DQG�D�UDQJH�RI�DW�OHDVW�1e-100�WR�1e100�

� :HOO��3HUO�ZLOO�VRPHWLPHV�XVH�LQWHUQDO�LQWHJHUV�LQ�ZD\V�WKDW�DUH�QRW�YLVLEOH�WR�WKH�SURJUDPPHU��7KDW�LV��WKHRQO\�GLIIHUHQFH�\RX�VKRXOG�JHQHUDOO\�EH�DEOH�WR�VHH�LV�WKDW�\RXU�SURJUDP�UXQV�IDVWHU��$QG�ZKR�FRXOG�FRPSODLQDERXW�WKDW"

® 2ND\��WKHUH�LV�WKH�integer�SUDJPD��%XW�XVLQJ�WKDW�LV�EH\RQG�WKH�VFRSH�RI�WKLV�ERRN��$QG�\HV��VRPH�RSHUDWLRQVFRPSXWH�DQ�LQWHJHU�IURP�D�JLYHQ�IORDWLQJ�SRLQW�QXPEHU��DV�\RX¦OO�VHH�ODWHU��%XW�WKDW¦V�QRW�ZKDW�ZH¦UH�WDONLQJDERXW�KHUH�

20 | Chapter 2:ಗScalar Data

25561298040283768

7KDW�ODVW�RQH�LV�D�OLWWOH�KDUG�WR�UHDG��3HUO�DOORZV�XQGHUVFRUHV�IRU�FODULW\�ZLWKLQ�LQWHJHUOLWHUDOV��VR�\RX�FDQ�DOVR�ZULWH�WKDW�QXPEHU�OLNH�WKLV�

61_298_040_283_768

,W¦V� WKH� VDPH� YDOXH�� LW�PHUHO\� ORRNV�GLIIHUHQW� WR�XV�KXPDQ�EHLQJV��<RX�PLJKW�KDYHWKRXJKW�WKDW�FRPPDV�VKRXOG�EH�XVHG�IRU�WKLV�SXUSRVH��EXW�FRPPDV�DUH�DOUHDG\�XVHGIRU�D�PRUH�LPSRUWDQW�SXUSRVH�LQ�3HUO��DV�\RX¦OO�VHH�LQ�WKH�QH[W�FKDSWHU��

Nondecimal Integer Literals/LNH�PDQ\�RWKHU�SURJUDPPLQJ�ODQJXDJHV��3HUO�DOORZV�\RX�WR�VSHFLI\�QXPEHUV�LQ�RWKHUWKDQ�EDVH�����GHFLPDO���2FWDO��EDVH����OLWHUDOV�VWDUW�ZLWK�D�OHDGLQJ�0��KH[DGHFLPDO��EDVH����OLWHUDOV�VWDUW�ZLWK�D�OHDGLQJ�0x��DQG�ELQDU\��EDVH����OLWHUDOV�VWDUW�ZLWK�D�OHDGLQJ�0b�

7KH�KH[�GLJLWV�A�WKURXJK�F��RU�a�WKURXJK�f��UHSUHVHQW�WKH�FRQYHQWLRQDO�GLJLW�YDOXHV�RI���WKURXJK�����)RU�H[DPSOH�

0377 # 377 octal, same as 255 decimal0xff # FF hex, also 255 decimal0b11111111 # also 255 decimal

$OWKRXJK�WKHVH�YDOXHV�ORRN�GLIIHUHQW�WR�XV�KXPDQV��WKH\¦UH�DOO�WKUHH�WKH�VDPH�QXPEHUWR�3HUO��,W�PDNHV�QR�GLIIHUHQFH�WR�3HUO�ZKHWKHU�\RX�ZULWH�0xFF�RU�255.000��VR�FKRRVH�WKHUHSUHVHQWDWLRQ�WKDW�PDNHV�WKH�PRVW�VHQVH�WR�\RX�DQG�\RXU�PDLQWHQDQFH�SURJUDPPHU�E\�ZKLFK�ZH�PHDQ�WKH�SRRU�FKDS�ZKR�JHWV�VWXFN�WU\LQJ�WR�ILJXUH�RXW�ZKDW�\RX�PHDQWZKHQ�\RX�ZURWH�\RXU�FRGH��PRVW�RIWHQ��WKLV�SRRU�FKDS�LV�\RX��DQG�\RX�FDQ¦W�UHFDOO�ZK\\RX�GLG�ZKDW�\RX�GLG�WKUHH�PRQWKV�DJR��

:KHQ�D�QRQGHFLPDO�OLWHUDO�LV�PRUH�WKDQ�DERXW�IRXU�FKDUDFWHUV�ORQJ��LW�PD\�EH�KDUG�WRUHDG��)RU�WKLV�UHDVRQ��3HUO�DOORZV�XQGHUVFRUHV�IRU�FODULW\�ZLWKLQ�WKHVH�OLWHUDOV�

0x1377_0B770x50_65_72_7C

Numeric Operators3HUO�SURYLGHV�WKH�W\SLFDO�RUGLQDU\�DGGLWLRQ��VXEWUDFWLRQ��PXOWLSOLFDWLRQ��DQG�GLYLVLRQRSHUDWRUV��DQG�VR�RQ��)RU�H[DPSOH�

2 + 3 # 2 plus 3, or 55.1 ! 2.4 # 5.1 minus 2.4, or 2.73 * 12 # 3 times 12 = 3614 / 2 # 14 divided by 2, or 7

7KH�£OHDGLQJ�]HUR¤�LQGLFDWRU�ZRUNV�RQO\�IRU�OLWHUDOV¢QRW�IRU�DXWRPDWLF�VWULQJ�WR�QXPEHU�FRQYHUVLRQV��ZKLFK\RX¦OO�VHH�ODWHU�LQ�WKLV�FKDSWHU��<RX�FDQ�FRQYHUW�D�GDWD�VWULQJ�WKDW�ORRNV�OLNH�DQ�RFWDO�RU�KH[�YDOXH�LQWR�D�QXPEHUZLWK�oct( )�RU�hex( )��$OWKRXJK�WKHUH¦V�QR�bin�IXQFWLRQ�IRU�FRQYHUWLQJ�ELQDU\�YDOXHV��oct( )�FDQ�GR�WKDW�IRUVWULQJV�EHJLQQLQJ�ZLWK�0b�

Numbers | 21

10.2 / 0.3 # 10.2 divided by 0.3, or 3410 / 3 # always floating-point divide, so 3.3333333...

3HUO�DOVR�VXSSRUWV�D�PRGXOXV�RSHUDWRU��%���7KH�YDOXH�RI�WKH�H[SUHVVLRQ�10 % 3�LV�WKHUHPDLQGHU�ZKHQ����LV�GLYLGHG�E\����ZKLFK�LV�RQH��%RWK�YDOXHV�DUH�ILUVW�UHGXFHG�WR�WKHLULQWHJHU�YDOXHV��VR�10.5 % 3.2�LV�FRPSXWHG�DV�10 % 3� �$GGLWLRQDOO\��3HUO�SURYLGHV�WKH)2575$1�OLNH�H[SRQHQWLDWLRQ�RSHUDWRU��ZKLFK�PDQ\�KDYH�\HDUQHG�IRU�LQ�3DVFDO�DQG&��7KH�RSHUDWRU�LV�UHSUHVHQWHG�E\�WKH�GRXEOH�DVWHULVN��VXFK�DV�2**3��ZKLFK�LV�WZR�WR�WKHWKLUG�SRZHU��RU� HLJKW��� ,Q�DGGLWLRQ�� WKHUH�DUH�RWKHU�QXPHULF�RSHUDWRUV��ZKLFK�ZH¦OOLQWURGXFH�DV�ZH�QHHG�WKHP�

Strings6WULQJV�DUH�VHTXHQFHV�RI�FKDUDFWHUV��OLNH�hello���6WULQJV�PD\�FRQWDLQ�DQ\�FRPELQDWLRQRI�DQ\�FKDUDFWHUV�®�7KH�VKRUWHVW�SRVVLEOH�VWULQJ�KDV�QR�FKDUDFWHUV��7KH�ORQJHVW�VWULQJILOOV�DOO�RI�\RXU�DYDLODEOH�PHPRU\��DOWKRXJK�\RX�ZRXOGQ¦W�EH�DEOH�WR�GR�PXFK�ZLWK�WKDW��7KLV�LV�LQ�DFFRUGDQFH�ZLWK�WKH�SULQFLSOH�RI�£QR�EXLOW�LQ�OLPLWV¤�WKDW�3HUO�IROORZV�DW�HYHU\RSSRUWXQLW\��7\SLFDO�VWULQJV�DUH�SULQWDEOH�VHTXHQFHV�RI�OHWWHUV�DQG�GLJLWV�DQG�SXQFWX�DWLRQ�LQ�WKH�$6&,,����WR�$6&,,�����UDQJH��+RZHYHU��WKH�DELOLW\�WR�KDYH�DQ\�FKDUDFWHULQ�D�VWULQJ�PHDQV�\RX�FDQ�FUHDWH��VFDQ��DQG�PDQLSXODWH�UDZ�ELQDU\�GDWD�DV�VWULQJV¢VRPHWKLQJ�ZLWK�ZKLFK�PDQ\�RWKHU�XWLOLWLHV�ZRXOG�KDYH�JUHDW�GLIILFXOW\��)RU�H[DPSOH�\RX�FRXOG�XSGDWH�D�JUDSKLFDO�LPDJH�RU�FRPSLOHG�SURJUDP�E\�UHDGLQJ�LW�LQWR�D�3HUO�VWULQJ�PDNLQJ�WKH�FKDQJH��DQG�ZULWLQJ�WKH�UHVXOW�EDFN�RXW�

/LNH�QXPEHUV��VWULQJV�KDYH�D�OLWHUDO�UHSUHVHQWDWLRQ��ZKLFK�LV�WKH�ZD\�\RX�UHSUHVHQW�WKHVWULQJ�LQ�D�3HUO�SURJUDP��/LWHUDO�VWULQJV�FRPH�LQ�WZR�GLIIHUHQW�IODYRUV��VLQJOH�TXRWHG�VWULQJOLWHUDOV�DQG�GRXEOH�TXRWHG�VWULQJ�OLWHUDOV�

Single-Quoted String Literals$�VLQJOH�TXRWHG�VWULQJ�OLWHUDO�LV�D�VHTXHQFH�RI�FKDUDFWHUV�HQFORVHG�LQ�VLQJOH�TXRWHV��7KHVLQJOH�TXRWHV�DUH�QRW�SDUW�RI�WKH�VWULQJ�LWVHOI¢WKH\¦UH�MXVW�WKHUH�WR�OHW�3HUO�LGHQWLI\�WKHEHJLQQLQJ�DQG�WKH�HQGLQJ�RI�WKH�VWULQJ��$Q\�FKDUDFWHU�RWKHU�WKDQ�D�VLQJOH�TXRWH�RU�DEDFNVODVK�EHWZHHQ�WKH�TXRWH�PDUNV��LQFOXGLQJ�QHZOLQH�FKDUDFWHUV��LI�WKH�VWULQJ�FRQWLQ�XHV�RQWR�VXFFHVVLYH�OLQHV��VWDQGV�IRU�LWVHOI�LQVLGH�D�VWULQJ��7R�JHW�D�EDFNVODVK��SXW�WZREDFNVODVKHV�LQ�D�URZ��DQG�WR�JHW�D�VLQJOH�TXRWH��SXW�D�EDFNVODVK�IROORZHG�E\�D�VLQJOHTXRWH��,Q�RWKHU�ZRUGV�

7KH� UHVXOW� RI� D�PRGXOXV� RSHUDWRU�ZKHQ� D� QHJDWLYH� QXPEHU� �RU� WZR�� LV� LQYROYHG� FDQ� YDU\� EHWZHHQ� 3HUOLPSOHPHQWDWLRQV��%HZDUH�

� <RX�FDQ¦W�QRUPDOO\�UDLVH�D�QHJDWLYH�QXPEHU�WR�D�QRQLQWHJHU�H[SRQHQW��0DWK�JHHNV�NQRZ�WKDW�WKH�UHVXOW�ZRXOGEH�D�FRPSOH[�QXPEHU��7R�PDNH�WKDW�SRVVLEOH��\RX¦OO�QHHG�WKH�KHOS�RI�WKH�Math::Complex�PRGXOH�

® 8QOLNH�&�RU�&����WKHUH¦V�QRWKLQJ�VSHFLDO�DERXW�WKH�18/�FKDUDFWHU�LQ�3HUO�EHFDXVH�3HUO�XVHV�OHQJWK�FRXQWLQJ�QRW�D�QXOO�E\WH��WR�GHWHUPLQH�WKH�HQG�RI�WKH�VWULQJ�

22 | Chapter 2:ಗScalar Data

'fred' # those four characters: f, r, e, and d'barney' # those six characters'' # the null string (no characters)'Don\'t let an apostrophe end this string prematurely!''the last character of this string is a backslash: \\''hello\n' # hello followed by backslash followed by n'hellothere' # hello, newline, there (11 characters total)'\'\\' # single quote followed by backslash

1RWH�WKDW�WKH�\n�ZLWKLQ�D�VLQJOH�TXRWHG�VWULQJ�LV�QRW�LQWHUSUHWHG�DV�D�QHZOLQH��EXW�DV�WKHWZR�FKDUDFWHUV�EDFNVODVK�DQG�n��2QO\�ZKHQ�WKH�EDFNVODVK�LV�IROORZHG�E\�DQRWKHU�EDFN�VODVK�RU�D�VLQJOH�TXRWH�GRHV�LW�KDYH�VSHFLDO�PHDQLQJ�

Double-Quoted String Literals$�GRXEOH�TXRWHG�VWULQJ�OLWHUDO�LV�VLPLODU�WR�WKH�VWULQJV�\RX�PD\�KDYH�VHHQ�LQ�RWKHU�ODQ�JXDJHV��2QFH�DJDLQ��LW¦V�D�VHTXHQFH�RI�FKDUDFWHUV��DOWKRXJK�WKLV�WLPH�HQFORVHG�LQ�GRXEOHTXRWHV��%XW�QRZ�WKH�EDFNVODVK�WDNHV�RQ�LWV�IXOO�SRZHU�WR�VSHFLI\�FHUWDLQ�FRQWURO�FKDU�DFWHUV��RU�HYHQ�DQ\�FKDUDFWHU�DW�DOO�WKURXJK�RFWDO�DQG�KH[�UHSUHVHQWDWLRQV��+HUH�DUH�VRPHGRXEOH�TXRWHG�VWULQJV�

"barney" # just the same as 'barney'"hello world\n" # hello world, and a newline"The last character of this string is a quote mark: \"""coke\tsprite" # coke, a tab, and sprite

1RWH�WKDW�WKH�GRXEOH�TXRWHG�OLWHUDO�VWULQJ�"barney"�PHDQV�WKH�VDPH�VL[�FKDUDFWHU�VWULQJWR�3HUO�DV�GRHV�WKH�VLQJOH�TXRWHG�OLWHUDO�VWULQJ�'barney'�� ,W¦V� OLNH�ZKDW�\RX�VDZ�ZLWKQXPHULF�OLWHUDOV��ZKHUH�\RX�VDZ�WKDW�0377�ZDV�DQRWKHU�ZD\�WR�ZULWH�255.0��3HUO�OHWV�\RXZULWH�WKH�OLWHUDO�LQ�WKH�ZD\�WKDW�PDNHV�PRUH�VHQVH�WR�\RX��2I�FRXUVH��LI�\RX�ZLVK�WR�XVHD�EDFNVODVK�HVFDSH��OLNH�\n�WR�PHDQ�D�QHZOLQH�FKDUDFWHU���\RX¦OO�QHHG�WR�XVH�WKH�GRXEOHTXRWHV�

7KH�EDFNVODVK�FDQ�SUHFHGH�PDQ\�GLIIHUHQW�FKDUDFWHUV�WR�PHDQ�GLIIHUHQW�WKLQJV��JHQHUDOO\FDOOHG�D�EDFNVODVK�HVFDSH���7KH�QHDUO\�FRPSOHWH �OLVW�RI�GRXEOH�TXRWHG�VWULQJ�HVFDSHV�LVJLYHQ�LQ�7DEOH�����

7DEOH������'RXEOH�TXRWHG�VWULQJ�EDFNVODVK�HVFDSHV

Construct Meaning

\n Newline

\r Return

\t Tab

\f Form-feed

\b Backspace

5HFHQW�YHUVLRQV�RI�3HUO�KDYH�LQWURGXFHG�£8QLFRGH¤�HVFDSHV��ZKLFK�ZH�DUHQ¦W�JRLQJ�WR�VKRZ�\RX�KHUH�

Strings | 23

Construct Meaning

\a Bell

\e Escape (ASCII escape character)

\007 Any octal ASCII value (here, 007 = bell)

\x7f Any hex ASCII value (here, 7f = delete)

\cC A “control” character (here, Control-C)

\\ Backslash

\” Double quote

\l Lowercase next letter

\L Lowercase all following letters until \E

\u Uppercase next letter

\U Uppercase all following letters until \E

\Q Quote nonword characters by adding a backslash until \E

\E End \L, \U, or \Q

$QRWKHU�IHDWXUH�RI�GRXEOH�TXRWHG�VWULQJV�LV�WKDW�WKH\�DUH�YDULDEOH�LQWHUSRODWHG��PHDQLQJWKDW�VRPH�YDULDEOH�QDPHV�ZLWKLQ�WKH�VWULQJ�DUH�UHSODFHG�ZLWK�WKHLU�FXUUHQW�YDOXHV�ZKHQWKH�VWULQJV�DUH�XVHG��<RX�KDYHQ¦W�IRUPDOO\�EHHQ�LQWURGXFHG�WR�ZKDW�D�YDULDEOH�ORRNV�OLNH\HW��VR�ZH¦OO�JHW�EDFN�WR�WKDW�ODWHU�LQ�WKLV�FKDSWHU�

String Operators6WULQJ�YDOXHV�FDQ�EH�FRQFDWHQDWHG�ZLWK�WKH�.�RSHUDWRU���<HV��WKDW¦V�D�VLQJOH�SHULRG���7KLVGRHV�QRW�DOWHU�HLWKHU�VWULQJ��DQ\�PRUH�WKDQ�2+3�DOWHUV�HLWKHU�2�RU�3��7KH�UHVXOWLQJ��ORQJHU�VWULQJ� LV� WKHQ� DYDLODEOH� IRU� IXUWKHU� FRPSXWDWLRQ� RU� DVVLJQPHQW� WR� D� YDULDEOH�� )RUH[DPSOH�

"hello" . "world" # same as "helloworld""hello" . ' ' . "world" # same as 'hello world''hello world' . "\n" # same as "hello world\n"

1RWH�WKDW�WKH�FRQFDWHQDWLRQ�PXVW�EH�H[SOLFLWO\�UHTXHVWHG�ZLWK�WKH�.�RSHUDWRU��XQOLNHLQ�VRPH�RWKHU�ODQJXDJHV�ZKHUH�\RX�PHUHO\�KDYH�WR�VWLFN�WKH�WZR�YDOXHV�QH[W�WR�HDFKRWKHU�

$� VSHFLDO� VWULQJ� RSHUDWRU� LV� WKH� VWULQJ� UHSHWLWLRQ� RSHUDWRU�� FRQVLVWLQJ� RI� WKH� VLQJOHORZHUFDVH�OHWWHU�x��7KLV�RSHUDWRU�WDNHV�LWV�OHIW�RSHUDQG��D�VWULQJ��DQG�PDNHV�DV�PDQ\FRQFDWHQDWHG�FRSLHV�RI�WKDW�VWULQJ�DV�LQGLFDWHG�E\�LWV�ULJKW�RSHUDQG��D�QXPEHU���)RUH[DPSOH�

"fred" x 3 # is "fredfredfred""barney" x (4+1) # is "barney" " 5, or "barneybarneybarneybarneybarney"5 " 4 # is really "5" " 4, which is "5555"

24 | Chapter 2:ಗScalar Data

7KDW�ODVW�H[DPSOH�LV�ZRUWK�VSHOOLQJ�RXW�VORZO\��7KH�VWULQJ�UHSHWLWLRQ�RSHUDWRU�ZDQWV�DVWULQJ�IRU�D�OHIW�RSHUDQG��VR�WKH�QXPEHU�5� LV�FRQYHUWHG�WR�WKH�VWULQJ�"5"��XVLQJ�UXOHVGHVFULEHG�LQ�GHWDLO�ODWHU���JLYLQJ�D�RQH�FKDUDFWHU�VWULQJ��7KLV�QHZ�VWULQJ�LV�WKHQ�FRSLHGIRXU�WLPHV��\LHOGLQJ�WKH�IRXU�FKDUDFWHU�VWULQJ�5555��1RWH�WKDW�LI�\RX�KDG�UHYHUVHG�WKHRUGHU�RI�WKH�RSHUDQGV��DV�4 " 5��\RX�ZRXOG�KDYH�PDGH�ILYH�FRSLHV�RI�WKH�VWULQJ�4��\LHOGLQJ44444��7KLV�VKRZV�WKDW�VWULQJ�UHSHWLWLRQ�LV�QRW�FRPPXWDWLYH�

7KH�FRS\�FRXQW��WKH�ULJKW�RSHUDQG��LV�ILUVW�WUXQFDWHG�WR�DQ�LQWHJHU�YDOXH������EHFRPHV���EHIRUH�EHLQJ�XVHG��$�FRS\�FRXQW�RI�OHVV�WKDQ�RQH�UHVXOWV�LQ�DQ�HPSW\��]HUR�OHQJWK�VWULQJ�

Automatic Conversion Between Numbers and Strings)RU�WKH�PRVW�SDUW��3HUO�DXWRPDWLFDOO\�FRQYHUWV�EHWZHHQ�QXPEHUV�DQG�VWULQJV�DV�QHHGHG�+RZ�GRHV�LW�NQRZ�ZKLFK�LV�QHHGHG"�,W�DOO�GHSHQGV�XSRQ�WKH�RSHUDWRU�EHLQJ�XVHG�RQ�WKHVFDODU�YDOXH��,I�DQ�RSHUDWRU�H[SHFWV�D�QXPEHU��OLNH�+�GRHV���3HUO�ZLOO�VHH�WKH�YDOXH�DV�DQXPEHU��,I�DQ�RSHUDWRU�H[SHFWV�D�VWULQJ��OLNH�.�GRHV���3HUO�ZLOO�VHH�WKH�YDOXH�DV�D�VWULQJ�6R�\RX�GRQ¦W�QHHG�WR�ZRUU\�DERXW�WKH�GLIIHUHQFH�EHWZHHQ�QXPEHUV�DQG�VWULQJV��MXVW�XVHWKH�SURSHU�RSHUDWRUV��DQG�3HUO�ZLOO�PDNH�LW�DOO�ZRUN�

:KHQ�D�VWULQJ�YDOXH�LV�XVHG�ZKHUH�DQ�RSHUDWRU�QHHGV�D�QXPEHU��VD\��IRU�PXOWLSOLFDWLRQ��3HUO�DXWRPDWLFDOO\�FRQYHUWV�WKH�VWULQJ�WR�LWV�HTXLYDOHQW�QXPHULF�YDOXH��DV�LI�LW�KDG�EHHQHQWHUHG�DV�D�GHFLPDO�IORDWLQJ�SRLQW�YDOXH� �6R�"12" * "3"�JLYHV�WKH�YDOXH�36��7UDLOLQJQRQQXPEHU�VWXII�DQG�OHDGLQJ�ZKLWHVSDFH�DUH�GLVFDUGHG��VR�"12fred34" * " 3"�ZLOO�DOVRJLYH�36�ZLWKRXW�DQ\�FRPSODLQWV���$W�WKH�H[WUHPH�HQG�RI�WKLV��VRPHWKLQJ�WKDW�LVQ¦W�DQXPEHU�DW�DOO�FRQYHUWV�WR�]HUR��7KLV�ZRXOG�KDSSHQ�LI�\RX�XVHG�WKH�VWULQJ�"fred"�DV�DQXPEHU�

/LNHZLVH��LI�D�QXPHULF�YDOXH�LV�JLYHQ�ZKHQ�D�VWULQJ�YDOXH�LV�QHHGHG��VD\��IRU�VWULQJ�FRQ�FDWHQDWLRQ���WKH�QXPHULF�YDOXH�LV�H[SDQGHG�LQWR�ZKDWHYHU�VWULQJ�ZRXOG�KDYH�EHHQ�SULQ�WHG�IRU�WKDW�QXPEHU��)RU�H[DPSOH��LI�\RX�ZDQW�WR�FRQFDWHQDWH�WKH�VWULQJ�Z�IROORZHG�E\WKH�UHVXOW�RI���PXOWLSOLHG�E\���®�\RX�FDQ�VD\�WKLV�VLPSO\�DV�

"Z" . 5 * 7 # same as "Z" . 35, or "Z35"

,Q�RWKHU�ZRUGV��\RX�GRQ¦W�UHDOO\�KDYH�WR�ZRUU\�DERXW�ZKHWKHU�\RX�KDYH�D�QXPEHU�RU�DVWULQJ��PRVW�RI�WKH�WLPH���3HUO�SHUIRUPV�DOO�WKH�FRQYHUVLRQV�IRU�\RX�

7KH�WULFN�RI�XVLQJ�D�OHDGLQJ�]HUR�WR�PHDQ�D�QRQGHFLPDO�YDOXH�ZRUNV�IRU� OLWHUDOV��EXW�QHYHU�IRU�DXWRPDWLFFRQYHUVLRQ��8VH�hex( )�RU�oct( )�WR�FRQYHUW�WKRVH�NLQGV�RI�VWULQJV�

� 8QOHVV�\RX�UHTXHVW�ZDUQLQJV��ZKLFK�ZH¦OO�GLVFXVV�LQ�D�PRPHQW�

® <RX¦OO�VHH�DERXW�SUHFHGHQFH�DQG�SDUHQWKHVHV�VKRUWO\�

$QG�LI�\RX¦UH�ZRUULHG�DERXW�HIILFLHQF\��GRQ¦W�EH��3HUO�JHQHUDOO\�UHPHPEHUV�WKH�UHVXOW�RI�D�FRQYHUVLRQ�VR�WKDWLW¦V�GRQH�RQO\�RQFH�

Strings | 25

Perl’s Built-in Warnings3HUO�FDQ�EH�WROG�WR�ZDUQ�\RX�ZKHQ�LW�VHHV�VRPHWKLQJ�VXVSLFLRXV�JRLQJ�RQ�LQ�\RXU�SUR�JUDP��7R�UXQ�\RXU�SURJUDP�ZLWK�ZDUQLQJV�WXUQHG�RQ��XVH�WKH�-w�RSWLRQ�RQ�WKH�FRP�PDQG�OLQH�

$ perl -w my_program

2U��LI�\RX�DOZD\V�ZDQW�ZDUQLQJV��\RX�PD\�UHTXHVW�WKHP�RQ�WKH�#!�OLQH�

#!/usr/bin/perl -w

7KDW�ZRUNV�HYHQ�RQ�QRQ�8QL[�V\VWHPV��ZKHUH�LW¦V�WUDGLWLRQDO�WR�ZULWH�VRPHWKLQJ�OLNHWKLV��VLQFH�WKH�SDWK�WR�3HUO�GRHVQ¦W�JHQHUDOO\�PDWWHU�

#!perl -w

:LWK�3HUO�����DQG�ODWHU��\RX�FDQ�WXUQ�RQ�ZDUQLQJV�ZLWK�D�SUDJPD��EXW�EH�FDUHIXO�EHFDXVHLW�ZRQ¦W�ZRUN�IRU�SHRSOH�ZLWK�HDUOLHU�YHUVLRQV�RI�3HUO��

#!/usr/bin/perluse warnings;

1RZ��3HUO�ZLOO�ZDUQ�\RX�LI�\RX�XVH�'12fred34'�DV�LI�LW�ZHUH�D�QXPEHU�

Argument "12fred34" isn't numeric

2I�FRXUVH��ZDUQLQJV�DUH�JHQHUDOO\�PHDQW�IRU�SURJUDPPHUV��QRW�IRU�HQG�XVHUV�� ,I� WKHZDUQLQJ�ZRQ¦W�EH�VHHQ�E\�D�SURJUDPPHU��LW�SUREDEO\�ZRQ¦W�GR�DQ\�JRRG��$QG�ZDUQLQJVZRQ¦W�FKDQJH�WKH�EHKDYLRU�RI�\RXU�SURJUDP��H[FHSW�WKDW�QRZ�LW�ZLOO�HPLW�JULSHV�RQFHLQ�D�ZKLOH��,I�\RX�JHW�D�ZDUQLQJ�PHVVDJH�\RX�GRQ¦W�XQGHUVWDQG��\RX�FDQ�JHW�D�ORQJHUGHVFULSWLRQ�RI�WKH�SUREOHP�ZLWK�WKH�diagnostics�SUDJPD��7KH�SHUOGLDJ�PDQSDJH�KDVERWK�WKH�VKRUW�ZDUQLQJ�DQG�WKH�ORQJHU�GLDJQRVWLF�GHVFULSWLRQ�

#!/usr/bin/perluse diagnostics;

:KHQ�\RX�DGG�WKH�use diagnostics�SUDJPD�WR�\RXU�SURJUDP��LW�PD\�VHHP�WR�\RX�WKDW\RXU�SURJUDP�QRZ�SDXVHV�IRU�D�PRPHQW�ZKHQHYHU�\RX�ODXQFK�LW��7KDW¦V�EHFDXVH�\RXUSURJUDP�KDV�WR�GR�D�ORW�RI�ZRUN��DQG�D�FKXQN�RI�PHPRU\�WR�JREEOH��MXVW�LQ�FDVH�\RXZDQW�WR�UHDG�WKH�GRFXPHQWDWLRQ�DV�VRRQ�DV�3HUO�QRWLFHV�\RXU�PLVWDNHV��LI�DQ\��7KLV�OHDGVWR�D�QLIW\�RSWLPL]DWLRQ�WKDW�FDQ�VSHHG�XS�\RXU�SURJUDP¦V�ODXQFK��DQG�PHPRU\�IRRW�SULQW��ZLWK�QR�DGYHUVH�LPSDFW�RQ�XVHUV��RQFH�\RX�QR�ORQJHU�QHHG�WR�UHDG�WKH�GRFXPHQ�WDWLRQ�DERXW�WKH�ZDUQLQJ�PHVVDJHV�SURGXFHG�E\�\RXU�SURJUDP��UHPRYH�WKH�use diagnostics�SUDJPD���,W¦V�HYHQ�EHWWHU�LI�\RX�IL[�\RXU�SURJUDP�WR�DYRLG�FDXVLQJ�WKH�ZDUQLQJV�%XW�LW¦V�VXIILFLHQW�PHUHO\�WR�ILQLVK�UHDGLQJ�WKH�RXWSXW��

7KH�warnings�SUDJPD�DFWXDOO\�DOORZV�OH[LFDO�ZDUQLQJV��EXW�\RX¦OO�KDYH�WR�VHH�WKH�SHUOOH[ZDUQ�PDQSDJH�WR�ILQGRXW�DERXW�WKRVH�

26 | Chapter 2:ಗScalar Data

$�IXUWKHU�RSWLPL]DWLRQ�FDQ�EH�KDG�E\�XVLQJ�RQH�RI�3HUO¦V�FRPPDQG�OLQH�RSWLRQV��-M��WRORDG�WKH�SUDJPD�RQO\�ZKHQ�QHHGHG�LQVWHDG�RI�HGLWLQJ�WKH�VRXUFH�FRGH�HDFK�WLPH�WRHQDEOH�DQG�GLVDEOH�diagnostics�

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

$V�ZH�UXQ�DFURVV�VLWXDWLRQV�LQ�ZKLFK�3HUO�ZLOO�XVXDOO\�EH�DEOH�WR�ZDUQ�XV�DERXW�D�PLVWDNHLQ�\RXU�FRGH��ZH¦OO�SRLQW�WKHP�RXW��%XW�\RX�VKRXOGQ¦W�FRXQW�RQ�WKH�WH[W�RU�EHKDYLRU�RIDQ\�ZDUQLQJ�VWD\LQJ�H[DFWO\�WKH�VDPH�LQ�IXWXUH�3HUO�UHOHDVHV�

Scalar Variables$�YDULDEOH�LV�D�QDPH�IRU�D�FRQWDLQHU�WKDW�KROGV�RQH�RU�PRUH�YDOXHV� �7KH�QDPH�RI�WKHYDULDEOH�VWD\V�WKH�VDPH�WKURXJKRXW�WKH�SURJUDP��EXW�WKH�YDOXH�RU�YDOXHV�FRQWDLQHG�LQWKDW� YDULDEOH� W\SLFDOO\� FKDQJH�RYHU� DQG�RYHU� DJDLQ� WKURXJKRXW� WKH� H[HFXWLRQ�RI� WKHSURJUDP�

$�VFDODU�YDULDEOH�KROGV�D�VLQJOH�VFDODU�YDOXH��DV�\RX¦G�H[SHFW��6FDODU�YDULDEOH�QDPHV�EHJLQZLWK�D�GROODU�VLJQ�IROORZHG�E\�ZKDW�ZH¦OO�FDOO�D�3HUO�LGHQWLILHU��D�OHWWHU�RU�XQGHUVFRUH�DQG�WKHQ�SRVVLEO\�PRUH�OHWWHUV��RU�GLJLWV��RU�XQGHUVFRUHV��$QRWKHU�ZD\�WR�WKLQN�RI�LW�LVWKDW�LW¦V�PDGH�XS�RI�DOSKDQXPHULFV�DQG�XQGHUVFRUHV��EXW�FDQ¦W�VWDUW�ZLWK�D�GLJLW��8SSHU�DQG�ORZHUFDVH�OHWWHUV�DUH�GLVWLQFW��WKH�YDULDEOH�$Fred�LV�D�GLIIHUHQW�YDULDEOH�IURP�$fred�$QG�DOO�RI�WKH�OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV�DUH�VLJQLILFDQW��VR�

$a_very_long_variable_that_ends_in_1

LV�GLIIHUHQW�IURP�

$a_very_long_variable_that_ends_in_2

6FDODU�YDULDEOHV�LQ�3HUO�DUH�DOZD\V�UHIHUHQFHG�ZLWK�WKH�OHDGLQJ�$&���,Q�WKH�VKHOO��\RX�XVH$�WR�JHW�WKH�YDOXH��EXW�OHDYH�WKH�$�RII�WR�DVVLJQ�D�QHZ�YDOXH��,Q�DZN�RU�&��\RX�OHDYH�WKH$�RII�HQWLUHO\��,I�\RX�ERXQFH�EDFN�DQG�IRUWK�D�ORW��\RX¦OO�ILQG�\RXUVHOI�W\SLQJ�WKH�ZURQJWKLQJV�RFFDVLRQDOO\��7KLV�LV�H[SHFWHG���0RVW�3HUO�SURJUDPPHUV�ZRXOG�UHFRPPHQG�WKDW\RX�VWRS�ZULWLQJ�VKHOO��DZN��DQG�&�SURJUDPV��EXW�WKDW�PD\�QRW�ZRUN�IRU�\RX��

Choosing Good Variable Names<RX�VKRXOG�JHQHUDOO\�VHOHFW�YDULDEOH�QDPHV�WKDW�PHDQ�VRPHWKLQJ�UHJDUGLQJ�WKH�SXUSRVHRI�WKH�YDULDEOH��)RU�H[DPSOH��$r�LV�SUREDEO\�QRW�YHU\�GHVFULSWLYH�EXW�$line_length�LV��$

$V�\RX¦OO�VHH��D�VFDODU�YDULDEOH�FDQ�KROG�RQO\�RQH�YDOXH��%XW�RWKHU�W\SHV�RI�YDULDEOHV��VXFK�DV�DUUD\V�DQG�KDVKHV�PD\�KROG�PDQ\�YDOXHV�

� 7KLV�LV�FDOOHG�D�£VLJLO¤�LQ�3HUOVSHDN�

Scalar Variables | 27

YDULDEOH�XVHG�IRU�RQO\�WZR�RU�WKUHH�OLQHV�FORVH�WRJHWKHU�PD\�EH�FDOOHG�VRPHWKLQJ�VLPSOH�OLNH� $n�� EXW� D� YDULDEOH� XVHG� WKURXJKRXW� D� SURJUDP� VKRXOG� SUREDEO\� KDYH� D� PRUHGHVFULSWLYH�QDPH�

6LPLODUO\��SURSHUO\�SODFHG�XQGHUVFRUHV�FDQ�PDNH�D�QDPH�HDVLHU�WR�UHDG�DQG�XQGHUVWDQG�HVSHFLDOO\� LI� \RXU�PDLQWHQDQFH� SURJUDPPHU� KDV� D� GLIIHUHQW� VSRNHQ� ODQJXDJH� EDFN�JURXQG�WKDQ�\RX�KDYH��)RU�H[DPSOH��$super_bowl� LV�D�EHWWHU�QDPH�WKDQ�$superbowl�VLQFH�WKDW�ODVW�RQH�PLJKW�ORRN�OLNH�$superb_owl��'RHV�$stopid�PHDQ�$sto_pid��VWRULQJD�SURFHVV�,'�RI�VRPH�NLQG"��RU�$s_to_pid��FRQYHUWLQJ�VRPHWKLQJ�WR�D�SURFHVV�,'"��RU$stop_id��WKH�,'�IRU�VRPH�NLQG�RI�£VWRS¤�REMHFW"��RU�LV�LW�MXVW�D�VWRSLG�PLVVSHOOLQJ"

0RVW�YDULDEOH�QDPHV�LQ�RXU�3HUO�SURJUDPV�DUH�DOO�ORZHUFDVH��OLNH�PRVW�RI�WKH�RQHV�\RX¦OOVHH�LQ�WKLV�ERRN��,Q�D�IHZ�VSHFLDO�FDVHV��XSSHUFDVH�OHWWHUV�DUH�XVHG��8VLQJ�DOO�FDSV��OLNH$ARGV��JHQHUDOO\�LQGLFDWHV�WKDW�WKHUH¦V�VRPHWKLQJ�VSHFLDO�DERXW�WKDW�YDULDEOH��:KHQ�DYDULDEOH¦V�QDPH�KDV�PRUH�WKDQ�RQH�ZRUG��VRPH�VD\�$underscores_are_cool��ZKLOH�RWKHUVVD\�$giveMeInitialCaps��-XVW�EH�FRQVLVWHQW�

2I�FRXUVH��FKRRVLQJ�JRRG�RU�SRRU�QDPHV�PDNHV�QR�GLIIHUHQFH�WR�3HUO��<RX�FRXOG�QDPH\RXU� SURJUDP¦V� WKUHH� PRVW�LPSRUWDQW� YDULDEOHV� $OOO000OOO�� $OO00OO00�� DQG$O0O0O0O0O�DQG�3HUO�ZRXOGQ¦W�EH�ERWKHUHG¢EXW�LQ�WKDW�FDVH��SOHDVH��GRQ¦W�DVN�XV�WRPDLQWDLQ�\RXU�FRGH�

Scalar Assignment7KH�PRVW�FRPPRQ�RSHUDWLRQ�RQ�D�VFDODU�YDULDEOH�LV�DVVLJQPHQW��ZKLFK�LV�WKH�ZD\�WRJLYH�D�YDOXH�WR�D�YDULDEOH��7KH�3HUO�DVVLJQPHQW�RSHUDWRU�LV�WKH�HTXDOV�VLJQ��PXFK�OLNHRWKHU�ODQJXDJHV���ZKLFK�WDNHV�D�YDULDEOH�QDPH�RQ�WKH�OHIW�VLGH��DQG�JLYHV�LW�WKH�YDOXH�RIWKH�H[SUHVVLRQ�RQ�WKH�ULJKW��)RU�H[DPSOH�

$fred = 17; # give $fred the value of 17$barney = 'hello'; # give $barney the five-character string 'hello'$barney = $fred + 3; # give $barney the current value of $fred plus 3 (20)$barney = $barney * 2; # $barney is now $barney multiplied by 2 (40)

1RWLFH�WKDW�ODVW�OLQH�XVHV�WKH�$barney�YDULDEOH�WZLFH��RQFH�WR�JHW�LWV�YDOXH��RQ�WKH�ULJKWVLGH�RI�WKH�HTXDOV�VLJQ���DQG�RQFH�WR�GHILQH�ZKHUH�WR�SXW�WKH�FRPSXWHG�H[SUHVVLRQ��RQWKH�OHIW�VLGH�RI�WKH�HTXDOV�VLJQ���7KLV�LV�OHJDO��VDIH��DQG�UDWKHU�FRPPRQ��,Q�IDFW��LW¦V�VRFRPPRQ�WKDW�\RX�FDQ�ZULWH�LW�XVLQJ�D�FRQYHQLHQW�VKRUWKDQG��DV�\RX¦OO�VHH�LQ�WKH�QH[WVHFWLRQ�

Binary Assignment Operators([SUHVVLRQV�OLNH�$fred = $fred + 5��ZKHUH�WKH�VDPH�YDULDEOH�DSSHDUV�RQ�ERWK�VLGHV�RIDQ�DVVLJQPHQW��RFFXU�IUHTXHQWO\�HQRXJK�WKDW�3HUO��OLNH�&�DQG�-DYD��KDV�D�VKRUWKDQG�IRUWKH�RSHUDWLRQ�RI�DOWHULQJ�D�YDULDEOH¢WKH�ELQDU\�DVVLJQPHQW�RSHUDWRU��1HDUO\�DOO�ELQDU\RSHUDWRUV�WKDW�FRPSXWH�D�YDOXH�KDYH�D�FRUUHVSRQGLQJ�ELQDU\�DVVLJQPHQW�IRUP�ZLWK�DQDSSHQGHG�HTXDOV�VLJQ��)RU�H[DPSOH��WKH�IROORZLQJ�WZR�OLQHV�DUH�HTXLYDOHQW�

28 | Chapter 2:ಗScalar Data

$fred = $fred + 5; # without the binary assignment operator$fred += 5; # with the binary assignment operator

7KHVH�DUH�DOVR�HTXLYDOHQW�

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

,Q�HDFK�FDVH��WKH�RSHUDWRU�DOWHUV�WKH�H[LVWLQJ�YDOXH�RI�WKH�YDULDEOH�LQ�VRPH�ZD\��UDWKHUWKDQ�VLPSO\�RYHUZULWLQJ�WKH�YDOXH�ZLWK�WKH�UHVXOW�RI�VRPH�QHZ�H[SUHVVLRQ�

$QRWKHU�FRPPRQ�DVVLJQPHQW�RSHUDWRU�LV�PDGH�ZLWK�WKH�VWULQJ�FRQFDWHQDWH�RSHUDWRU��.����WKLV�JLYHV�XV�DQ�DSSHQG�RSHUDWRU���.=���

$str = $str . " "; # append a space to $str$str .= " "; # same thing with assignment operator

1HDUO\�DOO�ELQDU\�RSHUDWRUV�DUH�YDOLG� WKLV�ZD\��)RU�H[DPSOH��D�UDLVH� WR� WKH�SRZHU�RIRSHUDWRU�LV�ZULWWHQ�DV�**=��6R��$fred **= 3�PHDQV�£UDLVH�WKH�QXPEHU�LQ�$fred�WR�WKH�WKLUGSRZHU��SODFLQJ�WKH�UHVXOW�EDFN�LQ�$fred�¤

Output with print,W¦V� JHQHUDOO\� D� JRRG� LGHD� WR� KDYH� \RXU� SURJUDP� SURGXFH� VRPH� RXWSXW�� RWKHUZLVH�VRPHRQH�PD\�WKLQN�LW�GLGQ¦W�GR�DQ\WKLQJ��7KH�print( )�RSHUDWRU�PDNHV�WKDW�SRVVLEOH�LW�WDNHV�D�VFDODU�DUJXPHQW�DQG�SXWV�LW�RXW�ZLWKRXW�DQ\�HPEHOOLVKPHQW�RQWR�VWDQGDUGRXWSXW��8QOHVV�\RX¦YH�GRQH� VRPHWKLQJ�RGG�� WKLV�ZLOO�EH�\RXU� WHUPLQDO�GLVSOD\��)RUH[DPSOH�

print "hello world\n"; # say hello world, followed by a newline

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

<RX�FDQ�JLYH�print�D�VHULHV�RI�YDOXHV��VHSDUDWHG�E\�FRPPDV�

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

7KLV�LV�UHDOO\�D�OLVW��EXW�ZH�KDYHQ¦W�WDONHG�DERXW�OLVWV�\HW��VR�ZH¦OO�SXW�WKDW�RII�IRU�ODWHU�

Interpolation of Scalar Variables into Strings:KHQ�D�VWULQJ�OLWHUDO�LV�GRXEOH�TXRWHG��LW�LV�VXEMHFW�WR�YDULDEOH�LQWHUSRODWLRQ ��EHVLGHVEHLQJ�FKHFNHG�IRU�EDFNVODVK�HVFDSHV���7KLV�PHDQV�WKDW�DQ\�VFDODU�YDULDEOH��QDPH�LQ�WKHVWULQJ�LV�UHSODFHG�ZLWK�LWV�FXUUHQW�YDOXH��)RU�H[DPSOH�

7KLV�KDV�QRWKLQJ�WR�GR�ZLWK�PDWKHPDWLFDO�RU�VWDWLVWLFDO�LQWHUSRODWLRQ�

� $QG�VRPH�RWKHU�YDULDEOH�W\SHV��EXW�\RX�ZRQ¦W�VHH�WKRVH�XQWLO�ODWHU�

Output with print | 29

$meal = "brontosaurus steak";$barney = "fred ate a $meal"; # $barney is now "fred ate a brontosaurus steak"$barney = 'fred ate a ' . $meal; # another way to write that

$V�\RX�VHH�RQ�WKH� ODVW� OLQH�DERYH��\RX�FDQ�JHW� WKH�VDPH�UHVXOWV�ZLWKRXW� WKH�GRXEOHTXRWHV��EXW�WKH�GRXEOH�TXRWHG�VWULQJ�LV�RIWHQ�WKH�PRUH�FRQYHQLHQW�ZD\�WR�ZULWH�LW�

,I�WKH�VFDODU�YDULDEOH�KDV�QHYHU�EHHQ�JLYHQ�D�YDOXH� �WKH�HPSW\�VWULQJ�LV�XVHG�LQVWHDG�

$barney = "fred ate a $meat"; # $barney is now "fred ate a"

'RQ¦W�ERWKHU�ZLWK�LQWHUSRODWLQJ�LI�\RX�KDYH�MXVW�WKH�RQH�ORQH�YDULDEOH�

print "$fred"; # unneeded quote marksprint $fred; # better style

7KHUH¦V�QRWKLQJ�UHDOO\�ZURQJ�ZLWK�SXWWLQJ�TXRWH�PDUNV�DURXQG�D�ORQH�YDULDEOH��EXW�WKHRWKHU�SURJUDPPHUV�ZLOO�ODXJK�DW�\RX�EHKLQG�\RXU�EDFN���9DULDEOH�LQWHUSRODWLRQ�LV�DOVRNQRZQ�DV�GRXEOH�TXRWH�LQWHUSRODWLRQ�EHFDXVH�LW�KDSSHQV�ZKHQ�GRXEOH�TXRWH�PDUNV��EXWQRW�VLQJOH�TXRWHV��DUH�XVHG��,W�KDSSHQV�IRU�VRPH�RWKHU�VWULQJV�LQ�3HUO��ZKLFK�ZH¦OO�PHQ�WLRQ�DV�ZH�JHW�WR�WKHP�

7R�SXW�D�UHDO�GROODU�VLJQ�LQWR�D�GRXEOH�TXRWHG�VWULQJ��SUHFHGH�WKH�GROODU�VLJQ�ZLWK�DEDFNVODVK��ZKLFK�WXUQV�RII�WKH�GROODU�VLJQ¦V�VSHFLDO�VLJQLILFDQFH�

$fred = 'hello';print "The name is \$fred.\n"; # prints a dollar signprint 'The name is $fred' . "\n"; # so does this

7KH�YDULDEOH�QDPH�ZLOO�EH�WKH�ORQJHVW�SRVVLEOH�YDULDEOH�QDPH�WKDW�PDNHV�VHQVH�DW�WKDWSDUW�RI�WKH�VWULQJ��7KLV�FDQ�EH�D�SUREOHP�LI�\RX�ZDQW�WR�IROORZ�WKH�UHSODFHG�YDOXH�LP�PHGLDWHO\�ZLWK�VRPH�FRQVWDQW�WH[W�WKDW�EHJLQV�ZLWK�D�OHWWHU��GLJLW��RU�XQGHUVFRUH�®�$V3HUO�VFDQV�IRU�YDULDEOH�QDPHV��LW�ZRXOG�FRQVLGHU�WKRVH�FKDUDFWHUV�DV�DGGLWLRQDO�QDPHFKDUDFWHUV��ZKLFK�LV�QRW�ZKDW�\RX�ZDQW��3HUO�SURYLGHV�D�GHOLPLWHU�IRU�WKH�YDULDEOH�QDPHLQ�D�PDQQHU�VLPLODU�WR�WKH�VKHOO��6LPSO\�HQFORVH�WKH�QDPH�RI�WKH�YDULDEOH�LQ�D�SDLU�RIFXUO\�EUDFHV��2U��\RX�FDQ�HQG�WKDW�SDUW�RI�WKH�VWULQJ�DQG�VWDUW�DQRWKHU�SDUW�RI�WKH�VWULQJZLWK�D�FRQFDWHQDWLRQ�RSHUDWRU�

$what = "brontosaurus steak";$n = 3;print "fred ate $n $whats.\n"; # not the steaks, but the value of $whatsprint "fred ate $n ${what}s.\n"; # now uses $whatprint "fred ate $n $what" . "s.\n"; # another way to do itprint 'fred ate ' . $n . ' ' . $what . "s.\n"; # an especially difficult way

7KLV�LV�DFWXDOO\�WKH�VSHFLDO�XQGHILQHG�YDOXH��undef��ZKLFK�\RX¦OO�VHH�D�OLWWOH�ODWHU�LQ�WKLV�FKDSWHU��,I�ZDUQLQJVDUH�WXUQHG�RQ��3HUO�ZLOO�FRPSODLQ�DERXW�LQWHUSRODWLQJ�WKH�XQGHILQHG�YDOXH�

� :HOO��LW�PD\�LQWHUSUHW�WKH�YDOXH�DV�D�VWULQJ��UDWKHU�WKDQ�D�QXPEHU��,Q�D�IHZ�UDUH�FDVHV�WKDW�PD\�EH�QHHGHG��EXWQHDUO\�DOZD\V�LW¦V�MXVW�D�ZDVWH�RI�W\SLQJ�

® 7KHUH�DUH�VRPH�RWKHU�FKDUDFWHUV�WKDW�PD\�EH�D�SUREOHP�DV�ZHOO��,I�\RX�QHHG�D�OHIW�VTXDUH�EUDFNHW�RU�D�OHIW�FXUO\EUDFH�MXVW�DIWHU�D�VFDODU�YDULDEOH¦V�QDPH��SUHFHGH�LW�ZLWK�D�EDFNVODVK��<RX�PD\�DOVR�GR�WKDW�LI�WKH�YDULDEOH¦VQDPH�LV�IROORZHG�E\�DQ�DSRVWURSKH�RU�D�SDLU�RI�FRORQV��RU�\RX�FRXOG�XVH�WKH�FXUO\�EUDFH�PHWKRG�GHVFULEHG�LQWKH�PDLQ�WH[W�

30 | Chapter 2:ಗScalar Data

Operator Precedence and Associativity2SHUDWRU�SUHFHGHQFH�GHWHUPLQHV�ZKLFK�RSHUDWLRQV�LQ�D�FRPSOH[�JURXS�RI�RSHUDWLRQVKDSSHQ�ILUVW��)RU�H[DPSOH��LQ�WKH�H[SUHVVLRQ�2+3*4��GR�\RX�SHUIRUP�WKH�DGGLWLRQ�ILUVWRU�WKH�PXOWLSOLFDWLRQ�ILUVW"�,I�\RX�GLG�WKH�DGGLWLRQ�ILUVW��\RX¦G�JHW�5*4��RU�20��%XW�LI�\RXGLG�WKH�PXOWLSOLFDWLRQ�ILUVW��DV�\RX�ZHUH�WDXJKW�LQ�PDWK�FODVV���\RX¦G�JHW�2+12��RU�14�)RUWXQDWHO\��3HUO�FKRRVHV�WKH�FRPPRQ�PDWKHPDWLFDO�GHILQLWLRQ��SHUIRUPLQJ�WKH�PXO�WLSOLFDWLRQ�ILUVW��%HFDXVH�RI�WKLV��\RX�VD\�PXOWLSOLFDWLRQ�KDV�D�KLJKHU�SUHFHGHQFH�WKDQDGGLWLRQ�

<RX�FDQ�RYHUULGH�WKH�GHIDXOW�SUHFHGHQFH�RUGHU�E\�XVLQJ�SDUHQWKHVHV��$Q\WKLQJ�LQ�SD�UHQWKHVHV� LV�FRPSOHWHO\�FRPSXWHG�EHIRUH� WKH�RSHUDWRU�RXWVLGH�RI� WKH�SDUHQWKHVHV� LVDSSOLHG��MXVW�OLNH�\RX�OHDUQHG�LQ�PDWK�FODVV���6R�LI�\RX�UHDOO\�ZDQW�WKH�DGGLWLRQ�EHIRUHWKH�PXOWLSOLFDWLRQ��\RX�FDQ�VD\�(2+3)*4��\LHOGLQJ�20��$OVR��LI�\RX�ZDQWHG�WR�GHPRQVWUDWHWKDW�PXOWLSOLFDWLRQ�LV�SHUIRUPHG�EHIRUH�DGGLWLRQ��\RX�FRXOG�DGG�D�GHFRUDWLYH�EXW�XQ�QHFHVVDU\�VHW�RI�SDUHQWKHVHV��DV�LQ�2+(3*4)�

:KLOH�SUHFHGHQFH� LV� VLPSOH� IRU� DGGLWLRQ�DQG�PXOWLSOLFDWLRQ�� \RX� VWDUW� UXQQLQJ� LQWRSUREOHPV�ZKHQ�IDFHG�ZLWK��VD\��VWULQJ�FRQFDWHQDWLRQ�FRPSDUHG�ZLWK�H[SRQHQWLDWLRQ�7KH�SURSHU�ZD\�WR�UHVROYH�WKLV�LV�WR�FRQVXOW�WKH�RIILFLDO��DFFHSW�QR�VXEVWLWXWHV�3HUO�RS�HUDWRU�SUHFHGHQFH�FKDUW��VKRZQ�LQ�7DEOH����� ��1RWH�WKDW�VRPH�RI�WKH�RSHUDWRUV�KDYHQRW�\HW�EHHQ�GHVFULEHG��DQG�LQ�IDFW��PD\�QRW�HYHQ�DSSHDU�DQ\ZKHUH�LQ�WKLV�ERRN��EXWGRQ¦W�OHW�WKDW�VFDUH�\RX�IURP�UHDGLQJ�DERXW�WKHP�LQ�WKH�SHUORS�PDQSDJH��

7DEOH������$VVRFLDWLYLW\�DQG�SUHFHGHQFH�RI�RSHUDWRUV��KLJKHVW�WR�ORZHVW�

Associativity Operators

left parentheses and arguments to list operators

left ->

++ -- (autoincrement and autodecrement)

right **

right \ ! ~ + - (unary operators)

left =~ !~

left * / % x

left + - . (binary operators)

left << >>

named unary operators (-X filetests, rand)

< <= > >= lt le gt ge (the “unequal” ones)

== != <=> eq ne cmp (the “equal” ones)

left &

&�SURJUDPPHUV��5HMRLFH��7KH�RSHUDWRUV�WKDW�DUH�DYDLODEOH�LQ�ERWK�3HUO�DQG�&�KDYH�WKH�VDPH�SUHFHGHQFH�DQGDVVRFLDWLYLW\�LQ�ERWK�

Output with print | 31

Associativity Operators

left | ^

left &&

left ||

.. ...

right ?: (ternary)

right = += -= .= (and similar assignment operators)

left , =>

list operators (rightward)

right not

left and

left or xor

,Q�WKH�FKDUW��DQ\�JLYHQ�RSHUDWRU�KDV�KLJKHU�SUHFHGHQFH�WKDQ�DOO�RI�WKH�RSHUDWRUV�OLVWHGEHORZ�LW��DQG�ORZHU�SUHFHGHQFH�WKDQ�DOO�RI�WKH�RSHUDWRUV�OLVWHG�DERYH�LW��2SHUDWRUV�DWWKH�VDPH�SUHFHGHQFH�OHYHO�UHVROYH�DFFRUGLQJ�WR�UXOHV�RI�DVVRFLDWLYLW\�LQVWHDG�

-XVW�OLNH�SUHFHGHQFH��DVVRFLDWLYLW\�UHVROYHV�WKH�RUGHU�RI�RSHUDWLRQV�ZKHQ�WZR�RSHUDWRUVRI�WKH�VDPH�SUHFHGHQFH�FRPSHWH�IRU�WKUHH�RSHUDQGV�

4 ** 3 ** 2 # 4 ** (3 ** 2), or 4 ** 9 (right associative)72 / 12 / 3 # (72 / 12) / 3, or 6/3, or 2 (left associative)36 / 6 * 3 # (36/6)*3, or 18

,Q�WKH�ILUVW�FDVH��WKH�**�RSHUDWRU�KDV�ULJKW�DVVRFLDWLYLW\��VR�WKH�SDUHQWKHVHV�DUH�LPSOLHGRQ�WKH�ULJKW��&RPSDUDWLYHO\��WKH�*�DQG�/�RSHUDWRUV�KDYH�OHIW�DVVRFLDWLYLW\��\LHOGLQJ�D�VHWRI�LPSOLHG�SDUHQWKHVHV�RQ�WKH�OHIW�

6R�VKRXOG�\RX�MXVW�PHPRUL]H�WKH�SUHFHGHQFH�FKDUW"�1R��1RERG\�DFWXDOO\�GRHV�WKDW�,QVWHDG�� MXVW�XVH�SDUHQWKHVHV�ZKHQ�\RX�GRQ¦W�UHPHPEHU�WKH�RUGHU�RI�RSHUDWLRQV��RUZKHQ�\RX¦UH�WRR�EXV\�WR�ORRN�LQ�WKH�FKDUW��$IWHU�DOO��LI�\RX�FDQ¦W�UHPHPEHU�LW�ZLWKRXWWKH�SDUHQWKHVHV��\RXU�PDLQWHQDQFH�SURJUDPPHU�LV�JRLQJ�WR�KDYH�WKH�VDPH�WURXEOH��6REH�QLFH�WR�\RXU�PDLQWHQDQFH�SURJUDPPHU��\RX�PD\�EH�WKDW�SHUVRQ�RQH�GD\�

Comparison Operators)RU�FRPSDULQJ�QXPEHUV��3HUO�KDV�WKH�ORJLFDO�FRPSDULVRQ�RSHUDWRUV�WKDW�UHPLQG�\RX�RIDOJHEUD��< <= == >= > !=��(DFK�RI�WKHVH�UHWXUQV�D�WUXH�RU�IDOVH�YDOXH��<RX¦OO�ILQG�RXWPRUH�DERXW�WKRVH�UHWXUQ�YDOXHV�LQ�WKH�QH[W�VHFWLRQ��6RPH�RI�WKHVH�PD\�EH�GLIIHUHQW�WKDQ\RX¦G�XVH�LQ�RWKHU�ODQJXDJHV��)RU�H[DPSOH��==�LV�XVHG�IRU�HTXDOLW\��QRW�D�VLQJOH�=�VLJQEHFDXVH�WKDW¦V�XVHG�IRU�DVVLJQPHQW��$QG�!=�LV�XVHG�IRU�LQHTXDOLW\�WHVWLQJ�EHFDXVH�<>�LVXVHG�IRU�DQRWKHU�SXUSRVH�LQ�3HUO��$QG�\RX¦OO�QHHG�>=�DQG�QRW�=>�IRU�£JUHDWHU�WKDQ�RUHTXDO�WR¤�EHFDXVH�WKH�ODWWHU�LV�XVHG�IRU�DQRWKHU�SXUSRVH�LQ�3HUO��,Q�IDFW��QHDUO\�HYHU\

32 | Chapter 2:ಗScalar Data

VHTXHQFH�RI�SXQFWXDWLRQ�LV�XVHG�IRU�VRPHWKLQJ�LQ�3HUO��6R��LI�\RX�JHW�ZULWHU¦V�EORFN��MXVWOHW�WKH�FDW�ZDON�DFURVV�WKH�NH\ERDUG��DQG�GHEXJ�ZKDW�UHVXOWV�

)RU�FRPSDULQJ�VWULQJV��3HUO�KDV�DQ�HTXLYDOHQW�VHW�RI�VWULQJ�FRPSDULVRQ�RSHUDWRUV��ZKLFKORRN�OLNH�IXQQ\�OLWWOH�ZRUGV��lt le eq ge gt ne��7KHVH�FRPSDUH�WZR�VWULQJV�FKDUDFWHUE\�FKDUDFWHU�WR�VHH�ZKHWKHU�WKH\¦UH�WKH�VDPH��RU�ZKHWKHU�RQH�FRPHV�ILUVW�LQ�VWDQGDUGVWULQJ�VRUWLQJ�RUGHU���,Q�$6&,,��WKH�FDSLWDO�OHWWHUV�FRPH�EHIRUH�WKH�ORZHUFDVH�OHWWHUV��VREHZDUH��

7KH�FRPSDULVRQ�RSHUDWRUV��IRU�ERWK�QXPEHUV�DQG�VWULQJV��DUH�JLYHQ�LQ�7DEOH�����

7DEOH������1XPHULF�DQG�VWULQJ�FRPSDULVRQ�RSHUDWRUV

Comparison Numeric String

Equal == eq

Not equal != ne

Less than < lt

Greater than > gt

Less than or equal to <= le

Greater than or equal to >= ge

+HUH�DUH�VRPH�H[DPSOH�H[SUHVVLRQV�XVLQJ�WKHVH�FRPSDULVRQ�RSHUDWRUV�

35 != 30 + 5 # false35 == 35.0 # true'35' eq '35.0' # false (comparing as strings)'fred' lt 'barney' # false'fred' lt 'free' # true'fred' eq "fred" # true'fred' eq 'Fred' # false' ' gt '' # true

The if Control Structure2QFH�\RX�FDQ�FRPSDUH�WZR�YDOXHV��\RX¦OO�SUREDEO\�ZDQW�\RXU�SURJUDP�WR�PDNH�GHFL�VLRQV�EDVHG�XSRQ�WKDW�FRPSDULVRQ��/LNH�DOO�VLPLODU�ODQJXDJHV��3HUO�KDV�DQ�if�FRQWUROVWUXFWXUH�

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

,I�\RX�QHHG�DQ�DOWHUQDWLYH�FKRLFH��WKH�else�NH\ZRUG�SURYLGHV�WKDW�DV�ZHOO�

if ($name gt 'fred') { print "'$name' comes after 'fred' in sorted order.\n";} else { print "'$name' does not come after 'fred'.\n"; print "Maybe it's the same string, in fact.\n";}

The if Control Structure | 33

7KRVH�EORFN�FXUO\�EUDFHV�DUH�UHTXLUHG�DURXQG�WKH�FRQGLWLRQDO�FRGH��XQOLNH�&��ZKHWKHU\RX�NQRZ�&�RU�QRW���,W¦V�D�JRRG�LGHD�WR�LQGHQW�WKH�FRQWHQWV�RI�WKH�EORFNV�RI�FRGH�DV�ZHVKRZ�KHUH��WKDW�PDNHV�LW�HDVLHU�WR�VHH�ZKDW¦V�JRLQJ�RQ��,I�\RX¦UH�XVLQJ�D�SURJUDPPHUV¦WH[W�HGLWRU��DV�GLVFXVVHG�LQ�&KDSWHU�����LW¦OO�GR�PRVW�RI�WKH�ZRUN�IRU�\RX�

Boolean Values<RX�PD\�DFWXDOO\�XVH�DQ\�VFDODU�YDOXH�DV�WKH�FRQGLWLRQDO�RI�WKH�if�FRQWURO�VWUXFWXUH�7KDW¦V�KDQG\�LI�\RX�ZDQW�WR�VWRUH�D�WUXH�RU�IDOVH�YDOXH�LQWR�D�YDULDEOH��OLNH�WKLV�

$is_bigger = $name gt 'fred';if ($is_bigger) { ... }

%XW�KRZ�GRHV�3HUO�GHFLGH�ZKHWKHU�D�JLYHQ�YDOXH�LV�WUXH�RU�IDOVH"�3HUO�GRHVQ¦W�KDYH�DVHSDUDWH�%RROHDQ�GDWD�W\SH�� OLNH�VRPH�ODQJXDJHV�KDYH�� ,QVWHDG�� LW�XVHV�D� IHZ�VLPSOHUXOHV�

� ,I�WKH�YDOXH�LV�D�QXPEHU��0�PHDQV�IDOVH��DOO�RWKHU�QXPEHUV�PHDQ�WUXH�

� 2WKHUZLVH��LI�WKH�YDOXH�LV�D�VWULQJ��WKH�HPSW\�VWULQJ��''��PHDQV�IDOVH��DOO�RWKHU�VWULQJVPHDQ�WUXH�

� 2WKHUZLVH��WKDW�LV��LI�WKH�YDOXH�LV�DQRWKHU�NLQG�RI�VFDODU�WKDQ�D�QXPEHU�RU�D�VWULQJ��FRQYHUW�LW�WR�D�QXPEHU�RU�D�VWULQJ�DQG�WU\�DJDLQ��

7KHUH¦V�RQH�WULFN�KLGGHQ�LQ�WKRVH�UXOHV��%HFDXVH�WKH�VWULQJ�'0'�LV�WKH�H[DFW�VDPH�VFDODUYDOXH�DV�WKH�QXPEHU�0��3HUO�KDV�WR�WUHDW�WKHP�ERWK�WKH�VDPH��7KDW�PHDQV�WKDW�WKH�VWULQJ'0'�LV�WKH�RQO\�QRQHPSW\�VWULQJ�WKDW�LV�IDOVH�

,I�\RX�QHHG�WR�JHW�WKH�RSSRVLWH�RI�DQ\�%RROHDQ�YDOXH��XVH�WKH�XQDU\�QRW�RSHUDWRU��!��,IZKDW�IROORZV�LW�LV�D�WUXH�YDOXH��LW�UHWXUQV�IDOVH��LI�ZKDW�IROORZV�LV�IDOVH��LW�UHWXUQV�WUXH�

if (! $is_bigger) { # Do something when $is_bigger is not true}

Getting User Input$W�WKLV�SRLQW��\RX¦UH�SUREDEO\�ZRQGHULQJ�KRZ�WR�JHW�D�YDOXH�IURP�WKH�NH\ERDUG�LQWR�D3HUO�SURJUDP��+HUH¦V�WKH�VLPSOHVW�ZD\��XVH�WKH�OLQH�LQSXW�RSHUDWRU��<STDIN>�®

(DFK�WLPH�\RX�XVH�<STDIN>�LQ�D�SODFH�ZKHUH�D�VFDODU�YDOXH�LV�H[SHFWHG��3HUO�UHDGV�WKHQH[W�FRPSOHWH�WH[W�OLQH�IURP�VWDQGDUG�LQSXW��XS�WR�WKH�ILUVW�QHZOLQH���DQG�XVHV�WKDW�VWULQJ

7KHVH�DUHQ¦W�WKH�UXOHV�WKDW�3HUO�XVHV��RI�FRXUVH��7KHVH�DUH�VRPH�UXOHV�WKDW�\RX�FDQ�XVH�WR�JHW�HVVHQWLDOO\�WKHVDPH�UHVXOW��WKRXJK�

� 7KLV�PHDQV�WKDW�undef��ZKLFK�ZH¦OO�VHH�VRRQ��PHDQV�IDOVH��ZKLOH�DOO�UHIHUHQFHV��ZKLFK�DUH�FRYHUHG�LQ�WKH�$OSDFDERRN��DUH�WUXH�

® 7KLV�LV�DFWXDOO\�D�OLQH�LQSXW�RSHUDWRU�ZRUNLQJ�RQ�WKH�ILOHKDQGOH�STDIN��EXW�ZH�FDQ¦W�WHOO�\RX�DERXW�WKDW�XQWLOZH�JHW�WR�ILOHKDQGOHV��LQ�&KDSWHU����

34 | Chapter 2:ಗScalar Data

DV� WKH� YDOXH�RI�<STDIN>�� 6WDQGDUG� LQSXW� FDQ�PHDQ�PDQ\� WKLQJV�� EXW� XQOHVV� \RX�GRVRPHWKLQJ�XQFRPPRQ��LW�PHDQV�WKH�NH\ERDUG�RI�WKH�XVHU�ZKR�LQYRNHG�\RXU�SURJUDP�SUREDEO\�\RX���,I�WKHUH¦V�QRWKLQJ�ZDLWLQJ�IRU�<STDIN>�WR�UHDG��W\SLFDOO\�WKH�FDVH��XQOHVV\RX�W\SH�DKHDG�D�FRPSOHWH�OLQH���WKH�3HUO�SURJUDP�ZLOO�VWRS�DQG�ZDLW�IRU�\RX�WR�HQWHUVRPH�FKDUDFWHUV�IROORZHG�E\�D�QHZOLQH��UHWXUQ��

7KH�VWULQJ�YDOXH�RI�<STDIN>�W\SLFDOO\�KDV�D�QHZOLQH�FKDUDFWHU�RQ�WKH�HQG�RI�LW���VR�\RXFRXOG�GR�VRPHWKLQJ�OLNH�WKLV�

$line = <STDIN>;if ($line eq "\n") { print "That was just a blank line!\n";} else { print "That line of input was: $line";}

%XW� LQ� SUDFWLFH�� \RX� GRQ¦W� RIWHQ�ZDQW� WR� NHHS� WKH� QHZOLQH�� VR� \RX� QHHG� WKH� chompRSHUDWRU�

The chomp Operator7KH�ILUVW�WLPH�\RX�UHDG�DERXW�WKH�chomp�RSHUDWRU��LW�VHHPV�WHUULEO\�RYHUVSHFLDOL]HG��,WZRUNV�RQ�D�YDULDEOH��7KH�YDULDEOH�KDV�WR�KROG�D�VWULQJ��$QG�LI�WKH�VWULQJ�HQGV�LQ�D�QHZOLQHFKDUDFWHU��chomp�FDQ�JHW�ULG�RI�WKH�QHZOLQH��7KDW¦V��QHDUO\��DOO�LW�GRHV��)RU�H[DPSOH�

$text = "a line of text\n"; # Or the same thing from <STDIN>chomp($text); # Gets rid of the newline character

%XW�LW�WXUQV�RXW�WR�EH�VR�XVHIXO��\RX¦OO�SXW�LW�LQWR�QHDUO\�HYHU\�SURJUDP�\RX�ZULWH��$V\RX�VHH��LW¦V�WKH�EHVW�ZD\�WR�UHPRYH�D�WUDLOLQJ�QHZOLQH�IURP�D�VWULQJ�LQ�D�YDULDEOH��,Q�IDFW�WKHUH¦V�DQ�HDVLHU�ZD\�WR�XVH�chomp�EHFDXVH�RI�D�VLPSOH�UXOH��DQ\�WLPH�WKDW�\RX�QHHG�DYDULDEOH�LQ�3HUO��\RX�FDQ�XVH�DQ�DVVLJQPHQW�LQVWHDG��)LUVW��3HUO�GRHV�WKH�DVVLJQPHQW�7KHQ�LW�XVHV�WKH�YDULDEOH�LQ�ZKDWHYHU�ZD\�\RX�UHTXHVWHG��6R�WKH�PRVW�FRPPRQ�XVH�RIchomp�ORRNV�OLNH�WKLV�

chomp($text = <STDIN>); # Read the text, without the newline character

$text = <STDIN>; # Do the same thing...chomp($text); # ...but in two steps

$W�ILUVW�JODQFH��WKH�FRPELQHG�chomp�PD\�QRW�VHHP�WR�EH�WKH�HDV\�ZD\��HVSHFLDOO\�LI�LWVHHPV�PRUH�FRPSOH[��,I�\RX�WKLQN�RI�LW�DV�WZR�RSHUDWLRQV¢UHDG�D�OLQH��WKHQ�chomp�LW¢WKHQ�LW¦V�PRUH�QDWXUDO�WR�ZULWH�LW�DV�WZR�VWDWHPHQWV��%XW�LI�\RX�WKLQN�RI�LW�DV�RQH�RSHUDWLRQ

7R�EH�KRQHVW��LW¦V�QRUPDOO\�\RXU�V\VWHP�WKDW�ZDLWV�IRU�WKH�LQSXW��3HUO�ZDLWV�IRU�\RXU�V\VWHP��$OWKRXJK�WKHGHWDLOV�GHSHQG�XSRQ�\RXU�V\VWHP�DQG�LWV�FRQILJXUDWLRQ��\RX�FDQ�JHQHUDOO\�FRUUHFW�\RXU�PLVW\SLQJ�ZLWK�WKHEDFNVSDFH�NH\�EHIRUH�\RX�SUHVV�5HWXUQ¢\RXU�V\VWHP�KDQGOHV�WKDW��QRW�3HUO�LWVHOI��,I�\RX�QHHG�PRUH�FRQWURORYHU�WKH�LQSXW��JHW�WKH�Term::ReadLine�PRGXOH�IURP�&3$1�

� 7KH�H[FHSWLRQ�LV�LI�WKH�VWDQGDUG�LQSXW�VWUHDP�VRPHKRZ�UXQV�RXW�LQ�WKH�PLGGOH�RI�D�OLQH��%XW�WKDW¦V�QRW�D�SURSHUWH[W�ILOH��RI�FRXUVH�

The chomp Operator | 35

¢UHDG�MXVW�WKH�WH[W��QRW�WKH�QHZOLQH¢LW¦V�PRUH�QDWXUDO�WR�ZULWH�WKH�RQH�VWDWHPHQW��$QGVLQFH�PRVW�RWKHU�3HUO�SURJUDPPHUV�DUH�JRLQJ�WR�ZULWH�LW�WKDW�ZD\��\RX�PD\�DV�ZHOO�JHWXVHG�WR�LW�QRZ�

chomp�LV�DFWXDOO\�D�IXQFWLRQ��$V�D�IXQFWLRQ��LW�KDV�D�UHWXUQ�YDOXH��ZKLFK�LV�WKH�QXPEHURI�FKDUDFWHUV�UHPRYHG��7KLV�QXPEHU�LV�KDUGO\�HYHU�XVHIXO�

$food = <STDIN>;$betty = chomp $food; # gets the value 1 - but you knew that!

$V�\RX�VHH��\RX�PD\�ZULWH�chomp�ZLWK�RU�ZLWKRXW�WKH�SDUHQWKHVHV��7KLV�LV�DQRWKHU�JHQHUDOUXOH�LQ�3HUO��H[FHSW�LQ�FDVHV�ZKHUH�LW�FKDQJHV�WKH�PHDQLQJ�WR�UHPRYH�WKHP��SDUHQWKHVHVDUH�DOZD\V�RSWLRQDO�

,I�D�OLQH�HQGV�ZLWK�WZR�RU�PRUH�QHZOLQHV� �chomp�UHPRYHV�RQO\�RQH��,I�WKHUH¦V�QR�QHZOLQH�LW�GRHV�QRWKLQJ��DQG�UHWXUQV�]HUR�

The while Control Structure/LNH�PRVW�DOJRULWKPLF�SURJUDPPLQJ�ODQJXDJHV��3HUO�KDV�D�QXPEHU�RI�ORRSLQJ�VWUXF�WXUHV���7KH�while�ORRS�UHSHDWV�D�EORFN�RI�FRGH�DV�ORQJ�DV�D�FRQGLWLRQ�LV�WUXH�

$count = 0;while ($count < 10) { $count += 2; print "count is now $count\n"; # Gives values 2 4 6 8 10}

$V�DOZD\V�LQ�3HUO��WKH�WUXWK�YDOXH�KHUH�ZRUNV�OLNH�WKH�WUXWK�YDOXH�LQ�WKH�if�WHVW��$OVR�OLNHWKH�if�FRQWURO�VWUXFWXUH��WKH�EORFN�FXUO\�EUDFHV�DUH�UHTXLUHG��7KH�FRQGLWLRQDO�H[SUHVVLRQLV�HYDOXDWHG�EHIRUH� WKH� ILUVW� LWHUDWLRQ��VR� WKH� ORRS�PD\�EH�VNLSSHG�FRPSOHWHO\� LI� WKHFRQGLWLRQ�LV�LQLWLDOO\�IDOVH�

The undef Value:KDW�KDSSHQV�LI�\RX�XVH�D�VFDODU�YDULDEOH�EHIRUH�\RX�JLYH�LW�D�YDOXH"�1RWKLQJ�VHULRXV�DQG�GHILQLWHO\�QRWKLQJ�IDWDO��9DULDEOHV�KDYH�WKH�VSHFLDO�undef�YDOXH�EHIRUH�WKH\�DUH�ILUVWDVVLJQHG��ZKLFK�LV�MXVW�3HUO¦V�ZD\�RI�VD\LQJ��£1RWKLQJ�KHUH�WR�ORRN�DW¢PRYH�DORQJ�PRYH�DORQJ�¤�,I�\RX�WU\�WR�XVH�WKLV�£QRWKLQJ¤�DV�D�£QXPHULF�VRPHWKLQJ�¤�LW�DFWV�OLNH]HUR�� ,I� \RX� WU\� WR�XVH� LW� DV� D� £VWULQJ� VRPHWKLQJ�¤� LW� DFWV� OLNH� WKH� HPSW\� VWULQJ��%XWundef�LV�QHLWKHU�D�QXPEHU�QRU�D�VWULQJ��LW¦V�DQ�HQWLUHO\�VHSDUDWH�NLQG�RI�VFDODU�YDOXH�

7KLV�VLWXDWLRQ�FDQ¦W�DULVH�LI�\RX¦UH�UHDGLQJ�D�OLQH�DW�D�WLPH��EXW�LW�FHUWDLQO\�FDQ�ZKHQ�\RX�KDYH�VHW�WKH�LQSXWVHSDUDWRU��$/��WR�VRPHWKLQJ�RWKHU�WKDQ�QHZOLQH��RU�XVHG�WKH�read�IXQFWLRQ��RU�SHUKDSV�KDYH�JOXHG�VRPH�VWULQJVWRJHWKHU�\RXUVHOI�

� (YHU\�SURJUDPPHU�HYHQWXDOO\�FUHDWHV�DQ�LQILQLWH�ORRS�E\�DFFLGHQW��,I�\RXU�SURJUDP�NHHSV�UXQQLQJ�DQG�UXQQLQJ�WKRXJK��\RX�FDQ�JHQHUDOO\�VWRS�LW�LQ�WKH�VDPH�ZD\�\RX¦G�VWRS�DQ\�RWKHU�SURJUDP�RQ�\RXU�V\VWHP��2IWHQ�W\SLQJ�&RQWURO�&�ZLOO�VWRS�D�UXQDZD\�SURJUDP��FKHFN�ZLWK�\RXU�V\VWHP¦V�GRFXPHQWDWLRQ�WR�EH�VXUH�

36 | Chapter 2:ಗScalar Data

%HFDXVH�undef�DXWRPDWLFDOO\�DFWV�OLNH�]HUR�ZKHQ�XVHG�DV�D�QXPEHU��LW¦V�HDV\�WR�PDNH�DQQXPHULF�DFFXPXODWRU�WKDW�VWDUWV�RXW�HPSW\�

# Add up some odd numbers$n = 1;while ($n < 10) { $sum += $n; $n += 2; # On to the next odd number}print "The total was $sum.\n";

7KLV�ZRUNV�SURSHUO\�ZKHQ�$sum�ZDV�undef�EHIRUH�WKH�ORRS�VWDUWHG��7KH�ILUVW�WLPH�WKURXJKWKH�ORRS�$n�LV�RQH��VR�WKH�ILUVW�OLQH�LQVLGH�WKH�ORRS�DGGV�RQH�WR�$sum��7KDW¦V�OLNH�DGGLQJRQH�WR�D�YDULDEOH�WKDW�DOUHDG\�KROGV�]HUR��EHFDXVH�\RX¦UH�XVLQJ�undef�DV� LI� LW�ZHUH�DQXPEHU���6R�QRZ�LW�KDV�WKH�YDOXH�1��$IWHU�WKDW��VLQFH�LW¦V�EHHQ�LQLWLDOL]HG��DGGLQJ�ZRUNVLQ�WKH�WUDGLWLRQDO�ZD\�

6LPLODUO\��\RX�FRXOG�KDYH�D�VWULQJ�DFFXPXODWRU�WKDW�VWDUWV�RXW�HPSW\�

$string .= "more text\n";

,I�$string�LV�undef��WKLV�ZLOO�DFW�DV�LI�LW�DOUHDG\�KHOG�WKH�HPSW\�VWULQJ��SXWWLQJ�"more text\n"�LQWR�WKDW�YDULDEOH��%XW�LI�LW�DOUHDG\�KROGV�D�VWULQJ��WKH�QHZ�WH[W�LV�VLPSO\�DSSHQGHG�

3HUO�SURJUDPPHUV�IUHTXHQWO\�XVH�D�QHZ�YDULDEOH�LQ�WKLV�ZD\��OHWWLQJ�LW�DFW�DV�HLWKHU�]HURRU�WKH�HPSW\�VWULQJ�DV�QHHGHG�

0DQ\�RSHUDWRUV�UHWXUQ�undef�ZKHQ�WKH�DUJXPHQWV�DUH�RXW�RI�UDQJH�RU�GRQ¦W�PDNH�VHQVH�,I�\RX�GRQ¦W�GR�DQ\WKLQJ�VSHFLDO��\RX¦OO�JHW�D�]HUR�RU�D�QXOO�VWULQJ�ZLWKRXW�PDMRU�FRQ�VHTXHQFHV��,Q�SUDFWLFH��WKLV�LV�KDUGO\�D�SUREOHP��,Q�IDFW��PRVW�SURJUDPPHUV�ZLOO�UHO\XSRQ�WKLV�EHKDYLRU��%XW�\RX�VKRXOG�NQRZ�WKDW�ZKHQ�ZDUQLQJV�DUH�WXUQHG�RQ��3HUO�ZLOOW\SLFDOO\�ZDUQ�DERXW�XQXVXDO�XVHV�RI�WKH�XQGHILQHG�YDOXH��VLQFH�WKDW�PD\�LQGLFDWH�DEXJ��)RU�H[DPSOH��VLPSO\�FRS\LQJ�undef�IURP�RQH�YDULDEOH�LQWR�DQRWKHU�LVQ¦W�D�SUREOHP�EXW�WU\LQJ�WR�print�LW�ZRXOG�JHQHUDOO\�FDXVH�D�ZDUQLQJ�

The defined Function7KH�OLQH�LQSXW�RSHUDWRU�<STDIN>�LV�RQH�RSHUDWRU�WKDW�FDQ�UHWXUQ�undef��1RUPDOO\��LW�ZLOOUHWXUQ�D� OLQH�RI� WH[W��EXW� LI� WKHUH� LV�QR�PRUH� LQSXW�� VXFK�DV�DW�HQG�RI�ILOH�� LW� UHWXUQVundef�WR�VLJQDO�WKLV� �7R�WHOO�ZKHWKHU�D�YDOXH�LV�undef�DQG�QRW�WKH�HPSW\�VWULQJ��XVH�WKH�defined�IXQFWLRQ��ZKLFK�UHWXUQV�IDOVH�IRU�undef��DQG�WUXH�IRU�HYHU\WKLQJ�HOVH�

$madonna = <STDIN>;if ( defined($madonna) ) { print "The input was $madonna";} else {

1RUPDOO\�� WKHUH¦V� QR� £HQG�RI�ILOH¤�ZKHQ� WKH� LQSXW� FRPHV� IURP� WKH� NH\ERDUG�� EXW� LQSXW�PD\� KDYH� EHHQUHGLUHFWHG�WR�FRPH�IURP�D�ILOH��2U�WKH�XVHU�PD\�KDYH�SUHVVHG�WKH�NH\�WKDW�WKH�V\VWHP�UHFRJQL]HV�WR�LQGLFDWHHQG�RI�ILOH�

The defined Function | 37

print "No input available!\n";}

,I�\RX¦G�OLNH�WR�PDNH�\RXU�RZQ�undef�YDOXHV��\RX�FDQ�XVH�WKH�REVFXUHO\�QDPHG�undefRSHUDWRU�

$madonna = undef; # As if it had never been touched

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >�@�:ULWH�D�SURJUDP�WKDW�FRPSXWHV�WKH�FLUFXPIHUHQFH�RI�D�FLUFOH�ZLWK�D�UDGLXV�RI������&LUFXPIHUHQFH�LV��˭�WLPHV�WKH�UDGLXV��DSSUR[LPDWHO\���WLPHV��������������7KH�DQVZHU�\RX�JHW�VKRXOG�EH�DERXW������

�� >�@�0RGLI\� WKH�SURJUDP�IURP�WKH�SUHYLRXV�H[HUFLVH� WR�SURPSW� IRU�DQG�DFFHSW�DUDGLXV�IURP�WKH�SHUVRQ�UXQQLQJ�WKH�SURJUDP��6R�� LI� WKH�XVHU�HQWHUV������IRU�WKHUDGLXV��VKH�VKRXOG�JHW�WKH�VDPH�QXPEHU�DV�LQ�WKH�SUHYLRXV�H[HUFLVH�

�� >�@�0RGLI\� WKH�SURJUDP�IURP�WKH�SUHYLRXV�H[HUFLVH�VR� WKDW�� LI� WKH�XVHU�HQWHUV�DQXPEHU� OHVV� WKDQ� ]HUR�� WKH� UHSRUWHG� FLUFXPIHUHQFH� ZLOO� EH� ]HUR�� UDWKHU� WKDQQHJDWLYH�

�� >�@�:ULWH�D�SURJUDP�WKDW�SURPSWV�IRU�DQG�UHDGV�WZR�QXPEHUV��RQ�VHSDUDWH�OLQHV�RILQSXW��DQG�SULQWV�RXW�WKH�SURGXFW�RI�WKH�WZR�QXPEHUV�PXOWLSOLHG�WRJHWKHU�

�� >�@�:ULWH�D�SURJUDP�WKDW�SURPSWV�IRU�DQG�UHDGV�D�VWULQJ�DQG�D�QXPEHU��RQ�VHSDUDWHOLQHV�RI�LQSXW��DQG�SULQWV�RXW�WKH�VWULQJ�WKH�QXPEHU�RI�WLPHV�LQGLFDWHG�E\�WKH�QXP�EHU�RQ�VHSDUDWH�OLQHV���+LQW��XVH�WKH�x�RSHUDWRU���,I�WKH�XVHU�HQWHUV�£IUHG¤�DQG�£�¤�WKH�RXWSXW�VKRXOG�EH�WKUHH�OLQHV��HDFK�VD\LQJ�£IUHG¤��,I�WKH�XVHU�HQWHUV�£IUHG¤�DQG£������¤��WKHUH�PD\�EH�D�ORW�RI�RXWSXW�

38 | Chapter 2:ಗScalar Data

CHAPTER 3

Lists and Arrays

,I�D�VFDODU�LV�WKH�£VLQJXODU¤�LQ�3HUO��DV�ZH�GHVFULEHG�LW�DW�WKH�EHJLQQLQJ�RI�&KDSWHU����WKH£SOXUDO¤�LQ�3HUO�LV�UHSUHVHQWHG�E\�OLVWV�DQG�DUUD\V�

$�OLVW�LV�DQ�RUGHUHG�FROOHFWLRQ�RI�VFDODUV��$Q�DUUD\�LV�D�YDULDEOH�WKDW�FRQWDLQV�D�OLVW��,Q3HUO��WKH�WZR�WHUPV�DUH�RIWHQ�XVHG�DV�LI�WKH\¦UH�LQWHUFKDQJHDEOH��%XW��WR�EH�DFFXUDWH��WKHOLVW�LV�WKH�GDWD��DQG�WKH�DUUD\�LV�WKH�YDULDEOH��<RX�FDQ�KDYH�D�OLVW�YDOXH�WKDW�LVQ¦W�LQ�DQDUUD\�� EXW� HYHU\� DUUD\� YDULDEOH� KROGV� D� OLVW� �DOWKRXJK� WKDW� OLVW�PD\� EH� HPSW\��� )LJ�XUH�����UHSUHVHQWV�D�OLVW��ZKHWKHU�LW¦V�VWRUHG�LQ�DQ�DUUD\�RU�QRW�

ELEM

ENT N

UMBE

RS(IN

DICE

S)

VALUES

0

1

2

3

4

35

12.4

“hello”

1.72e30

“bye\n”

)LJXUH������$�OLVW�ZLWK�ILYH�HOHPHQWV

(DFK�HOHPHQW�RI�DQ�DUUD\�RU�OLVW�LV�D�VHSDUDWH�VFDODU�YDULDEOH�ZLWK�DQ�LQGHSHQGHQW�VFDODUYDOXH��7KHVH�YDOXHV�DUH�RUGHUHG¢WKDW�LV��WKH\�KDYH�D�SDUWLFXODU�VHTXHQFH�IURP�WKH�ILUVWWR�WKH�ODVW�HOHPHQW��7KH�HOHPHQWV�RI�DQ�DUUD\�RU�OLVW�DUH�LQGH[HG�E\�VPDOO�LQWHJHUV�VWDUWLQJDW�]HUR �DQG�FRXQWLQJ�E\�RQHV��VR�WKH�ILUVW�HOHPHQW�RI�DQ\�DUUD\�RU�OLVW�LV�DOZD\V�HOHPHQW]HUR�

$UUD\�DQG�OLVW�LQGLFHV�DOZD\V�VWDUW�DW�]HUR�LQ�3HUO��XQOLNH�LQ�VRPH�RWKHU�ODQJXDJHV��,Q�HDUO\�3HUO��LW�ZDV�SRVVLEOHWR�FKDQJH�WKH�VWDUWLQJ�QXPEHU�RI�DUUD\�DQG�OLVW�LQGH[LQJ��QRW�IRU�MXVW�RQH�DUUD\�RU�OLVW��EXW�IRU�DOO�RI�WKHP�DWRQFH����/DUU\�ODWHU�UHDOL]HG�WKDW�WKLV�ZDV�D�PLVIHDWXUH��DQG�LWV��DE�XVH�LV�QRZ�VWURQJO\�GLVFRXUDJHG��%XW��LI\RX¦UH�WHUPLQDOO\�FXULRXV��ORRN�XS�WKH�$[�YDULDEOH�LQ�WKH�SHUOYDU�PDQSDJH�

39

6LQFH�HDFK�HOHPHQW�LV�DQ�LQGHSHQGHQW�VFDODU�YDOXH��D�OLVW�RU�DUUD\�PD\�KROG�QXPEHUV�VWULQJV��undef�YDOXHV��RU�DQ\�PL[WXUH�RI�GLIIHUHQW�VFDODU�YDOXHV��1HYHUWKHOHVV��LW¦V�PRVWFRPPRQ�WR�KDYH�DOO�HOHPHQWV�RI�WKH�VDPH�W\SH��VXFK�DV�D�OLVW�RI�ERRN�WLWOHV��DOO�VWULQJV�RU�D�OLVW�RI�FRVLQHV��DOO�QXPEHUV��

$UUD\V�DQG�OLVWV�FDQ�KDYH�DQ\�QXPEHU�RI�HOHPHQWV��7KH�VPDOOHVW�RQH�KDV�QR�HOHPHQWV�ZKLOH�WKH�ODUJHVW�FDQ�ILOO�DOO�RI�WKH�DYDLODEOH�PHPRU\��2QFH�DJDLQ��WKLV�LV�LQ�NHHSLQJ�ZLWK3HUO¦V�SKLORVRSK\�RI�£QR�XQQHFHVVDU\�OLPLWV�¤

Accessing Elements of an Array,I�\RX¦YH�XVHG�DUUD\V� LQ�DQRWKHU� ODQJXDJH��\RX�ZRQ¦W�EH� VXUSULVHG� WR� ILQG� WKDW�3HUOSURYLGHV�D�ZD\�WR�VXEVFULSW�DQ�DUUD\�LQ�RUGHU�WR�UHIHU�WR�DQ�HOHPHQW�E\�D�QXPHULF�LQGH[�

7KH�DUUD\�HOHPHQWV�DUH�QXPEHUHG�XVLQJ�VHTXHQWLDO�LQWHJHUV��EHJLQQLQJ�DW�]HUR�DQG�LQ�FUHDVLQJ�E\�RQH�IRU�HDFK�HOHPHQW��OLNH�WKLV�

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

7KH�DUUD\�QDPH�LWVHOI��LQ�WKLV�FDVH��"fred"��LV�IURP�D�FRPSOHWHO\�VHSDUDWH�QDPHVSDFHWKDQ�VFDODUV�XVH��\RX�FRXOG�KDYH�D�VFDODU�YDULDEOH�QDPHG�$fred�LQ�WKH�VDPH�SURJUDP�DQG�3HUO�ZLOO�WUHDW�WKHP�DV�GLIIHUHQW�WKLQJV�DQG�ZRXOGQ¦W�EH�FRQIXVHG� ��<RXU�PDLQWH�QDQFH�SURJUDPPHU�PLJKW�EH�FRQIXVHG��WKRXJK��VR�GRQ¦W�FDSULFLRXVO\�PDNH�DOO�RI�\RXUYDULDEOH�QDPHV�WKH�VDPH��

<RX�FDQ�XVH�DQ�DUUD\�HOHPHQW�OLNH�$fred[2]�LQ�HYHU\�SODFH��ZKHUH�\RX�FRXOG�XVH�DQ\RWKHU�VFDODU�YDULDEOH�OLNH�$fred��)RU�H[DPSOH��\RX�FDQ�JHW�WKH�YDOXH�IURP�DQ�DUUD\�HOH�PHQW�RU�FKDQJH�WKDW�YDOXH�E\�WKH�VDPH�VRUWV�RI�H[SUHVVLRQV�ZH�XVHG�LQ�WKH�SUHYLRXVFKDSWHU�

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

2I�FRXUVH��WKH�VXEVFULSW�PD\�EH�DQ\�H[SUHVVLRQ�WKDW�JLYHV�D�QXPHULF�YDOXH��,I�LW¦V�QRWDQ�LQWHJHU�DOUHDG\��LW¦OO�DXWRPDWLFDOO\�EH�WUXQFDWHG�WR�WKH�QH[W�ORZHU�LQWHJHU�

$number = 2.71828;print $fred[$number ! 1]; # Same as printing $fred[1]

,I�WKH�VXEVFULSW�LQGLFDWHV�DQ�HOHPHQW�WKDW�ZRXOG�EH�EH\RQG�WKH�HQG�RI�WKH�DUUD\��WKHFRUUHVSRQGLQJ�YDOXH�ZLOO�EH�undef��7KLV�LV�MXVW�DV�ZLWK�RUGLQDU\�VFDODUV��LI�\RX¦YH�QHYHUVWRUHG�D�YDOXH�LQWR�WKH�YDULDEOH��LW¦V�undef�

7KH�V\QWD[�LV�DOZD\V�XQDPELJXRXV¢WULFN\�SHUKDSV��EXW�XQDPELJXRXV�

� :HOO��DOPRVW��7KH�PRVW�QRWDEOH�H[FHSWLRQ�LV�WKDW�WKH�FRQWURO�YDULDEOH�RI�D�foreach�ORRS��ZKLFK�\RX¦OO�VHH�ODWHULQ�WKLV�FKDSWHU��PXVW�EH�D�VLPSOH�VFDODU��$QG�WKHUH�DUH�RWKHUV��OLNH�WKH�£LQGLUHFW�REMHFW�VORW¤�DQG�£LQGLUHFWILOHKDQGOH�VORW¤�IRU�print�DQG�printf�

40 | Chapter 3:ಗLists and Arrays

$blank = $fred[ 142_857 ]; # unused array element gives undef$blanc = $mel; # unused scalar $mel also gives undef

Special Array Indices,I� \RX� VWRUH� LQWR�DQ�DUUD\� HOHPHQW� WKDW� LV�EH\RQG� WKH� HQG�RI� WKH�DUUD\�� WKH�DUUD\� LVDXWRPDWLFDOO\�H[WHQGHG�DV�QHHGHG¢WKHUH¦V�QR�OLPLW�RQ�LWV� OHQJWK��DV� ORQJ�DV�WKHUH¦VDYDLODEOH�PHPRU\�IRU�3HUO�WR�XVH��,I�3HUO�QHHGV�WR�FUHDWH�WKH�LQWHUYHQLQJ�HOHPHQWV��LWFUHDWHV�WKHP�DV�undef�YDOXHV�

$rocks[0] = 'bedrock'; # One element...$rocks[1] = 'slate'; # another...$rocks[2] = 'lava'; # and another...$rocks[3] = 'crushed rock'; # and another...$rocks[99] = 'schist'; # now there are 95 undef elements

6RPHWLPHV��\RX�QHHG�WR�ILQG�RXW�WKH�ODVW�HOHPHQW�LQGH[�LQ�DQ�DUUD\��)RU�WKH�DUUD\�RIrocks�WKDW�ZH¦YH�MXVW�EHHQ�XVLQJ��WKH�ODVW�HOHPHQW�LQGH[�LV�$#rocks� �7KDW¦V�QRW�WKH�VDPHDV�WKH�QXPEHU�RI�HOHPHQWV��WKRXJK��EHFDXVH�WKHUH¦V�DQ�HOHPHQW�QXPEHU�]HUR�

$end = $#rocks; # 99, which is the last element's index$number_of_rocks = $end + 1; # okay, but you'll see a better way later$rocks[ $#rocks ] = 'hard rock'; # the last rock

8VLQJ�WKH�$#name�YDOXH�DV�DQ�LQGH[��OLNH�WKDW�ODVW�H[DPSOH��KDSSHQV�RIWHQ�HQRXJK�WKDW/DUU\�KDV�SURYLGHG�D�VKRUWFXW��QHJDWLYH�DUUD\�LQGLFHV�FRXQW�IURP�WKH�HQG�RI�WKH�DUUD\�%XW�GRQ¦W�JHW�WKH�LGHD�WKDW�WKHVH�LQGLFHV�£ZUDS�DURXQG�¤�,I�\RX¦YH�JRW�WKUHH�HOHPHQWVLQ�WKH�DUUD\��WKH�YDOLG�QHJDWLYH�LQGLFHV�DUH�!1��WKH�ODVW�HOHPHQW���!2��WKH�PLGGOH�HOHPHQW��DQG�!3��WKH�ILUVW�HOHPHQW���,Q�WKH�UHDO�ZRUOG��QRERG\�VHHPV�WR�XVH�DQ\�RI�WKHVH�H[FHSW!1��WKRXJK�

$rocks[ !1 ] = 'hard rock'; # easier way to do that last example$dead_rock = $rocks[!100]; # gets 'bedrock'$rocks[ !200 ] = 'crystal'; # fatal error!

List Literals$Q�DUUD\��WKH�ZD\�\RX�UHSUHVHQW�D�OLVW�YDOXH�ZLWKLQ�\RXU�SURJUDP��LV�D�OLVW�RI�FRPPD�VHSDUDWHG�YDOXHV�HQFORVHG�LQ�SDUHQWKHVHV��7KHVH�YDOXHV�IRUP�WKH�HOHPHQWV�RI�WKH�OLVW�)RU�H[DPSOH�

(1, 2, 3) # list of three values 1, 2, and 3(1, 2, 3,) # the same three values (the trailing comma is ignored)("fred", 4.5) # two values, "fred" and 4.5( ) # empty list - zero elements(1..100) # list of 100 integers

%ODPH�WKLV�XJO\�V\QWD[�RQ�WKH�&�VKHOO��)RUWXQDWHO\��\RX�GRQ¦W�KDYH�WR�ORRN�DW�WKLV�YHU\�RIWHQ�LQ�WKH�UHDO�ZRUOG�

Special Array Indices | 41

7KDW� ODVW�RQH�XVHV� WKH� ��� UDQJH�RSHUDWRU��ZKLFK� LV� VHHQ�KHUH� IRU� WKH� ILUVW� WLPH��7KDWRSHUDWRU�FUHDWHV�D�OLVW�RI�YDOXHV�E\�FRXQWLQJ�IURP�WKH�OHIW�VFDODU�XS�WR�WKH�ULJKW�VFDODUE\�RQHV��)RU�H[DPSOH�

(1..5) # same as (1, 2, 3, 4, 5)(1.7..5.7) # same thing - both values are truncated(5..1) # empty list - .. only counts "uphill"(0, 2..6, 10, 12) # same as (0, 2, 3, 4, 5, 6, 10, 12)($m..$n) # range determined by current values of $m and $n(0..$#rocks) # the indices of the rocks array from the previous section

$V�\RX�FDQ�VHH�IURP�WKRVH�ODVW�WZR�LWHPV��WKH�HOHPHQWV�RI�D�OLVW�OLWHUDO�DUH�QRW�QHFHVVDULO\FRQVWDQWV¢WKH\�FDQ�EH�H[SUHVVLRQV�WKDW�ZLOO�EH�QHZO\�HYDOXDWHG�HDFK�WLPH�WKH�OLWHUDOLV�XVHG��)RU�H[DPSOH�

($m, 17) # two values: the current value of $m, and 17($m+$o, $p+$q) # two values

2I�FRXUVH��D�OLVW�PD\�KDYH�DQ\�VFDODU�YDOXHV��OLNH�WKLV�W\SLFDO�OLVW�RI�VWULQJV�

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

The qw Shortcut,W�WXUQV�RXW�WKDW�OLVWV�RI�VLPSOH�ZRUGV��OLNH�WKH�SUHYLRXV�H[DPSOH��DUH�IUHTXHQWO\�QHHGHGLQ�3HUO�SURJUDPV��7KH�qw�VKRUWFXW�PDNHV�LW�HDV\�WR�JHQHUDWH�WKHP�ZLWKRXW�W\SLQJ�D�ORWRI�H[WUD�TXRWH�PDUNV�

qw( fred barney betty wilma dino ) # same as above, but less typing

qw�VWDQGV�IRU�£TXRWHG�ZRUGV¤�RU�£TXRWHG�E\�ZKLWHVSDFH�¤�GHSHQGLQJ�XSRQ�ZKRP�\RXDVN��(LWKHU�ZD\��3HUO�WUHDWV�LW�OLNH�D�VLQJOH�TXRWHG�VWULQJ��VR��\RX�FDQ¦W�XVH�\n�RU�$fredLQVLGH�D�qw�OLVW�DV�\RX�ZRXOG�LQ�D�GRXEOH�TXRWHG�VWULQJ���7KH�ZKLWHVSDFH��FKDUDFWHUV�OLNHVSDFHV��WDEV��DQG�QHZOLQHV��ZLOO�EH�GLVFDUGHG��DQG�ZKDWHYHU�LV�OHIW�EHFRPHV�WKH�OLVW�RILWHPV��6LQFH�ZKLWHVSDFH�LV�GLVFDUGHG��KHUH¦V�DQRWKHU��EXW�XQXVXDO��ZD\�WR�ZULWH�WKDWVDPH�OLVW�

qw(fred barney bettywilma dino) # same as above, but pretty strange whitespace

6LQFH�qw�LV�D�IRUP�RI�TXRWLQJ��WKRXJK��\RX�FDQ¦W�SXW�FRPPHQWV�LQVLGH�D�qw�OLVW�

7KH�SUHYLRXV�WZR�H[DPSOHV�KDYH�XVHG�SDUHQWKHVHV�DV�WKH�GHOLPLWHU��EXW�3HUO�DFWXDOO\OHWV�\RX�FKRRVH�DQ\�SXQFWXDWLRQ�FKDUDFWHU�DV�WKH�GHOLPLWHU��+HUH�DUH�VRPH�RI�WKH�FRP�PRQ�RQHV�

qw! fred barney betty wilma dino !qw/ fred barney betty wilma dino /qw# fred barney betty wilma dino # # like in a comment!qw( fred barney betty wilma dino )qw{ fred barney betty wilma dino }qw[ fred barney betty wilma dino ]qw< fred barney betty wilma dino >

42 | Chapter 3:ಗLists and Arrays

$V�WKRVH�ODVW�IRXU�VKRZ��VRPHWLPHV�WKH�WZR�GHOLPLWHUV�FDQ�EH�GLIIHUHQW��,I�WKH�RSHQLQJGHOLPLWHU�LV�RQH�RI�WKRVH�£OHIW¤�FKDUDFWHUV��WKH�FRUUHVSRQGLQJ�£ULJKW¤�FKDUDFWHU�LV�WKHSURSHU�FORVLQJ�GHOLPLWHU��2WKHU�GHOLPLWHUV�XVH�WKH�VDPH�FKDUDFWHU�IRU�VWDUW�DQG�ILQLVK�

,I�\RX�QHHG�WR�LQFOXGH�WKH�FORVLQJ�GHOLPLWHU�ZLWKLQ�WKH�VWULQJ�DV�RQH�RI�WKH�FKDUDFWHUV�\RX�SUREDEO\�SLFNHG�WKH�ZURQJ�GHOLPLWHU��%XW�HYHQ�LI�\RX�FDQ¦W�RU�GRQ¦W�ZDQW�WR�FKDQJHWKH�GHOLPLWHU��\RX�FDQ�VWLOO�LQFOXGH�WKH�FKDUDFWHU�XVLQJ�WKH�EDFNVODVK�

qw! yahoo\! google ask msn ! # include yahoo! as an element

$V�LQ�VLQJOH�TXRWHG�VWULQJV��WZR�FRQVHFXWLYH�EDFNVODVKHV�FRQWULEXWH�RQH�VLQJOH�EDFN�VODVK�WR�WKH�LWHP�

1RZ��DOWKRXJK�WKH�3HUO�PRWWR�LV�7KHUH¦V�0RUH�7KDQ�2QH�:D\�7R�'R�,W��\RX�PD\�ZHOOZRQGHU�ZK\�DQ\RQH�ZRXOG�QHHG�DOO�RI�WKRVH�GLIIHUHQW�ZD\V��:HOO��\RX¦OO�VHH�ODWHU�WKDWWKHUH�DUH�RWKHU�NLQGV�RI�TXRWLQJ�ZKHUH�3HUO�XVHV�WKLV�VDPH�UXOH��DQG�LW�FDQ�FRPH�LQ�KDQG\LQ�PDQ\�RI�WKRVH��%XW�HYHQ�KHUH��LW�FRXOG�EH�XVHIXO�LI�\RX�ZHUH�WR�QHHG�D�OLVW�RI�8QL[ILOHQDPHV�

qw{ /usr/dict/words /home/rootbeer/.ispell_english}

7KDW�OLVW�ZRXOG�EH�TXLWH�LQFRQYHQLHQW�WR�UHDG��ZULWH��DQG�PDLQWDLQ�LI�WKH�VODVK�ZHUH�WKHRQO\�GHOLPLWHU�DYDLODEOH�

List Assignment,Q�PXFK�WKH�VDPH�ZD\�DV�VFDODU�YDOXHV�PD\�EH�DVVLJQHG�WR�YDULDEOHV��OLVW�YDOXHV�PD\DOVR�EH�DVVLJQHG�WR�YDULDEOHV�

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

$OO�WKUHH�YDULDEOHV�LQ�WKH�OLVW�RQ�WKH�OHIW�JHW�QHZ�YDOXHV��MXVW�DV�LI�\RX�GLG�WKUHH�VHSDUDWHDVVLJQPHQWV��6LQFH�WKH�OLVW�LV�EXLOW�XS�EHIRUH�WKH�DVVLJQPHQW�VWDUWV��WKLV�PDNHV�LW�HDV\WR�VZDS�WZR�YDULDEOHV¦�YDOXHV�LQ�3HUO�

($fred, $barney) = ($barney, $fred); # swap those values($betty[0], $betty[1]) = ($betty[1], $betty[0]);

$V�RSSRVHG�WR�LQ�ODQJXDJHV�OLNH�&��LQ�ZKLFK�WKHUH�LV�QR�HDV\�ZD\�WR�GR�WKLV�LQ�JHQHUDO��&�SURJUDPPHUV�XVHDQ�DX[LOLDU\�VZDS�YDULDEOH�WR�WHPSRUDULO\�KROG�WKH�YDOXH��SRVVLEO\�PDQDJHG�YLD�D�PDFUR�

List Assignment | 43

%XW�ZKDW�KDSSHQV�LI�WKH�QXPEHU�RI�YDULDEOHV��RQ�WKH�OHIW�VLGH�RI�WKH�HTXDOV�VLJQ��LVQ¦WWKH�VDPH�DV�WKH�QXPEHU�RI�YDOXHV��IURP�WKH�ULJKW�VLGH�"�,Q�D�OLVW�DVVLJQPHQW��H[WUD�YDOXHVDUH�VLOHQWO\�LJQRUHG¢3HUO�ILJXUHV�WKDW�LI�\RX�ZDQWHG�WKRVH�YDOXHV�VWRUHG�VRPHZKHUH�\RX�ZRXOG�KDYH�WROG�LW�ZKHUH�WR�VWRUH�WKHP��$OWHUQDWLYHO\��LI�\RX�KDYH�WRR�PDQ\�YDUL�DEOHV��WKH�H[WUDV�JHW�WKH�YDOXH�undef�

($fred, $barney) = qw< flintstone rubble slate granite >; # two ignored items($wilma, $dino) = qw[flintstone]; # $dino gets undef

1RZ�WKDW�\RX�FDQ�DVVLJQ�OLVWV��\RX�FRXOG�EXLOG�XS�DQ�DUUD\�RI�VWULQJV�ZLWK�D�OLQH�RI�FRGHOLNH�WKLV��

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

%XW�ZKHQ�\RX�ZLVK�WR�UHIHU�WR�DQ�HQWLUH�DUUD\��3HUO�KDV�D�VLPSOHU�QRWDWLRQ��-XVW�XVH�WKH�DW�VLJQ��@��EHIRUH�WKH�QDPH�RI�WKH�DUUD\��DQG�QR�LQGH[�EUDFNHWV�DIWHU�LW��WR�UHIHU�WR�WKHHQWLUH�DUUD\�DW�RQFH��<RX�FDQ�UHDG�WKLV�DV�£DOO�RI�WKH�¤�VR�@rocks�LV�£DOO�RI�WKH�URFNV�¤®

7KLV�ZRUNV�RQ�HLWKHU�VLGH�RI�WKH�DVVLJQPHQW�RSHUDWRU�

@rocks = qw/ bedrock slate lava /;@tiny = ( ); # the empty list@giant = 1..1e5; # a list with 100,000 elements@stuff = (@giant, undef, @giant); # a list with 200,001 elements$dino = "granite";@quarry = (@rocks, "crushed rock", @tiny, $dino);

7KDW�ODVW�DVVLJQPHQW�JLYHV�@quarry�WKH�ILYH�HOHPHQW�OLVW��bedrock��slate��lava��crushedrock��granite���VLQFH�@tiny�FRQWULEXWHV�]HUR�HOHPHQWV�WR�WKH�OLVW���,Q�SDUWLFXODU��LW�GRHVQ¦WSXW� DQ� undef� LWHP� LQWR� WKH� OLVW¢EXW� \RX� FRXOG� GR� WKDW� H[SOLFLWO\�� DV� ZH� GLG� ZLWK@stuff�HDUOLHU���,W¦V�DOVR�ZRUWK�QRWLQJ�WKDW�DQ�DUUD\�QDPH�LV�UHSODFHG�E\�WKH�OLVW�LW�FRQ�WDLQV��$Q�DUUD\�GRHVQ¦W�EHFRPH�DQ�HOHPHQW�LQ�WKH�OLVW�EHFDXVH�WKHVH�DUUD\V�FDQ�FRQWDLQRQO\�VFDODUV��QRW�RWKHU�DUUD\V��7KH�YDOXH�RI�DQ�DUUD\�YDULDEOH�WKDW�KDV�QRW�\HW�EHHQDVVLJQHG�LV�( )��WKH�HPSW\�OLVW��-XVW�DV�QHZ��HPSW\�VFDODUV�VWDUW�RXW�ZLWK�undef��QHZ�HPSW\�DUUD\V�VWDUW�RXW�ZLWK�WKH�HPSW\�OLVW�

,W¦V�ZRUWK�QRWLQJ�WKDW�ZKHQ�DQ�DUUD\�LV�FRSLHG�WR�DQRWKHU�DUUD\��LW¦V�VWLOO�D�OLVW�DVVLJQPHQW�7KH�OLVWV�DUH�VLPSO\�VWRUHG�LQ�DUUD\V��)RU�H[DPSOH�

@copy = @quarry; # copy a list from one array to another

:HOO��WKDW¦V�WUXH�IRU�VFDODU�YDULDEOHV��$UUD\�YDULDEOHV�JHW�DQ�HPSW\�OLVW��DV�\RX¦OO�VHH�LQ�D�PRPHQW�

� :H¦UH�FKHDWLQJ�E\�DVVXPLQJ�WKDW�WKH�rocks�DUUD\� LV�HPSW\�EHIRUH�WKLV�VWDWHPHQW�� ,I� WKHUH�ZHUH�D�YDOXH� LQ$rocks[7]��VD\��WKLV�DVVLJQPHQW�ZRXOGQ¦W�DIIHFW�WKDW�HOHPHQW�

® /DUU\�FODLPV�WKDW�KH�FKRVH�WKH�GROODU�DQG�DW�VLJQ�EHFDXVH�WKH\�FDQ�EH�UHDG�DV�$calar��VFDODU��DQG�@rray��DUUD\��,I�\RX�GRQ¦W�JHW�WKDW��RU�UHPHPEHU�LW�WKDW�ZD\��QR�ELJ�GHDO�

%XW�LQ�WKH�$OSDFD�ERRN��ZH¦OO�VKRZ�\RX�D�VSHFLDO�NLQG�RI�VFDODU�FDOOHG�D�UHIHUHQFH��7KDW�OHWV�XV�PDNH�ZKDW�DUHLQIRUPDOO\�FDOOHG�£OLVWV�RI�OLVWV�¤�DPRQJ�RWKHU�LQWHUHVWLQJ�DQG�XVHIXO�VWUXFWXUHV��%XW�LQ�WKDW�FDVH��\RX¦UH�VWLOOQRW�UHDOO\�VWRULQJ�D�OLVW�LQWR�D�OLVW��\RX¦UH�VWRULQJ�D�UHIHUHQFH�WR�DQ�DUUD\�

44 | Chapter 3:ಗLists and Arrays

The pop and push Operators<RX�FRXOG�DGG�QHZ�LWHPV�WR�WKH�HQG�RI�DQ�DUUD\�E\�VLPSO\�VWRULQJ�WKHP�DV�HOHPHQWVZLWK�QHZ��ODUJHU�LQGLFHV��%XW�UHDO�3HUO�SURJUDPPHUV�GRQ¦W�XVH�LQGLFHV� �6R�LQ�WKH�QH[WIHZ�VHFWLRQV��ZH¦OO�SUHVHQW�VRPH�ZD\V�WR�ZRUN�ZLWK�DQ�DUUD\�ZLWKRXW�XVLQJ�LQGLFHV�

2QH�FRPPRQ�XVH�RI�DQ�DUUD\�LV�DV�D�VWDFN�RI�LQIRUPDWLRQ��ZKHUH�QHZ�YDOXHV�DUH�DGGHGWR�DQG�UHPRYHG�IURP�WKH�ULJKW�VLGH�RI�WKH�OLVW���7KLV�LV�WKH�HQG�ZLWK�WKH�£ODVW¤�LWHPV�LQWKH�DUUD\��WKH�HQG�ZLWK�WKH�KLJKHVW�LQGH[�YDOXHV���7KHVH�RSHUDWLRQV�RFFXU�RIWHQ�HQRXJKWR�KDYH�WKHLU�RZQ�VSHFLDO�IXQFWLRQV�

7KH�pop�RSHUDWRU�WDNHV�WKH�ODVW�HOHPHQW�RII�RI�DQ�DUUD\�DQG�UHWXUQV�LW�

@array = 5..9;$fred = pop(@array); # $fred gets 9, @array now has (5, 6, 7, 8)$barney = pop @array; # $barney gets 8, @array now has (5, 6, 7)pop @array; # @array now has (5, 6). (The 7 is discarded.)

7KDW�ODVW�H[DPSOH�XVHV�pop�£LQ�D�YRLG�FRQWH[W�¤�ZKLFK�LV�PHUHO\�D�IDQF\�ZD\�RI�VD\LQJWKH�UHWXUQ�YDOXH�LVQ¦W�JRLQJ�DQ\ZKHUH��7KHUH¦V�QRWKLQJ�ZURQJ�ZLWK�XVLQJ�pop�LQ�WKLVZD\��LI�WKDW¦V�ZKDW�\RX�ZDQW�

,I�WKH�DUUD\�LV�HPSW\��pop�ZLOO�OHDYH�LW�DORQH��VLQFH�WKHUH�LV�QR�HOHPHQW�WR�UHPRYH���DQGLW�ZLOO�UHWXUQ�undef�

<RX�PD\�KDYH�QRWLFHG�WKDW�pop�PD\�EH�XVHG�ZLWK�RU�ZLWKRXW�SDUHQWKHVHV��7KLV� LV�DJHQHUDO�UXOH�LQ�3HUO��DV�ORQJ�DV�\RX�GRQ¦W�FKDQJH�WKH�PHDQLQJ�E\�UHPRYLQJ�WKH�SDUHQ�WKHVHV��WKH\¦UH�RSWLRQDO���7KH�FRQYHUVH�RSHUDWLRQ�LV�push��ZKLFK�DGGV�DQ�HOHPHQW��RU�DOLVW�RI�HOHPHQWV��WR�WKH�HQG�RI�DQ�DUUD\�

push(@array, 0); # @array now has (5, 6, 0)push @array, 8; # @array now has (5, 6, 0, 8)push @array, 1..10; # @array now has those ten new elements@others = qw/ 9 0 2 1 0 /;push @array, @others; # @array now has those five new elements (19 total)

1RWH�WKDW�WKH�ILUVW�DUJXPHQW�WR�push�RU�WKH�RQO\�DUJXPHQW�IRU�pop�PXVW�EH�DQ�DUUD\YDULDEOH¢SXVKLQJ�DQG�SRSSLQJ�ZRXOG�QRW�PDNH�VHQVH�RQ�D�OLWHUDO�OLVW�

2I�FRXUVH��ZH¦UH�MRNLQJ��%XW�WKHUH¦V�D�NHUQHO�RI�WUXWK�LQ�WKLV�MRNH��,QGH[LQJ�LQWR�DUUD\V�LV�QRW�XVLQJ�3HUO¦VVWUHQJWKV��,I�\RX�XVH�WKH�pop��push��DQG�VLPLODU�RSHUDWRUV�WKDW�DYRLG�XVLQJ�LQGH[LQJ��\RXU�FRGH�ZLOO�JHQHUDOO\EH�IDVWHU�WKDQ�LI�\RX�XVH�PDQ\�LQGLFHV��DV�ZHOO�DV�DYRLGLQJ�£RII�E\�RQH¤�HUURUV��RIWHQ�FDOOHG�£IHQFHSRVW¤�HUURUV�2FFDVLRQDOO\��D�EHJLQQLQJ�3HUO�SURJUDPPHU��ZDQWLQJ�WR�VHH�KRZ�3HUO¦V�VSHHG�FRPSDUHV�WR�&¦V��ZLOO�WDNH��VD\�D�VRUWLQJ�DOJRULWKP�RSWLPL]HG�IRU�&��ZLWK�PDQ\�DUUD\�LQGH[�RSHUDWLRQV���UHZULWH�LW�VWUDLJKWIRUZDUGO\�LQ�3HUO�DJDLQ��ZLWK�PDQ\�LQGH[�RSHUDWLRQV��DQG�ZRQGHU�ZK\�LW¦V�VR�VORZ��7KH�DQVZHU�LV�WKDW�XVLQJ�D�6WUDGLYDULXVYLROLQ�WR�SRXQG�QDLOV�VKRXOG�QRW�EH�FRQVLGHUHG�D�VRXQG�FRQVWUXFWLRQ�WHFKQLTXH�

� $�UHDGHU�IURP�WKH�HGXFDWHG�FODVV�ZLOO�UHFRJQL]H�WKDW�WKLV�LV�D�WDXWRORJ\�

List Assignment | 45

The shift and unshift Operators7KH�push�DQG�pop�RSHUDWRUV�GR�WKLQJV�WR�WKH�HQG�RI�DQ�DUUD\��RU�WKH�ULJKW�VLGH�RI�DQ�DUUD\�RU�WKH�SRUWLRQ�ZLWK�WKH�KLJKHVW�VXEVFULSWV��GHSHQGLQJ�XSRQ�KRZ�\RX�OLNH�WR�WKLQN�RILW���6LPLODUO\��WKH�unshift�DQG�shift�RSHUDWRUV�SHUIRUP�WKH�FRUUHVSRQGLQJ�DFWLRQV�RQWKH�£VWDUW¤�RI�WKH�DUUD\��RU�WKH�£OHIW¤�VLGH�RI�DQ�DUUD\��RU�WKH�SRUWLRQ�ZLWK�WKH�ORZHVWVXEVFULSWV���+HUH�DUH�D�IHZ�H[DPSOHV�

@array = qw# dino fred barney #;$m = shift(@array); # $m gets "dino", @array now has ("fred", "barney")$n = shift @array; # $n gets "fred", @array now has ("barney")shift @array; # @array is now empty$o = shift @array; # $o gets undef, @array is still emptyunshift(@array, 5); # @array now has the one-element list (5)unshift @array, 4; # @array now has (4, 5)@others = 1..3;unshift @array, @others; # @array now has (1, 2, 3, 4, 5)

$QDORJRXV�WR�pop��shift�UHWXUQV�undef�LI�JLYHQ�DQ�HPSW\�DUUD\�YDULDEOH�

Interpolating Arrays into Strings/LNH�VFDODUV��DUUD\�YDOXHV�PD\�EH�LQWHUSRODWHG�LQWR�D�GRXEOH�TXRWHG�VWULQJ��(OHPHQWV�RIDQ�DUUD\�DUH�DXWRPDWLFDOO\�VHSDUDWHG�E\�VSDFHV �XSRQ�LQWHUSRODWLRQ�

@rocks = qw{ flintstone slate rubble };print "quartz @rocks limestone\n"; # prints five rocks separated by spaces

7KHUH�DUH�QR�H[WUD�VSDFHV�DGGHG�EHIRUH�RU�DIWHU�DQ�LQWHUSRODWHG�DUUD\��LI�\RX�ZDQW�WKRVH�\RX¦OO�KDYH�WR�SXW�WKHP�LQ�\RXUVHOI�

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

,I�\RX�IRUJHW�WKDW�DUUD\V�LQWHUSRODWH�OLNH�WKLV��\RX¦OO�EH�VXUSULVHG�ZKHQ�\RX�SXW�DQ�HPDLODGGUHVV�LQWR�D�GRXEOH�TXRWHG�VWULQJ�

$email = "fred@bedrock.edu"; # WRONG! Tries to interpolate @bedrock

$OWKRXJK�ZH�LQWHQGHG�WR�KDYH�DQ�HPDLO�DGGUHVV��3HUO�VHHV�WKH�DUUD\�QDPHG�@bedrockDQG�WULHV�WR�LQWHUSRODWH�LW��'HSHQGLQJ�RQ�RXU�YHUVLRQ�RI�3HUO��ZH¦OO�SUREDEO\�MXVW�JHW�DZDUQLQJ��

Possible unintended interpolation of @bedrock

7R�JHW�DURXQG�WKLV�SUREOHP��ZH�HLWKHU�HVFDSH�WKH�@�LQ�D�GRXEOH�TXRWHG�VWULQJ�RU�XVH�D�VLQJOH�TXRWHG�VWULQJ�

$FWXDOO\��WKH�VHSDUDWRU�LV�WKH�YDOXH�RI�WKH�VSHFLDO�$"�YDULDEOH��ZKLFK�LV�D�VSDFH�E\�GHIDXOW�

� 6RPH�3HUO�YHUVLRQV�EHIRUH�����DFWXDOO\�PDGH�WKLV�D�IDWDO�HUURU��EXW�LW�ZDV�FKDQJHG�WR�D�ZDUQLQJ�EHFDXVH�WKDWZDV�WRR�DQQR\LQJ�

46 | Chapter 3:ಗLists and Arrays

$email = "fred\@bedrock.edu"; # Correct$email = 'fred@bedrock.edu'; # Another way to do that

$�VLQJOH�HOHPHQW�RI�DQ�DUUD\�ZLOO�EH�UHSODFHG�E\�LWV�YDOXH��MXVW�DV�\RX¦G�H[SHFW�

@fred = qw(hello dolly);$y = 2;$x = "This is $fred[1]'s place"; # "This is dolly's place"$x = "This is $fred[$y!1]'s place"; # same thing

1RWH�WKDW� WKH� LQGH[�H[SUHVVLRQ� LV�HYDOXDWHG�DV�DQ�RUGLQDU\�H[SUHVVLRQ��DV� LI� LW�ZHUHRXWVLGH�D�VWULQJ��,W�LV�QRW�YDULDEOH�LQWHUSRODWHG�ILUVW��,Q�RWKHU�ZRUGV��LI�$y�FRQWDLQV�WKHVWULQJ�"2*4"��ZH¦UH� VWLOO� WDONLQJ�DERXW�HOHPHQW����QRW� HOHPHQW����EHFDXVH�"2*4"� DV�DQXPEHU��WKH�YDOXH�RI�$y�XVHG�LQ�D�QXPHULF�H[SUHVVLRQ��LV�MXVW�SODLQ��� �,I�\RX�ZDQW�WRIROORZ�D�VLPSOH�VFDODU�YDULDEOH�ZLWK�D�OHIW�VTXDUH�EUDFNHW��\RX�QHHG�WR�GHOLPLW�WKH�VTXDUHEUDFNHW�VR�WKDW�LW�LVQ¦W�FRQVLGHUHG�SDUW�RI�DQ�DUUD\�UHIHUHQFH��DV�IROORZV�

@fred = qw(eating rocks is wrong);$fred = "right"; # we are trying to say "this is right[3]"print "this is $fred[3]\n"; # prints "wrong" using $fred[3]print "this is ${fred}[3]\n"; # prints "right" (protected by braces)print "this is $fred"."[3]\n"; # right again (different string)print "this is $fred\[3]\n"; # right again (backslash hides it)

The foreach Control Structure,W¦V�KDQG\�WR�EH�DEOH�WR�SURFHVV�DQ�HQWLUH�DUUD\�RU�OLVW��VR�3HUO�SURYLGHV�D�FRQWURO�VWUXFWXUHWR�GR�MXVW�WKDW��7KH�foreach�ORRS�VWHSV�WKURXJK�D�OLVW�RI�YDOXHV��H[HFXWLQJ�RQH�LWHUDWLRQ�WLPH�WKURXJK�WKH�ORRS��IRU�HDFK�YDOXH�

foreach $rock (qw/ bedrock slate lava /) { print "One rock is $rock.\n"; # Prints names of three rocks}

7KH�FRQWURO�YDULDEOH��$rock�LQ�WKDW�H[DPSOH��WDNHV�RQ�D�QHZ�YDOXH�IURP�WKH�OLVW�IRU�HDFKLWHUDWLRQ��7KH�ILUVW�WLPH�WKURXJK�WKH�ORRS��LW¦V�"bedrock"��WKH�WKLUG�WLPH��LW¦V�"lava"�

7KH�FRQWURO�YDULDEOH�LV�QRW�D�FRS\�RI�WKH�OLVW�HOHPHQW¢LW�DFWXDOO\�LV�WKH�OLVW�HOHPHQW�7KDW� LV�� LI� \RX�PRGLI\� WKH�FRQWURO�YDULDEOH� LQVLGH� WKH� ORRS��\RX¦OO�EH�PRGLI\LQJ� WKHHOHPHQW�LWVHOI��DV�VKRZQ�LQ�WKH�IROORZLQJ�FRGH�VQLSSHW��7KLV�LV�XVHIXO��DQG�VXSSRUWHG�EXW�LW�ZRXOG�VXUSULVH�\RX�LI�\RX�ZHUHQ¦W�H[SHFWLQJ�LW�

@rocks = qw/ bedrock slate lava /;foreach $rock (@rocks) { $rock = "\t$rock"; # put a tab in front of each element of @rocks $rock .= "\n"; # put a newline on the end of each}print "The rocks are:\n", @rocks; # Each one is indented, on its own line

2I�FRXUVH��LI�\RX¦YH�JRW�ZDUQLQJV�WXUQHG�RQ��3HUO�LV�OLNHO\�WR�UHPLQG�\RX�WKDW�"2*4"�LV�D�SUHWW\�IXQQ\�ORRNLQJQXPEHU�

The foreach Control Structure | 47

:KDW�LV�WKH�YDOXH�RI�WKH�FRQWURO�YDULDEOH�DIWHU�WKH�ORRS�KDV�ILQLVKHG"�,W¦V�WKH�VDPH�DV�LWZDV�EHIRUH�WKH�ORRS�VWDUWHG��3HUO�DXWRPDWLFDOO\�VDYHV�DQG�UHVWRUHV�WKH�YDOXH�RI�WKH�FRQ�WURO�YDULDEOH�RI�D�foreach�ORRS��:KLOH�WKH�ORRS�LV�UXQQLQJ��WKHUH¦V�QR�ZD\�WR�DFFHVV�RUDOWHU�WKDW�VDYHG�YDOXH��6R�DIWHU�WKH�ORRS�LV�GRQH��WKH�YDULDEOH�KDV�WKH�YDOXH�LW�KDG�EHIRUHWKH�ORRS��RU�undef�LI�LW�KDGQ¦W�KDG�D�YDOXH��7KDW�PHDQV�WKDW�LI�\RX�ZDQW�WR�QDPH�\RXUORRS�FRQWURO�YDULDEOH�$rock��\RX�GRQ¦W�KDYH�WR�ZRUU\�WKDW�PD\EH�\RX¦YH�DOUHDG\�XVHGWKDW�QDPH�IRU�DQRWKHU�YDULDEOH�

Perl’s Favorite Default: $_,I�\RX�RPLW�WKH�FRQWURO�YDULDEOH�IURP�WKH�EHJLQQLQJ�RI�WKH�foreach�ORRS��3HUO�XVHV�LWVIDYRULWH�GHIDXOW�YDULDEOH��$_��7KLV�LV��PRVWO\��MXVW�OLNH�DQ\�RWKHU�VFDODU�YDULDEOH��H[FHSWIRU�LWV�XQXVXDO�QDPH��)RU�H[DPSOH�

foreach (1..10) { # Uses $_ by default print "I can count to $_!\n";}

$OWKRXJK�WKLV�LVQ¦W�3HUO¦V�RQO\�GHIDXOW�E\�D�ORQJ�VKRW��LW¦V�3HUO¦V�PRVW�FRPPRQ�GHIDXOW�<RX¦OO�VHH�PDQ\�RWKHU�FDVHV�LQ�ZKLFK�3HUO�ZLOO�DXWRPDWLFDOO\�XVH�$_�ZKHQ�\RX�GRQ¦W�WHOOLW�WR�XVH�VRPH�RWKHU�YDULDEOH�RU�YDOXH��WKHUHE\�VDYLQJ�WKH�SURJUDPPHU�IURP�WKH�KHDY\ODERU�RI�KDYLQJ�WR�WKLQN�XS�DQG�W\SH�D�QHZ�YDULDEOH�QDPH��6R�DV�QRW�WR�NHHS�\RX�LQVXVSHQVH��RQH�RI�WKRVH�FDVHV�LV�print��ZKLFK�ZLOO�SULQW�$_�LI�JLYHQ�QR�RWKHU�DUJXPHQW�

$_ = "Yabba dabba doo\n";print; # prints $_ by default

The reverse Operator7KH�reverse�RSHUDWRU�WDNHV�D�OLVW�RI�YDOXHV��ZKLFK�PD\�FRPH�IURP�DQ�DUUD\��DQG�UHWXUQVWKH�OLVW�LQ�WKH�RSSRVLWH�RUGHU��6R�LI�\RX�ZHUH�GLVDSSRLQWHG�WKDW�WKH�UDQJH�RSHUDWRU��..�RQO\�FRXQWV�XSZDUG��WKLV�LV�WKH�ZD\�WR�IL[�LW�

@fred = 6..10;@barney = reverse(@fred); # gets 10, 9, 8, 7, 6@wilma = reverse 6..10; # gets the same thing, without the other array@fred = reverse @fred; # puts the result back into the original array

7KH�ODVW�OLQH�LV�QRWHZRUWK\�EHFDXVH�LW�XVHV�@fred�WZLFH��3HUO�DOZD\V�FDOFXODWHV�WKH�YDOXHEHLQJ�DVVLJQHG��RQ�WKH�ULJKW��EHIRUH�LW�EHJLQV�WKH�DFWXDO�DVVLJQPHQW�

5HPHPEHU�WKDW�reverse�UHWXUQV�WKH�UHYHUVHG�OLVW��LW�GRHVQ¦W�DIIHFW�LWV�DUJXPHQWV��,I�WKHUHWXUQ�YDOXH�LVQ¦W�DVVLJQHG�DQ\ZKHUH��LW¦V�XVHOHVV�

reverse @fred; # WRONG - doesn't change @fred@fred = reverse @fred; # that's better

48 | Chapter 3:ಗLists and Arrays

The sort Operator7KH�sort�RSHUDWRU�WDNHV�D�OLVW�RI�YDOXHV��ZKLFK�PD\�FRPH�IURP�DQ�DUUD\��DQG�VRUWV�WKHPLQ�WKH�LQWHUQDO�FKDUDFWHU�RUGHULQJ��)RU�$6&,,�VWULQJV��WKDW�ZRXOG�EH�$6&,,EHWLFDO�RUGHU�2I�FRXUVH��$6&,,�LV�D�VWUDQJH�SODFH�ZKHUH�DOO�RI�WKH�FDSLWDO�OHWWHUV�FRPH�EHIRUH�DOO�RI�WKHORZHUFDVH� OHWWHUV��ZKHUH� WKH�QXPEHUV� FRPH�EHIRUH� WKH� OHWWHUV�� DQG� WKH�SXQFWXDWLRQPDUNV¢ZHOO��WKRVH�DUH�KHUH��WKHUH��DQG�HYHU\ZKHUH��%XW�VRUWLQJ�LQ�$6&,,�RUGHU�LV�MXVWWKH�GHIDXOW�EHKDYLRU��\RX¦OO�VHH�LQ�&KDSWHU����KRZ�WR�VRUW�LQ�ZKDWHYHU�RUGHU�\RX¦G�OLNH��

@rocks = qw/ bedrock slate rubble granite /;@sorted = sort(@rocks); # gets bedrock, granite, rubble, slate@back = reverse sort @rocks; # these go from slate to bedrock@rocks = sort @rocks; # puts sorted result back into @rocks@numbers = sort 97..102; # gets 100, 101, 102, 97, 98, 99

$V�\RX�FDQ�VHH�IURP�WKDW�ODVW�H[DPSOH��VRUWLQJ�QXPEHUV�DV�LI�WKH\�ZHUH�VWULQJV�PD\�QRWJLYH�XVHIXO�UHVXOWV��%XW��RI�FRXUVH��DQ\�VWULQJ�WKDW�VWDUWV�ZLWK�1�KDV�WR�VRUW�EHIRUH�DQ\VWULQJ�WKDW�VWDUWV�ZLWK�9��DFFRUGLQJ�WR�WKH�GHIDXOW�VRUWLQJ�UXOHV��$QG�OLNH�ZKDW�KDSSHQHGZLWK�reverse��WKH�DUJXPHQWV�WKHPVHOYHV�DUHQ¦W�DIIHFWHG��,I�\RX�ZDQW�WR�VRUW�DQ�DUUD\�\RX�PXVW�VWRUH�WKH�UHVXOW�EDFN�LQWR�WKDW�DUUD\�

sort @rocks; # WRONG, doesn't modify @rocks@rocks = sort @rocks; # Now the rock collection is in order

Scalar and List Context7KLV�LV�WKH�PRVW�LPSRUWDQW�VHFWLRQ�LQ�WKLV�FKDSWHU��,Q�IDFW��LW¦V�WKH�PRVW�LPSRUWDQW�VHFWLRQLQ�WKH�HQWLUH�ERRN��,W�ZRXOGQ¦W�EH�DQ�H[DJJHUDWLRQ�WR�VD\�WKDW�\RXU�HQWLUH�FDUHHU�LQ�XVLQJ3HUO�ZLOO�GHSHQG�XSRQ�XQGHUVWDQGLQJ�WKLV�VHFWLRQ��6R�LI�\RX¦YH�JRWWHQ�DZD\�ZLWK�VNLP�PLQJ�WKH�WH[W�XS�WR�WKLV�SRLQW��WKLV�LV�ZKHUH�\RX�VKRXOG�UHDOO\�SD\�DWWHQWLRQ�

7KDW¦V�QRW�WR�VD\�WKDW�WKLV�VHFWLRQ�LV�LQ�DQ\�ZD\�GLIILFXOW�WR�XQGHUVWDQG��,W¦V�DFWXDOO\�DVLPSOH�LGHD��D�JLYHQ�H[SUHVVLRQ�PD\�PHDQ�GLIIHUHQW�WKLQJV�GHSHQGLQJ�XSRQ�ZKHUH�LWDSSHDUV��7KLV�LV�QRWKLQJ�QHZ�WR�\RX��LW�KDSSHQV�DOO�WKH�WLPH�LQ�QDWXUDO�ODQJXDJHV��)RUH[DPSOH��LQ�(QJOLVK� �VXSSRVH�VRPHRQH�DVNHG�\RX�ZKDW�WKH�ZRUG�£UHDG¤��PHDQV��,W�KDVGLIIHUHQW�PHDQLQJV�GHSHQGLQJ�RQ�KRZ�LW¦V�XVHG��<RX�FDQ¦W�LGHQWLI\�WKH�PHDQLQJ�XQWLO\RX�NQRZ�WKH�FRQWH[W�

,I�\RX�DUHQ¦W�D�QDWLYH�VSHDNHU�RI�(QJOLVK��WKLV�DQDORJ\�PD\�QRW�EH�REYLRXV�WR�\RX��%XW�FRQWH[W�VHQVLWLYLW\KDSSHQV�LQ�HYHU\�VSRNHQ�ODQJXDJH��VR�\RX�PD\�EH�DEOH�WR�WKLQN�RI�DQ�H[DPSOH�LQ�\RXU�RZQ�ODQJXDJH�

� 2U�PD\EH�WKH\�ZHUH�DVNLQJ�ZKDW�WKH�ZRUG�£UHG¤�PHDQV��LI�WKH\�ZHUH�VSHDNLQJ�UDWKHU�WKDQ�ZULWLQJ�D�ERRN�,W¦V� DPELJXRXV� HLWKHU� ZD\�� $V� 'RXJODV� +RIVWDGWHU� VDLG�� QR� ODQJXDJH� FDQ� H[SUHVV� HYHU\� WKRXJKWXQDPELJXRXVO\��HVSHFLDOO\�WKLV�RQH�

Scalar and List Context | 49

7KH�FRQWH[W�UHIHUV�WR�ZKHUH�DQ�H[SUHVVLRQ�LV�IRXQG��$V�3HUO�LV�SDUVLQJ�\RXU�H[SUHVVLRQV�LW�DOZD\V�H[SHFWV�HLWKHU�D�VFDODU�YDOXH�RU�D�OLVW�YDOXH� �:KDW�3HUO�H[SHFWV�LV�FDOOHG�WKHFRQWH[W�RI�WKH�H[SUHVVLRQ��

42 + something # The something must be a scalarsort something # The something must be a list

(YHQ�LI�VRPHWKLQJ�LV�WKH�H[DFW�VDPH�VHTXHQFH�RI�FKDUDFWHUV��LQ�RQH�FDVH�LW�PD\�JLYH�DVLQJOH��VFDODU�YDOXH��ZKLOH�LQ�WKH�RWKHU��LW�PD\�JLYH�D�OLVW�®�([SUHVVLRQV�LQ�3HUO�DOZD\VUHWXUQ�WKH�DSSURSULDWH�YDOXH�IRU�WKHLU�FRQWH[W��)RU�H[DPSOH��WDNH�WKH�£QDPH¤�RI�DQDUUD\��,Q�D�OLVW�FRQWH[W��LW�JLYHV�WKH�OLVW�RI�HOHPHQWV��%XW�LQ�D�VFDODU�FRQWH[W��LW�UHWXUQV�WKHQXPEHU�RI�HOHPHQWV�LQ�WKH�DUUD\�

@people = qw( fred barney betty );@sorted = sort @people; # list context: barney, betty, fred$number = 42 + @people; # scalar context: 42 + 3 gives 45

(YHQ�RUGLQDU\�DVVLJQPHQW��WR�D�VFDODU�RU�D�OLVW��FDXVHV�GLIIHUHQW�FRQWH[WV�

@list = @people; # a list of three people$n = @people; # the number 3

%XW�SOHDVH�GRQ¦W�MXPS�WR�WKH�FRQFOXVLRQ�WKDW�VFDODU�FRQWH[W�DOZD\V�JLYHV�WKH�QXPEHURI�HOHPHQWV�WKDW�ZRXOG�KDYH�EHHQ�UHWXUQHG�LQ�OLVW�FRQWH[W��0RVW�OLVW�SURGXFLQJ�H[SUHV�VLRQV��UHWXUQ�VRPHWKLQJ�PXFK�PRUH�LQWHUHVWLQJ�WKDQ�WKDW�

Using List-Producing Expressions in Scalar Context7KHUH�DUH�PDQ\�H[SUHVVLRQV�WKDW�ZRXOG�W\SLFDOO\�EH�XVHG�WR�SURGXFH�D�OLVW��,I�\RX�XVHRQH�LQ�D�VFDODU�FRQWH[W��ZKDW�GR�\RX�JHW"�6HH�ZKDW�WKH�DXWKRU�RI�WKDW�RSHUDWLRQ�VD\VDERXW�LW��8VXDOO\��WKDW�SHUVRQ�LV�/DUU\��DQG�XVXDOO\�WKH�GRFXPHQWDWLRQ�JLYHV�WKH�ZKROHVWRU\��,Q�IDFW��D�ELJ�SDUW�RI�OHDUQLQJ�3HUO�LV�DFWXDOO\�OHDUQLQJ�KRZ�/DUU\�WKLQNV� �7KHUH�IRUH��RQFH�\RX�FDQ�WKLQN�OLNH�/DUU\�GRHV��\RX�NQRZ�ZKDW�3HUO�VKRXOG�GR��%XW�ZKLOH\RX¦UH�OHDUQLQJ��\RX¦OO�SUREDEO\�QHHG�WR�ORRN�LQWR�WKH�GRFXPHQWDWLRQ�

8QOHVV��RI�FRXUVH��3HUO�LV�H[SHFWLQJ�VRPHWKLQJ�HOVH�HQWLUHO\��7KHUH�DUH�RWKHU�FRQWH[WV�WKDW�DUHQ¦W�FRYHUHG�KHUH�,Q�IDFW��QRERG\�NQRZV�KRZ�PDQ\�FRQWH[WV�3HUO�XVHV��WKH�ELJJHVW�EUDLQV�LQ�DOO�RI�3HUO�KDYHQ¦W�DJUHHG�RQ�DQDQVZHU�WR�WKDW�\HW�

� 7KLV�LV�QR�GLIIHUHQW�WKDQ�ZKDW�\RX¦UH�XVHG�WR�LQ�KXPDQ�ODQJXDJHV��,I�,�PDNH�D�JUDPPDWLFDO�PLVWDNH��\RX�QRWLFHLW�ULJKW�DZD\�EHFDXVH�\RX�H[SHFW�FHUWDLQ�ZRUGV�LQ�SODFHV�FHUWDLQ��(YHQWXDOO\��\RX¦OO�UHDG�3HUO�WKLV�ZD\��WRR�EXW�DW�ILUVW�\RX�KDYH�WR�WKLQN�DERXW�LW�

® 7KH�OLVW�PD\�EH�MXVW�RQH�HOHPHQW�ORQJ��RI�FRXUVH��,W�FRXOG�DOVR�EH�HPSW\��RU�LW�FRXOG�KDYH�DQ\�QXPEHU�RIHOHPHQWV�

:HOO��WKH�WUXH�QDPH�RI�WKH�DUUD\�@people�LV�MXVW�people��7KH�@�VLJQ�LV�MXVW�D�TXDOLILHU�

� %XW�ZLWK�UHJDUG�WR�WKH�SRLQW�RI�WKLV�VHFWLRQ��WKHUH¦V�QR�GLIIHUHQFH�EHWZHHQ�D�£OLVW�SURGXFLQJ¤�H[SUHVVLRQ�DQGD�£VFDODU�SURGXFLQJ¤�RQH��DQ\�H[SUHVVLRQ�FDQ�SURGXFH�D�OLVW�RU�D�VFDODU��GHSHQGLQJ�XSRQ�FRQWH[W��6R�ZKHQZH�VD\�£OLVW�SURGXFLQJ�H[SUHVVLRQV�¤�ZH�PHDQ�H[SUHVVLRQV�WKDW�DUH�W\SLFDOO\�XVHG�LQ�D�OLVW�FRQWH[W�DQG�WKHUHIRUHPLJKW�VXUSULVH�\RX�ZKHQ�WKH\¦UH�XVHG�XQH[SHFWHGO\�LQ�D�VFDODU�FRQWH[W��OLNH�reverse�RU�@fred��

7KLV�LV�RQO\�IDLU��VLQFH�ZKLOH�ZULWLQJ�3HUO�KH�WULHG�WR�WKLQN�OLNH�\RX�GR�WR�SUHGLFW�ZKDW�\RX�ZRXOG�ZDQW�

50 | Chapter 3:ಗLists and Arrays

6RPH�H[SUHVVLRQV�GRQ¦W�KDYH�D�VFDODU�FRQWH[W�YDOXH�DW�DOO��)RU�H[DPSOH��ZKDW�VKRXOGsort�UHWXUQ�LQ�D�VFDODU�FRQWH[W"�<RX�ZRXOGQ¦W�QHHG�WR�VRUW�D�OLVW�WR�FRXQW�LWV�HOHPHQWV�VR�XQWLO�VRPHRQH�LPSOHPHQWV�VRPHWKLQJ�HOVH��sort�LQ�D�VFDODU�FRQWH[W�DOZD\V�UHWXUQVundef�

$QRWKHU�H[DPSOH�LV�reverse��,Q�D�OLVW�FRQWH[W��LW�JLYHV�D�UHYHUVHG�OLVW��,Q�D�VFDODU�FRQWH[W�LW�UHWXUQV�D�UHYHUVHG�VWULQJ��RU�UHYHUVLQJ�WKH�UHVXOW�RI�FRQFDWHQDWLQJ�DOO�WKH�VWULQJV�RI�DOLVW��LI�JLYHQ�RQH��

@backwards = reverse qw/ yabba dabba doo /; # gives doo, dabba, yabba$backwards = reverse qw/ yabba dabba doo /; # gives oodabbadabbay

$W�ILUVW��LW¦V�QRW�DOZD\V�REYLRXV�ZKHWKHU�DQ�H[SUHVVLRQ�LV�EHLQJ�XVHG�LQ�D�VFDODU�RU�D�OLVWFRQWH[W��%XW��WUXVW�XV��LW�ZLOO�EHFRPH�VHFRQG�QDWXUH�IRU�\RX�HYHQWXDOO\�

+HUH�DUH�VRPH�FRPPRQ�FRQWH[WV�WR�VWDUW�\RX�RII�

$fred = something; # scalar context@pebbles = something; # list context($wilma, $betty) = something; # list context($dino) = something; # still list context!

'RQ¦W�EH�IRROHG�E\�WKH�RQH�HOHPHQW�OLVW��WKDW�ODVW�RQH�LV�D�OLVW�FRQWH[W��QRW�D�VFDODU�RQH�7KH�SDUHQWKHVHV�DUH�VLJQLILFDQW�KHUH��PDNLQJ�WKH�IRXUWK�RI�WKRVH�GLIIHUHQW�WKDQ�WKH�ILUVW�,I�\RX¦UH�DVVLJQLQJ�WR�D�OLVW��QR�PDWWHU�WKH�QXPEHU�RI�HOHPHQWV���LW¦V�D�OLVW�FRQWH[W��,I\RX¦UH�DVVLJQLQJ�WR�DQ�DUUD\��LW¦V�D�OLVW�FRQWH[W�

+HUH�DUH�VRPH�RWKHU�H[SUHVVLRQV�\RX¦YH�VHHQ��DQG�WKH�FRQWH[WV�WKH\�SURYLGH��)LUVW��VRPHWKDW�SURYLGH�VFDODU�FRQWH[W�WR�VRPHWKLQJ�

$fred = something;$fred[3] = something;123 + somethingsomething + 654if (something) { ... }while (something) { ... }$fred[something] = something;

$QG�KHUH�DUH�VRPH�WKDW�SURYLGH�D�OLVW�FRQWH[W�

@fred = something;($fred, $barney) = something;($fred) = something;push @fred, something;foreach $fred (something) { ... }sort somethingreverse somethingprint something

Scalar and List Context | 51

Using Scalar-Producing Expressions in List Context*RLQJ�WKLV�GLUHFWLRQ�LV�VWUDLJKWIRUZDUG��LI�DQ�H[SUHVVLRQ�GRHVQ¦W�QRUPDOO\�KDYH�D�OLVWYDOXH��WKH�VFDODU�YDOXH�LV�DXWRPDWLFDOO\�SURPRWHG�WR�PDNH�D�RQH�HOHPHQW�OLVW�

@fred = 6 * 7; # gets the one-element list (42)@barney = "hello" . ' ' . "world";

:HOO��WKHUH¦V�RQH�SRVVLEOH�FDWFK�

@wilma = undef; # OOPS! Gets the one-element list (undef) # which is not the same as this:@betty = ( ); # A correct way to empty an array

6LQFH�undef�LV�D�VFDODU�YDOXH��DVVLJQLQJ�undef�WR�DQ�DUUD\�GRHVQ¦W�FOHDU�WKH�DUUD\��7KHEHWWHU�ZD\�WR�GR�WKDW�LV�WR�DVVLJQ�DQ�HPSW\�OLVW�

Forcing Scalar Context2Q�RFFDVLRQ��\RX�PD\�QHHG�WR�IRUFH�VFDODU�FRQWH[W�ZKHUH�3HUO�LV�H[SHFWLQJ�D�OLVW��,Q�WKDWFDVH��\RX�FDQ�XVH�WKH�IDNH�IXQFWLRQ�scalar��,W¦V�QRW�D�WUXH�IXQFWLRQ�EHFDXVH�LW�MXVW�WHOOV3HUO�WR�SURYLGH�D�VFDODU�FRQWH[W�

@rocks = qw( talc quartz jade obsidian );print "How many rocks do you have?\n";print "I have ", @rocks, " rocks!\n"; # WRONG, prints names of rocksprint "I have ", scalar @rocks, " rocks!\n"; # Correct, gives a number

2GGO\�HQRXJK��WKHUH¦V�QR�FRUUHVSRQGLQJ�IXQFWLRQ�WR�IRUFH�OLVW�FRQWH[W��,W�WXUQV�RXW�\RXQHYHU�QHHG�LW��7UXVW�XV�RQ�WKLV��WRR�

<STDIN> in List Context2QH�SUHYLRXVO\�VHHQ�RSHUDWRU�WKDW�UHWXUQV�D�GLIIHUHQW�YDOXH�LQ�DQ�DUUD\�FRQWH[W�LV�WKHOLQH�LQSXW�RSHUDWRU��<STDIN>��$V�GHVFULEHG�HDUOLHU��<STDIN>�UHWXUQV�WKH�QH[W�OLQH�RI�LQSXWLQ�D�VFDODU�FRQWH[W��1RZ��LQ�OLVW�FRQWH[W��WKLV�RSHUDWRU�UHWXUQV�DOO�RI�WKH�UHPDLQLQJ�OLQHVXS�WR�WKH�HQG�RI�ILOH��(DFK�OLQH�LV�UHWXUQHG�DV�D�VHSDUDWH�HOHPHQW�RI�WKH�OLVW��)RU�H[DPSOH�

@lines = <STDIN>; # read standard input in list context

:KHQ�WKH�LQSXW�LV�FRPLQJ�IURP�D�ILOH��WKLV�ZLOO�UHDG�WKH�UHVW�RI�WKH�ILOH��%XW�KRZ�FDQWKHUH�EH�DQ�HQG�RI�ILOH�ZKHQ�WKH�LQSXW�FRPHV�IURP�WKH�NH\ERDUG"�2Q�8QL[�DQG�VLPLODUV\VWHPV��LQFOXGLQJ�/LQX[�DQG�0DF�26�;��\RX¦OO�QRUPDOO\�W\SH�D�&RQWURO�'��WR�LQGLFDWHWR�WKH�V\VWHP�WKDW�WKHUH¦V�QR�PRUH�LQSXW��WKH�VSHFLDO�FKDUDFWHU�LWVHOI�LV�QHYHU�VHHQ�E\

:HOO�� LQ�PRVW�UHDO�ZRUOG�DOJRULWKPV�� LI� WKH�YDULDEOH� LV�GHFODUHG�LQ�WKH�SURSHU�VFRSH��\RX�ZLOO�QRW�QHHG�WRH[SOLFLWO\�HPSW\�LW��6R�WKLV�W\SH�RI�DVVLJQPHQW�LV�UDUH�LQ�ZHOO�ZULWWHQ�3HUO�SURJUDPV��<RX¦OO�OHDUQ�DERXW�VFRSLQJLQ�WKH�QH[W�FKDSWHU�

� 7KLV�LV�PHUHO\�WKH�GHIDXOW��LW�FDQ�EH�FKDQJHG�E\�WKH�stty�FRPPDQG��%XW�LW¦V�SUHWW\�GHSHQGDEOH¢ZH¦YH�QHYHUVHHQ�D�8QL[�V\VWHP�ZKHUH�D�GLIIHUHQW�FKDUDFWHU�ZDV�XVHG�WR�PHDQ�HQG�RI�ILOH�IURP�WKH�NH\ERDUG�

52 | Chapter 3:ಗLists and Arrays

3HUO� �HYHQ�WKRXJK�LW�PD\�EH�HFKRHG�WR�WKH�VFUHHQ��2Q�'26�:LQGRZV�V\VWHPV��XVH&RQWURO�=�LQVWHDG���<RX¦OO�QHHG�WR�FKHFN�WKH�GRFXPHQWDWLRQ�IRU�\RXU�V\VWHP�RU�DVN\RXU�ORFDO�H[SHUW�LI�LW¦V�GLIIHUHQW�IURP�WKHVH�

,I�WKH�SHUVRQ�UXQQLQJ�WKH�SURJUDP�W\SHV�WKUHH�OLQHV��WKHQ�SUHVVHV�WKH�SURSHU�NH\V�QHHGHGWR�LQGLFDWH�HQG�RI�ILOH��WKH�DUUD\�HQGV�XS�ZLWK�WKUHH�HOHPHQWV��(DFK�HOHPHQW�ZLOO�EH�DVWULQJ� WKDW� HQGV� LQ� D� QHZOLQH�� FRUUHVSRQGLQJ� WR� WKH� WKUHH� QHZOLQH�WHUPLQDWHG� OLQHVHQWHUHG�

:RXOGQ¦W�LW�EH�QLFH�LI��KDYLQJ�UHDG�WKRVH�OLQHV��\RX�FRXOG�chomp�WKH�QHZOLQHV�DOO�DW�RQFH",W�WXUQV�RXW�WKDW�LI�\RX�JLYH�chomp�DQ�DUUD\�KROGLQJ�D�OLVW�RI� OLQHV�� LW�ZLOO�UHPRYH�WKHQHZOLQHV�IURP�HDFK�LWHP�LQ�WKH�OLVW��)RU�H[DPSOH�

@lines = <STDIN>; # Read all the lineschomp(@lines); # discard all the newline characters

%XW�WKH�PRUH�FRPPRQ�ZD\�WR�ZULWH�WKDW�LV�ZLWK�FRGH�VLPLODU�WR�ZKDW�ZH�XVHG�HDUOLHU�

chomp(@lines = <STDIN>); # Read the lines, not the newlines

$OWKRXJK�\RX¦UH�ZHOFRPH�WR�ZULWH�\RXU�FRGH�HLWKHU�ZD\�LQ�WKH�SULYDF\�RI�\RXU�RZQFXELFOH��PRVW�3HUO�SURJUDPPHUV�ZLOO�H[SHFW�WKH�VHFRQG��PRUH�FRPSDFW��QRWDWLRQ�

,W�PD\�EH�REYLRXV�WR�\RX��EXW�LW¦V�QRW�REYLRXV�WR�HYHU\RQH��WKDW�RQFH�WKHVH�OLQHV�RI�LQSXWKDYH�EHHQ�UHDG��WKH\�FDQ¦W�EH�UH�UHDG�®�2QFH�\RX¦YH�UHDFKHG�HQG�RI�ILOH��WKHUH¦V�QR�PRUHLQSXW�RXW�WKHUH�WR�UHDG�

$QG�ZKDW�KDSSHQV�LI�WKH�LQSXW�LV�FRPLQJ�IURP�D�����0%�ORJILOH"�7KH�OLQH�LQSXW�RSHUDWRUUHDGV�DOO�RI�WKH�OLQHV��JREEOLQJ�XS�ORWV�RI�PHPRU\��3HUO�WULHV�QRW�WR�OLPLW�\RX�LQ�ZKDW\RX�FDQ�GR��EXW�WKH�RWKHU�XVHUV�RI�\RXU�V\VWHP��QRW�WR�PHQWLRQ�\RXU�V\VWHP�DGPLQLV�WUDWRU��DUH�OLNHO\�WR�REMHFW��,I�WKH�LQSXW�GDWD�LV�ODUJH��\RX�VKRXOG�JHQHUDOO\�ILQG�D�ZD\�WRGHDO�ZLWK�LW�ZLWKRXW�UHDGLQJ�LW�DOO�LQWR�PHPRU\�DW�RQFH�

,W¦V�WKH�26�WKDW�£VHHV¤�WKH�&RQWURO�NH\�DQG�UHSRUWV�£HQG�RI�ILOH¤�WR�WKH�DSSOLFDWLRQ�

� 7KHUH¦V�D�EXJ�DIIHFWLQJ�VRPH�SRUWV�RI�3HUO�IRU�'26�:LQGRZV�ZKHUH�WKH�ILUVW�OLQH�RI�RXWSXW�WR�WKH�WHUPLQDOIROORZLQJ�WKH�XVH�RI�&RQWURO�=�LV�REVFXUHG��2Q�WKHVH�V\VWHPV��\RX�FDQ�ZRUN�DURXQG�WKLV�SUREOHP�E\�VLPSO\SULQWLQJ�D�EODQN�OLQH��"\n")�DIWHU�UHDGLQJ�WKH�LQSXW�

® :HOO��\HV��LI�WKH�LQSXW�LV�IURP�D�VRXUFH�XSRQ�ZKLFK�\RX�FDQ�seek��\RX¦OO�EH�DEOH�WR�JR�EDFN�DQG�UHDG�DJDLQ�%XW�WKDW¦V�QRW�ZKDW�ZH¦UH�WDONLQJ�DERXW�KHUH�

7\SLFDOO\��WKDW¦V�PXFK�PRUH�PHPRU\�WKDQ�WKH�VL]H�RI�WKH�ILOH��WRR��7KDW�LV��D�����0%�ILOH�ZLOO�W\SLFDOO\�WDNHXS�DW�OHDVW�D�IXOO�JLJDE\WH�RI�PHPRU\�ZKHQ�UHDG�LQWR�DQ�DUUD\��7KLV�LV�EHFDXVH�3HUO�ZLOO�JHQHUDOO\�ZDVWH�PHPRU\WR�VDYH�WLPH��7KLV�LV�D�JRRG�WUDGHRII��LI�\RX¦UH�VKRUW�RI�PHPRU\��\RX�FDQ�EX\�PRUH��LI�\RX¦UH�VKRUW�RQ�WLPH�\RX¦UH�KRVHG�

<STDIN> in List Context | 53

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >�@�:ULWH�D�SURJUDP�WKDW�UHDGV�D�OLVW�RI�VWULQJV�RQ�VHSDUDWH�OLQHV�XQWLO�HQG�RI�LQSXWDQG�SULQWV�RXW�WKH�OLVW�LQ�UHYHUVH�RUGHU��,I�WKH�LQSXW�FRPHV�IURP�WKH�NH\ERDUG��\RX¦OOSUREDEO\�QHHG�WR�VLJQDO�WKH�HQG�RI�WKH�LQSXW�E\�SUHVVLQJ�&RQWURO�'�RQ�8QL[��RU&RQWURO�=�RQ�:LQGRZV�

�� >��@�:ULWH�D�SURJUDP�WKDW�UHDGV�D�OLVW�RI�QXPEHUV��RQ�VHSDUDWH�OLQHV��XQWLO�HQG�RI�LQSXW�DQG�WKHQ�SULQWV�IRU�HDFK�QXPEHU�WKH�FRUUHVSRQGLQJ�SHUVRQ¦V�QDPH�IURP�WKHOLVW�VKRZQ�EHORZ���+DUGFRGH�WKLV�OLVW�RI�QDPHV�LQWR�\RXU�SURJUDP��7KDW�LV��LW�VKRXOGDSSHDU�LQ�\RXU�SURJUDP¦V�VRXUFH�FRGH���)RU�H[DPSOH��LI�WKH�LQSXW�QXPEHUV�ZHUH1��2��4��DQG�2��WKH�RXWSXW�QDPHV�ZRXOG�EH�fred��betty��dino��DQG�betty�

fred betty barney dino wilma pebbles bamm-bamm

�� >�@�:ULWH�D�SURJUDP�WKDW�UHDGV�D�OLVW�RI�VWULQJV��RQ�VHSDUDWH�OLQHV��XQWLO�HQG�RI�LQSXW�7KHQ� LW� VKRXOG�SULQW� WKH�VWULQJV� LQ�$6&,,EHWLFDO�RUGHU��7KDW� LV�� LI�\RX�HQWHU� WKHVWULQJV� fred�� barney�� wilma�� betty�� WKH� RXWSXW� VKRXOG� VKRZ� barney betty fredwilma��$UH�DOO�RI�WKH�VWULQJV�RQ�RQH�OLQH�LQ�WKH�RXWSXW�RU�RQ�VHSDUDWH�OLQHV"�&RXOG\RX�PDNH�WKH�RXWSXW�DSSHDU�LQ�HLWKHU�VW\OH"

54 | Chapter 3:ಗLists and Arrays

CHAPTER 4

Subroutines

<RX¦YH�DOUHDG\�VHHQ�DQG�XVHG�VRPH�RI�WKH�EXLOW�LQ�V\VWHP�IXQFWLRQV��VXFK�DV�chomp�reverse��print�� DQG�VR�RQ��%XW��DV�RWKHU� ODQJXDJHV�GR��3HUO�KDV� WKH�DELOLW\� WR�PDNHVXEURXWLQHV��ZKLFK�DUH�XVHU�GHILQHG�IXQFWLRQV� �7KHVH�OHW�XV�UHF\FOH�RQH�FKXQN�RI�FRGHPDQ\�WLPHV�LQ�RQH�SURJUDP���7KH�QDPH�RI�D�VXEURXWLQH�LV�DQRWKHU�3HUO�LGHQWLILHU��OHWWHUV�GLJLWV�� DQG� XQGHUVFRUHV�� EXW� LW� FDQ¦W� VWDUW� ZLWK� D� GLJLW�� ZLWK� D� VRPHWLPHV�RSWLRQDODPSHUVDQG��&��LQ�IURQW��7KHUH¦V�D�UXOH�DERXW�ZKHQ�\RX�FDQ�RPLW�WKH�DPSHUVDQG�DQGZKHQ�\RX�FDQQRW��\RX¦OO�VHH�WKDW�UXOH�E\�WKH�HQG�RI�WKH�FKDSWHU��)RU�QRZ��ZH¦OO�MXVW�XVHLW�HYHU\�WLPH�WKDW�LW¦V�QRW�IRUELGGHQ��ZKLFK�LV�DOZD\V�D�VDIH�UXOH��:H¦OO�WHOO�\RX�HYHU\SODFH�ZKHUH�LW¦V�IRUELGGHQ��RI�FRXUVH�

7KH�VXEURXWLQH�QDPH�FRPHV�IURP�D�VHSDUDWH�QDPHVSDFH��VR�3HUO�ZRQ¦W�EH�FRQIXVHG�LI\RX�KDYH�D�VXEURXWLQH�FDOOHG�&fred�DQG�D�VFDODU�FDOOHG�$fred�LQ�WKH�VDPH�SURJUDP¢DOWKRXJK�WKHUH¦V�QR�UHDVRQ�WR�GR�WKDW�XQGHU�QRUPDO�FLUFXPVWDQFHV�

Defining a Subroutine7R�GHILQH� \RXU� RZQ� VXEURXWLQH�� XVH� WKH� NH\ZRUG� sub�� WKH� QDPH�RI� WKH� VXEURXWLQH�ZLWKRXW�WKH�DPSHUVDQG���WKHQ�WKH�LQGHQWHG�EORFN�RI�FRGH��LQ�FXUO\�EUDFHV��®�ZKLFKPDNHV�XS�WKH�ERG\�RI�WKH�VXEURXWLQH��VRPHWKLQJ�OLNH�WKLV�

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

,Q�3HUO��ZH�GRQ¦W�JHQHUDOO\�PDNH�WKH�GLVWLQFWLRQ�WKDW�3DVFDO�SURJUDPPHUV�DUH�XVHG�WR��EHWZHHQ�IXQFWLRQV�ZKLFK� UHWXUQ� D� YDOXH�� DQG� SURFHGXUHV�� ZKLFK� GRQ¦W�� %XW� D� VXEURXWLQH� LV� DOZD\V� XVHU�GHILQHG�� ZKLOH� DIXQFWLRQ�PD\�RU�PD\�QRW�EH��7KDW�LV��WKH�ZRUG�IXQFWLRQ�PD\�EH�XVHG�DV�D�V\QRQ\P�IRU�VXEURXWLQH��RU�LW�PD\PHDQ�RQH�RI�3HUO¦V�EXLOW�LQ�IXQFWLRQV��7KDW¦V�ZK\�WKLV�FKDSWHU�LV�WLWOHG�6XEURXWLQHV��EHFDXVH�LW¦V�DERXW�WKH�RQHV\RX�FDQ�GHILQH��QRW�WKH�EXLOW�LQV��0RVWO\�

� 7KH�FRGH�H[DPSOHV�XVHG�LQ�WKLV�ERRN�DUH�UHF\FOHG�IURP�DW�OHDVW�����SRVW�FRQVXPHU�SURJUDPPLQJ�DQG�DUH�DWOHDVW�����UHF\FODEOH�LQWR�\RXU�SURJUDPV�ZKHQ�SURSHUO\�GHFRPSRVHG�

® 2ND\��SXULVWV��ZH�DGPLW�LW��WKH�FXUO\�EUDFHV�DUH�SDUW�RI�WKH�EORFN��SURSHUO\�VSHDNLQJ��$QG�3HUO�GRHVQ¦W�UHTXLUHWKH�LQGHQWDWLRQ�RI�WKH�EORFN¢EXW�\RXU�PDLQWHQDQFH�SURJUDPPHU�ZLOO��6R�SOHDVH�EH�VW\OLVK�

55

6XEURXWLQH�GHILQLWLRQV�FDQ�EH�DQ\ZKHUH�LQ�\RXU�SURJUDP�WH[W��EXW�SURJUDPPHUV�ZKRFRPH�IURP�D�EDFNJURXQG�RI�ODQJXDJHV�OLNH�&�RU�3DVFDO�OLNH�WR�SXW�WKHP�DW�WKH�VWDUW�RIWKH�ILOH��2WKHUV�PD\�SUHIHU�WR�SXW�WKHP�DW�WKH�HQG�RI�WKH�ILOH�VR�WKDW�WKH�PDLQ�SDUW�RI�WKHSURJUDP�DSSHDUV�DW�WKH�EHJLQQLQJ��,W¦V�XS�WR�\RX��,Q�DQ\�FDVH��\RX�GRQ¦W�QRUPDOO\�QHHGDQ\� NLQG� RI� IRUZDUG� GHFODUDWLRQ� � 6XEURXWLQH� GHILQLWLRQV� DUH� JOREDO�� ZLWKRXW� VRPHSRZHUIXO�WULFNLQHVV��WKHUH�DUH�QR�SULYDWH�VXEURXWLQHV���,I�\RX�KDYH�WZR�VXEURXWLQH�GHI�LQLWLRQV�ZLWK�WKH�VDPH�QDPH��WKH�ODWHU�RQH�RYHUZULWHV�WKH�HDUOLHU�RQH�®�7KDW¦V�JHQHUDOO\FRQVLGHUHG�EDG�IRUP��RU�WKH�VLJQ�RI�D�FRQIXVHG�PDLQWHQDQFH�SURJUDPPHU�

$V�\RX�PD\�KDYH�QRWLFHG�LQ�WKH�SUHYLRXV�H[DPSOH��\RX�PD\�XVH�DQ\�JOREDO�YDULDEOHVZLWKLQ�WKH�VXEURXWLQH�ERG\��,Q�IDFW��DOO�RI�WKH�YDULDEOHV�\RX¦YH�VHHQ�VR�IDU�DUH�JOREDOV�WKDW�LV��WKH\�DUH�DFFHVVLEOH�IURP�HYHU\�SDUW�RI�\RXU�SURJUDP��7KLV�KRUULILHV�OLQJXLVWLFSXULVWV��EXW�WKH�3HUO�GHYHORSPHQW�WHDP�IRUPHG�DQ�DQJU\�PRE�ZLWK�WRUFKHV�DQG�UDQ�WKHPRXW�RI�WRZQ�\HDUV�DJR��<RX¦OO�VHH�KRZ�WR�PDNH�SULYDWH�YDULDEOHV�LQ�£3ULYDWH�9DULDEOHVLQ�6XEURXWLQHV�¤�ODWHU�LQ�WKLV�FKDSWHU�

Invoking a Subroutine,QYRNH�D�VXEURXWLQH�IURP�ZLWKLQ�DQ\�H[SUHVVLRQ�E\�XVLQJ�WKH�VXEURXWLQH�QDPH��ZLWKWKH�DPSHUVDQG��

&marine; # says Hello, sailor number 1!&marine; # says Hello, sailor number 2!&marine; # says Hello, sailor number 3!&marine; # says Hello, sailor number 4!

0RVW�RIWHQ��ZH�UHIHU�WR�WKH�LQYRFDWLRQ�DV�VLPSO\�FDOOLQJ�WKH�VXEURXWLQH�

Return Values7KH�VXEURXWLQH� LV�DOZD\V� LQYRNHG�DV�SDUW�RI�DQ�H[SUHVVLRQ��HYHQ� LI� WKH�UHVXOW�RI� WKHH[SUHVVLRQ�LVQ¦W�EHLQJ�XVHG��:KHQ�ZH�LQYRNHG�&marine�HDUOLHU��ZH�ZHUH�FDOFXODWLQJ�WKHYDOXH�RI�WKH�H[SUHVVLRQ�FRQWDLQLQJ�WKH�LQYRFDWLRQ��EXW�WKHQ�WKURZLQJ�DZD\�WKH�UHVXOW�

0DQ\�WLPHV��\RX¦OO�FDOO�D�VXEURXWLQH�DQG�DFWXDOO\�GR�VRPHWKLQJ�ZLWK�WKH�UHVXOW��7KLVPHDQV�WKDW�\RX¦OO�EH�SD\LQJ�DWWHQWLRQ�WR�WKH�UHWXUQ�YDOXH�RI�WKH�VXEURXWLQH��$OO�3HUOVXEURXWLQHV�KDYH�D�UHWXUQ�YDOXH¢WKHUH¦V�QR�GLVWLQFWLRQ�EHWZHHQ�WKRVH�WKDW�UHWXUQ�YDO�XHV�DQG�WKRVH�WKDW�GRQ¦W��1RW�DOO�3HUO�VXEURXWLQHV�KDYH�D�XVHIXO�UHWXUQ�YDOXH��KRZHYHU�

8QOHVV�\RXU�VXEURXWLQH�LV�EHLQJ�SDUWLFXODUO\�WULFN\�DQG�GHFODUHV�D�£SURWRW\SH�¤�ZKLFK�GLFWDWHV�KRZ�D�FRPSLOHUZLOO�SDUVH�DQG�LQWHUSUHW�LWV�LQYRFDWLRQ�DUJXPHQWV��7KLV�LV�UDUH¢VHH�WKH�SHUOVXE�PDQSDJH�IRU�PRUH�LQIRUPDWLRQ�

� ,I�\RX�ZLVK�WR�EH�SRZHUIXOO\�WULFN\��UHDG�WKH�3HUO�GRFXPHQWDWLRQ�DERXW�FRGHUHIV�VWRUHG�LQ�SULYDWH��OH[LFDO�YDULDEOHV�

® $�ZDUQDEOH�RIIHQVH��KRZHYHU�

$QG�IUHTXHQWO\�D�SDLU�RI�SDUHQWKHVHV��HYHQ�LI�HPSW\��$V�ZULWWHQ��WKH�VXEURXWLQH�LQKHULWV�WKH�FDOOHU¦V�@_�YDOXH�ZKLFK�ZH¦OO�EH�GLVFXVVLQJ�VKRUWO\��6R�GRQ¦W�VWRS�UHDGLQJ�KHUH��RU�\RX¦OO�EH�ZULWLQJ�FRGH�ZLWK�XQLQWHQGHG�HIIHFWV�

56 | Chapter 4:ಗSubroutines

6LQFH�DOO�3HUO�VXEURXWLQHV�FDQ�EH�FDOOHG�LQ�D�ZD\�WKDW�QHHGV�D�UHWXUQ�YDOXH��LW¦G�EH�D�ELWZDVWHIXO�WR�KDYH�WR�GHFODUH�VSHFLDO�V\QWD[�WR�£UHWXUQ¤�D�SDUWLFXODU�YDOXH�IRU�WKH�PDMRULW\RI�WKH�FDVHV��6R�/DUU\�PDGH�LW�VLPSOH��$V�3HUO�LV�FKXJJLQJ�DORQJ�LQ�D�VXEURXWLQH��LW�LVFDOFXODWLQJ�YDOXHV�DV�SDUW�RI�LWV�VHULHV�RI�DFWLRQV��:KDWHYHU�FDOFXODWLRQ�LV�ODVW�SHUIRUPHGLQ�D�VXEURXWLQH�LV�DXWRPDWLFDOO\�DOVR�WKH�UHWXUQ�YDOXH�

)RU�H[DPSOH��OHW¦V�GHILQH�WKLV�VXEURXWLQH�

sub sum_of_fred_and_barney { print "Hey, you called the sum_of_fred_and_barney subroutine!\n"; $fred + $barney; # That's the return value}

7KH�ODVW�H[SUHVVLRQ�HYDOXDWHG�LQ�WKH�ERG\�RI�WKLV�VXEURXWLQH�LV�WKH�VXP�RI�$fred�DQG$barney��VR�WKH�VXP�RI�$fred�DQG�$barney�ZLOO�EH�WKH�UHWXUQ�YDOXH��+HUH¦V�WKDW�LQ�DFWLRQ�

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

7KDW�FRGH�ZLOO�SURGXFH�WKLV�RXWSXW�

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

7KDW�print�VWDWHPHQW�LV�MXVW�D�GHEXJJLQJ�DLG��VR�WKDW�\RX�FDQ�VHH�WKDW�\RX�FDOOHG�WKHVXEURXWLQH��<RX¦G�WDNH�LW�RXW�ZKHQ�WKH�SURJUDP�LV�ILQLVKHG��%XW�VXSSRVH�\RX�DGGHGDQRWKHU�OLQH�WR�WKH�HQG�RI�WKH�FRGH��OLNH�WKLV�

sub sum_of_fred_and_barney { print "Hey, you called the sum_of_fred_and_barney subroutine!\n"; $fred + $barney; # That's not really the return value! print "Hey, I'm returning a value now!\n"; # Oops!}

,Q�WKLV�H[DPSOH��WKH�ODVW�H[SUHVVLRQ�HYDOXDWHG�LV�QRW�WKH�DGGLWLRQ��LW¦V�WKH�print�VWDWH�PHQW��,WV�UHWXUQ�YDOXH�ZLOO�QRUPDOO\�EH�1��PHDQLQJ�£SULQWLQJ�ZDV�VXFFHVVIXO�¤ �EXW�WKDW¦VQRW�WKH�UHWXUQ�YDOXH�\RX�DFWXDOO\�ZDQWHG��6R�EH�FDUHIXO�ZKHQ�DGGLQJ�DGGLWLRQDO�FRGHWR�D�VXEURXWLQH��VLQFH�WKH�ODVW�H[SUHVVLRQ�HYDOXDWHG�ZLOO�EH�WKH�UHWXUQ�YDOXH�

6R��ZKDW�KDSSHQHG�WR�WKH�VXP�RI�$fred�DQG�$barney�LQ�WKDW�VHFRQG��IDXOW\��VXEURXWLQH":H�GLGQ¦W�SXW�LW�DQ\ZKHUH��VR�3HUO�GLVFDUGHG�LW��,I�\RX�KDG�UHTXHVWHG�ZDUQLQJV��3HUO�QRWLFLQJ�WKDW� WKHUH¦V�QRWKLQJ�XVHIXO�DERXW�DGGLQJ�WZR�YDULDEOHV�DQG�GLVFDUGLQJ�WKHUHVXOW��ZRXOG�OLNHO\�ZDUQ�\RX�DERXW�VRPHWKLQJ�OLNH�£D�XVHOHVV�XVH�RI�DGGLWLRQ�LQ�D�YRLG

7KH�UHWXUQ�YDOXH�RI�print�LV�WUXH�IRU�D�VXFFHVVIXO�RSHUDWLRQ�DQG�IDOVH�IRU�D�IDLOXUH��<RX¦OO�VHH�KRZ�WR�GHWHUPLQHWKH�NLQG�RI�IDLOXUH�ODWHU�LQ�WKH�QH[W�FKDSWHU�

Return Values | 57

FRQWH[W�¤�7KH�WHUP�YRLG�FRQWH[W�LV�MXVW�D�IDQF\�ZD\�RI�VD\LQJ�WKDW�WKH�DQVZHU�LVQ¦W�EHLQJVWRUHG�LQ�D�YDULDEOH�RU�XVHG�LQ�DQ\�RWKHU�ZD\�

£7KH�ODVW�H[SUHVVLRQ�HYDOXDWHG¤�UHDOO\�PHDQV�WKH�ODVW�H[SUHVVLRQ�HYDOXDWHG��UDWKHU�WKDQWKH�ODVW�OLQH�RI�WH[W��)RU�H[DPSOH��WKLV�VXEURXWLQH�UHWXUQV�WKH�ODUJHU�YDOXH�RI�$fred�RU$barney�

sub larger_of_fred_or_barney { if ($fred > $barney) { $fred; } else { $barney; }}

7KH�ODVW�H[SUHVVLRQ�HYDOXDWHG�LV�HLWKHU�$fred�RU�$barney��VR�WKH�YDOXH�RI�RQH�RI�WKRVHYDULDEOHV�EHFRPHV�WKH�UHWXUQ�YDOXH��<RX�ZRQ¦W�NQRZ�ZKHWKHU�WKH�UHWXUQ�YDOXH�ZLOO�EH$fred�RU�$barney�XQWLO�\RX�VHH�ZKDW�WKRVH�YDULDEOHV�KROG�DW�UXQWLPH�

7KHVH�DUH�DOO�UDWKHU�WULYLDO�H[DPSOHV��,W�JHWV�EHWWHU�ZKHQ�\RX�FDQ�SDVV�YDOXHV�WKDW�DUHGLIIHUHQW�IRU�HDFK�LQYRFDWLRQ�LQWR�D�VXEURXWLQH�LQVWHDG�RI�UHO\LQJ�RQ�JOREDO�YDULDEOHV��,QIDFW��WKDW¦V�FRPLQJ�ULJKW�XS�

Arguments7KDW� VXEURXWLQH� FDOOHG� larger_of_fred_or_barney�ZRXOG� EH�PXFK�PRUH� XVHIXO� LI� LWGLGQ¦W�IRUFH�\RX�WR�XVH�WKH�JOREDO�YDULDEOHV�$fred�DQG�$barney��,I�\RX�ZDQWHG�WR�JHW�WKHODUJHU�YDOXH�IURP�$wilma�DQG�$betty��\RX�FXUUHQWO\�KDYH�WR�FRS\�WKRVH�LQWR�$fred�DQG$barney�EHIRUH�\RX�FDQ�XVH�larger_of_fred_or_barney��$QG�LI�\RX�KDG�VRPHWKLQJ�XVHIXOLQ�WKRVH�YDULDEOHV��\RX¦G�KDYH�WR�ILUVW�FRS\�WKRVH�WR�RWKHU�YDULDEOHV��VD\�$save_fred�DQG$save_barney��$QG�WKHQ��ZKHQ�\RX¦UH�GRQH�ZLWK�WKH�VXEURXWLQH��\RX¦G�KDYH�WR�FRS\WKRVH�EDFN�WR�$fred�DQG�$barney�DJDLQ�

/XFNLO\��3HUO�KDV�VXEURXWLQH�DUJXPHQWV��7R�SDVV�DQ�DUJXPHQW�OLVW�WR�WKH�VXEURXWLQH�VLPSO\�SODFH�WKH�OLVW�H[SUHVVLRQ��LQ�SDUHQWKHVHV��DIWHU�WKH�VXEURXWLQH�LQYRFDWLRQ��OLNHWKLV�

$n = &max(10, 15); # This sub call has two parameters

7KH�OLVW�LV�SDVVHG�WR�WKH�VXEURXWLQH��WKDW�LV��LW¦V�PDGH�DYDLODEOH�IRU�WKH�VXEURXWLQH�WR�XVHKRZHYHU�LW�QHHGV�WR��2I�FRXUVH��\RX�KDYH�WR�VWRUH�WKLV�OLVW�VRPHZKHUH��VR�3HUO�DXWRPDW�LFDOO\�VWRUHV�WKH�SDUDPHWHU�OLVW��DQRWKHU�QDPH�IRU�WKH�DUJXPHQW�OLVW��LQ�WKH�VSHFLDO�DUUD\YDULDEOH�QDPHG�@_�IRU�WKH�GXUDWLRQ�RI�WKH�VXEURXWLQH��7KH�VXEURXWLQH�FDQ�DFFHVV�WKLVYDULDEOH�WR�GHWHUPLQH�ERWK�WKH�QXPEHU�RI�DUJXPHQWV�DQG�WKH�YDOXH�RI�WKRVH�DUJXPHQWV�

7KLV�PHDQV�WKDW�WKH�ILUVW�VXEURXWLQH�SDUDPHWHU�LV�VWRUHG�LQ�$_[0]��WKH�VHFRQG�RQH�LVVWRUHG�LQ�$_[1]��DQG�VR�RQ��%XW¢DQG�KHUH¦V�DQ�LPSRUWDQW�QRWH¢WKHVH�YDULDEOHV�KDYHQRWKLQJ�ZKDWVRHYHU�WR�GR�ZLWK�WKH�$_�YDULDEOH��DQ\�PRUH�WKDQ�$dino[3]��DQ�HOHPHQW�RIWKH�@dino�DUUD\��KDV�WR�GR�ZLWK�$dino��D�FRPSOHWHO\�GLVWLQFW�VFDODU�YDULDEOH���,W¦V�MXVW

58 | Chapter 4:ಗSubroutines

WKDW�WKH�SDUDPHWHU�OLVW�PXVW�EH�VWRUHG�LQWR�VRPH�DUUD\�YDULDEOH�IRU�WKH�VXEURXWLQH�WRXVH�LW��DQG�3HUO�XVHV�WKH�DUUD\�@_�IRU�WKLV�SXUSRVH�

1RZ�� \RX� FRXOG� ZULWH� WKH� VXEURXWLQH� &max� WR� ORRN� D� OLWWOH� OLNH� WKH� VXEURXWLQH&larger_of_fred_or_barney��EXW�LQVWHDG�RI�XVLQJ�$fred�\RX�FRXOG�XVH�WKH�ILUVW�VXEURX�WLQH� SDUDPHWHU� �$_[0]��� DQG� LQVWHDG� RI� XVLQJ� $barney�� \RX� FRXOG� XVH� WKH� VHFRQGVXEURXWLQH�SDUDPHWHU��$_[1]���$QG�VR�\RX�FRXOG�HQG�XS�ZLWK�FRGH�VRPHWKLQJ�OLNH�WKLV�

sub max { # Compare this to &larger_of_fred_or_barney if ($_[0] > $_[1]) { $_[0]; } else { $_[1]; }}

:HOO��DV�ZH�VDLG��\RX�FRXOG�GR�WKDW��%XW�LW¦V�SUHWW\�XJO\�ZLWK�DOO�RI�WKRVH�VXEVFULSWV��DQGKDUG�WR�UHDG��ZULWH��FKHFN��DQG�GHEXJ��WRR��<RX¦OO�VHH�D�EHWWHU�ZD\�LQ�D�PRPHQW�

7KHUH¦V�DQRWKHU�SUREOHP�ZLWK�WKLV�VXEURXWLQH��7KH�QDPH�&max�LV�QLFH�DQG�VKRUW��EXW�LWGRHVQ¦W�UHPLQG�XV�WKDW�WKLV�VXEURXWLQH�ZRUNV�SURSHUO\�RQO\�LI�FDOOHG�ZLWK�H[DFWO\�WZRSDUDPHWHUV�

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

([FHVV�SDUDPHWHUV�DUH�LJQRUHG¢VLQFH�WKH�VXEURXWLQH�QHYHU�ORRNV�DW�$_[2]��3HUO�GRHVQ¦WFDUH�ZKHWKHU�WKHUH¦V�VRPHWKLQJ�LQ�WKHUH�RU�QRW��$QG�LQVXIILFLHQW�SDUDPHWHUV�DUH�DOVRLJQRUHG¢\RX�VLPSO\�JHW�undef�LI�\RX�ORRN�EH\RQG�WKH�HQG�RI�WKH�@_�DUUD\��DV�ZLWK�DQ\RWKHU�DUUD\��<RX¦OO�VHH�KRZ�WR�PDNH�D�EHWWHU�&max��ZKLFK�ZRUNV�ZLWK�DQ\�QXPEHU�RISDUDPHWHUV��ODWHU�LQ�WKLV�FKDSWHU�

7KH�@_�YDULDEOH�LV�SULYDWH�WR�WKH�VXEURXWLQH� �LI�WKHUH¦V�D�JOREDO�YDOXH�LQ�@_��LW�LV�VDYHGDZD\�EHIRUH�WKH�VXEURXWLQH�LV�LQYRNHG�DQG�UHVWRUHG�WR�LWV�SUHYLRXV�YDOXH�XSRQ�UHWXUQIURP�WKH�VXEURXWLQH���7KLV�DOVR�PHDQV�WKDW�D�VXEURXWLQH�FDQ�SDVV�DUJXPHQWV�WR�DQRWKHUVXEURXWLQH�ZLWKRXW�IHDU�RI�ORVLQJ�LWV�RZQ�@_�YDULDEOH¢WKH�QHVWHG�VXEURXWLQH�LQYRFDWLRQJHWV� LWV�RZQ�@_� LQ�WKH�VDPH�ZD\��(YHQ�LI�WKH�VXEURXWLQH�FDOOV� LWVHOI�UHFXUVLYHO\��HDFKLQYRFDWLRQ�JHWV�D�QHZ�@_��VR�@_�LV�DOZD\V�WKH�SDUDPHWHU�OLVW�IRU�WKH�FXUUHQW�VXEURXWLQHLQYRFDWLRQ�

8QOHVV�WKHUH¦V�DQ�DPSHUVDQG�LQ�IURQW�RI�WKH�QDPH�IRU�WKH�LQYRFDWLRQ��DQG�QR�SDUHQWKHVHV��RU�DUJXPHQWV�DIWHUZDUG��LQ�ZKLFK�FDVH�WKH�@_�DUUD\�LV�LQKHULWHG�IURP�WKH�FDOOHU¦V�FRQWH[W��7KDW¦V�JHQHUDOO\�D�EDG�LGHD��EXWLV�RFFDVLRQDOO\�XVHIXO�

� <RX�PLJKW�UHFRJQL]H�WKDW�WKLV�LV�WKH�VDPH�PHFKDQLVP�DV�XVHG�ZLWK�WKH�FRQWURO�YDULDEOH�RI�WKH�foreach�ORRS�DV�VHHQ�LQ�WKH�SUHYLRXV�FKDSWHU��,Q�HLWKHU�FDVH��WKH�YDULDEOH¦V�YDOXH�LV�VDYHG�DQG�DXWRPDWLFDOO\�UHVWRUHG�E\�3HUO�

Arguments | 59

Private Variables in Subroutines%XW�LI�3HUO�FDQ�JLYH�XV�D�QHZ�@_�IRU�HYHU\�LQYRFDWLRQ��FDQ¦W�LW�JLYH�XV�YDULDEOHV�IRU�RXURZQ�XVH�DV�ZHOO"�2I�FRXUVH�LW�FDQ�

%\�GHIDXOW��DOO�YDULDEOHV�LQ�3HUO�DUH�JOREDO�YDULDEOHV��WKDW�LV��WKH\�DUH�DFFHVVLEOH�IURPHYHU\�SDUW�RI�WKH�SURJUDP��%XW�\RX�FDQ�FUHDWH�SULYDWH�YDULDEOHV�FDOOHG�OH[LFDO�YDULDEOHVDW�DQ\�WLPH�ZLWK�WKH�my�RSHUDWRU�

sub max { my($m, $n); # new, private variables for this block ($m, $n) = @_; # give names to the parameters if ($m > $n) { $m } else { $n }}

7KHVH�YDULDEOHV�DUH�SULYDWH��RU�VFRSHG��WR�WKH�HQFORVLQJ�EORFN��DQ\�RWKHU�$m�RU�$n�LV�WRWDOO\XQDIIHFWHG�E\�WKHVH�WZR��$QG�WKDW�JRHV�WKH�RWKHU�ZD\��WRR¢QR�RWKHU�FRGH�FDQ�DFFHVVRU�PRGLI\�WKHVH�SULYDWH�YDULDEOHV��E\�DFFLGHQW�RU�GHVLJQ� �6R��\RX�FRXOG�GURS�WKLV�VXE�URXWLQH�LQWR�DQ\�3HUO�SURJUDP�LQ�WKH�ZRUOG�DQG�NQRZ�WKDW�\RX�ZRXOGQ¦W�PHVV�XS�WKDWSURJUDP¦V�$m�DQG�$n��LI�DQ\����,W¦V�DOVR�ZRUWK�SRLQWLQJ�RXW�WKDW��LQVLGH�WKH�if¦V�EORFNV�WKHUH¦V�QR�VHPLFRORQ�QHHGHG�DIWHU�WKH�UHWXUQ�YDOXH�H[SUHVVLRQ��$OWKRXJK�3HUO�DOORZV\RX�WR�RPLW�WKH�ODVW�VHPLFRORQ�LQ�D�EORFN��LQ�SUDFWLFH�\RX�RPLW�LW�RQO\�ZKHQ�WKH�FRGH�LVVR�VLPSOH�WKDW�\RX�FDQ�ZULWH�WKH�EORFN�LQ�D�VLQJOH�OLQH�

7KH�VXEURXWLQH�LQ�WKH�SUHYLRXV�H[DPSOH�FRXOG�EH�PDGH�HYHQ�VLPSOHU��'LG�\RX�QRWLFHWKDW�WKH�OLVW�($m, $n)�ZDV�ZULWWHQ�WZLFH"�7KDW�my�RSHUDWRU�FDQ�DOVR�EH�DSSOLHG�WR�D�OLVWRI�YDULDEOHV�HQFORVHG�LQ�SDUHQWKHVHV��VR�LW¦V�FXVWRPDU\�WR�FRPELQH�WKRVH�ILUVW�WZR�VWDWH�PHQWV�LQ�WKH�VXEURXWLQH�

my($m, $n) = @_; # Name the subroutine parameters

7KDW� RQH� VWDWHPHQW� FUHDWHV� WKH� SULYDWH� YDULDEOHV� DQG� VHWV� WKHLU� YDOXHV�� VR� WKH� ILUVWSDUDPHWHU�QRZ�KDV�WKH�HDVLHU�WR�XVH�QDPH�$m�DQG�WKH�VHFRQG�KDV�$n��1HDUO\�HYHU\�VXE�URXWLQH�ZLOO�VWDUW�ZLWK�D�OLQH�PXFK�OLNH�WKDW�RQH��QDPLQJ�LWV�SDUDPHWHUV��:KHQ�\RX�VHHWKDW�OLQH��\RX¦OO�NQRZ�WKDW�WKH�VXEURXWLQH�H[SHFWV�WZR�VFDODU�SDUDPHWHUV��ZKLFK�\RX¦OOFDOO�$m�DQG�$n�LQVLGH�WKH�VXEURXWLQH�

Variable-Length Parameter Lists,Q�UHDO�ZRUOG�3HUO�FRGH��VXEURXWLQHV�DUH�RIWHQ�JLYHQ�SDUDPHWHU�OLVWV�RI�DUELWUDU\�OHQJWK�7KDW¦V�EHFDXVH�RI�3HUO¦V�£QR�XQQHFHVVDU\�OLPLWV¤�SKLORVRSK\�WKDW�\RX¦YH�DOUHDG\�VHHQ�2I�FRXUVH��WKLV�LV�XQOLNH�PDQ\�WUDGLWLRQDO�SURJUDPPLQJ�ODQJXDJHV��ZKLFK�UHTXLUH�HYHU\VXEURXWLQH�WR�EH�VWULFWO\�W\SHG��WKDW�LV��WR�SHUPLW�RQO\�D�FHUWDLQ��SUHGHILQHG�QXPEHU�RI

$GYDQFHG�SURJUDPPHUV�ZLOO�UHDOL]H�WKDW�D�OH[LFDO�YDULDEOH�PD\�EH�DFFHVVLEOH�E\�UHIHUHQFH�IURP�RXWVLGH�LWVVFRSH��EXW�QHYHU�E\�QDPH�

� 2I�FRXUVH��LI�WKDW�SURJUDP�DOUHDG\�KDG�D�VXEURXWLQH�FDOOHG�&max��\RX¦G�PHVV�WKDW�XS�

60 | Chapter 4:ಗSubroutines

SDUDPHWHUV�RI�SUHGHILQHG�W\SHV���,W¦V�QLFH�WKDW�3HUO�LV�VR�IOH[LEOH��EXW��DV�\RX�VDZ�ZLWKWKH�&max�URXWLQH�HDUOLHU��WKDW�PD\�FDXVH�SUREOHPV�ZKHQ�D�VXEURXWLQH�LV�FDOOHG�ZLWK�DGLIIHUHQW�QXPEHU�RI�DUJXPHQWV�WKDQ�WKH�DXWKRU�H[SHFWHG�

2I�FRXUVH��WKH�VXEURXWLQH�FDQ�HDVLO\�FKHFN�WKDW�LW�KDV�WKH�ULJKW�QXPEHU�RI�DUJXPHQWVE\�H[DPLQLQJ�WKH�@_�DUUD\��)RU�H[DPSOH��ZH�FRXOG�KDYH�ZULWWHQ�&max�WR�FKHFN�LWV�DUJX�PHQW�OLVW�OLNH�WKLV�

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

7KDW�if�WHVW�XVHV�WKH�£QDPH¤�RI�WKH�DUUD\�LQ�D�VFDODU�FRQWH[W�WR�ILQG�RXW�WKH�QXPEHU�RIDUUD\�HOHPHQWV��DV�\RX�VDZ�LQ�&KDSWHU���

%XW�LQ�UHDO�ZRUOG�3HUO�SURJUDPPLQJ��WKLV�VRUW�RI�FKHFN�LV�KDUGO\�HYHU�XVHG��LW¦V�EHWWHU�WRPDNH�WKH�VXEURXWLQH�DGDSW�WR�WKH�SDUDPHWHUV�

A Better &max Routine6R�OHW¦V�UHZULWH�&max�WR�DOORZ�IRU�DQ\�QXPEHU�RI�DUJXPHQWV�

$maximum = &max(3, 5, 10, 4, 6);

sub max { my($max_so_far) = shift @_; # the first one is the largest yet seen foreach (@_) { # look at the remaining arguments if ($_ > $max_so_far) { # could this one be bigger yet? $max_so_far = $_; } } $max_so_far;}

7KLV�FRGH�XVHV�ZKDW�KDV�RIWHQ�EHHQ�FDOOHG�WKH�£KLJK�ZDWHU�PDUN¤�DOJRULWKP��DIWHU�DIORRG��ZKHQ�WKH�ZDWHUV�KDYH�VXUJHG�DQG�UHFHGHG�IRU�WKH�ODVW�WLPH��WKH�KLJK�ZDWHU�PDUNVKRZV�ZKHUH�WKH�KLJKHVW�ZDWHU�ZDV�VHHQ��,Q�WKLV�URXWLQH��$max_so_far�NHHSV�WUDFN�RIRXU�KLJK�ZDWHU�PDUN��WKH�ODUJHVW�QXPEHU�\HW�VHHQ�

7KH�ILUVW�OLQH�VHWV�$max_so_far�WR�3��WKH�ILUVW�SDUDPHWHU�LQ�WKH�H[DPSOH�FRGH��E\�VKLIWLQJWKDW�SDUDPHWHU�IURP�WKH�SDUDPHWHU�DUUD\��@_��6R�@_�QRZ�KROGV�(5, 10, 4, 6)��VLQFH�WKH

$V�VRRQ�DV�\RX�OHDUQ�DERXW�warn�LQ�WKH�QH[W�FKDSWHU��\RX¦OO�VHH�WKDW�\RX�FDQ�XVH�LW�WR�WXUQ�LPSURSHU�XVDJH�OLNHWKLV�LQWR�D�SURSHU�ZDUQLQJ��2U�SHUKDSV�\RX¦OO�GHFLGH�WKDW�WKLV�FDVH�LV�VHYHUH�HQRXJK�WR�ZDUUDQW�XVLQJ�die�GHVFULEHG�LQ�WKH�VDPH�FKDSWHU�

Variable-Length Parameter Lists | 61

3�KDV�EHHQ�VKLIWHG�RII��$QG�WKH�ODUJHVW�QXPEHU�\HW�VHHQ�LV�WKH�RQO\�RQH�\HW�VHHQ��3��WKHILUVW�SDUDPHWHU�

1RZ��WKH�foreach�ORRS�ZLOO�VWHS�WKURXJK�WKH�UHPDLQLQJ�YDOXHV�LQ�WKH�SDUDPHWHU�OLVW�IURP�@_��7KH�FRQWURO�YDULDEOH�RI�WKH�ORRS�LV��E\�GHIDXOW��$_���%XW��UHPHPEHU��WKHUH¦V�QRDXWRPDWLF�FRQQHFWLRQ�EHWZHHQ�@_�DQG�$_��LW¦V�MXVW�D�FRLQFLGHQFH�WKDW�WKH\�KDYH�VXFKVLPLODU�QDPHV���7KH�ILUVW�WLPH�WKURXJK�WKH�ORRS��$_�LV�5��7KH�if�WHVW�VHHV�WKDW�LW�LV�ODUJHUWKDQ�$max_so_far��VR�$max_so_far�LV�VHW�WR�5¢WKH�QHZ�KLJK�ZDWHU�PDUN�

7KH�QH[W�WLPH�WKURXJK�WKH�ORRS��$_�LV�10��7KDW¦V�D�QHZ�UHFRUG�KLJK��VR�LW¦V�VWRUHG�LQ$max_so_far�DV�ZHOO�

7KH�QH[W�WLPH��$_�LV�4��7KH�if�WHVW�IDLOV��VLQFH�WKDW¦V�QR�ODUJHU�WKDQ�$max_so_far��ZKLFKLV�10��VR�WKH�ERG\�RI�WKH�if�LV�VNLSSHG�

7KH�QH[W�WLPH��$_�LV�6��DQG�WKH�ERG\�RI�WKH�if�LV�VNLSSHG�DJDLQ��$QG�WKDW�ZDV�WKH�ODVWWLPH�WKURXJK�WKH�ORRS��VR�WKH�ORRS�LV�GRQH�

1RZ��$max_so_far�EHFRPHV�WKH�UHWXUQ�YDOXH��,W¦V�WKH�ODUJHVW�QXPEHU�ZH¦YH�VHHQ��DQGZH¦YH�VHHQ�WKHP�DOO��VR�LW�PXVW�EH�WKH�ODUJHVW�IURP�WKH�OLVW��10�

Empty Parameter Lists7KDW� LPSURYHG� &max� DOJRULWKP� ZRUNV� ILQH� QRZ�� HYHQ� LI� WKHUH� DUH� PRUH� WKDQ� WZRSDUDPHWHUV��%XW�ZKDW�KDSSHQV�LI�WKHUH�LV�QRQH"

$W�ILUVW��LW�PD\�VHHP�WRR�HVRWHULF�WR�ZRUU\�DERXW��$IWHU�DOO��ZK\�ZRXOG�VRPHRQH�FDOO&max�ZLWKRXW�JLYLQJ�LW�DQ\�SDUDPHWHUV"�%XW�PD\EH�VRPHRQH�ZURWH�D�OLQH�OLNH�WKLV�RQH�

$maximum = &max(@numbers);

$QG�WKH�DUUD\�@numbers�PLJKW�VRPHWLPHV�EH�DQ�HPSW\�OLVW��SHUKDSV�LW�ZDV�UHDG�LQ�IURPD�ILOH�WKDW�WXUQHG�RXW�WR�EH�HPSW\��IRU�H[DPSOH��6R�\RX�QHHG�WR�NQRZ��ZKDW�GRHV�&maxGR�LQ�WKDW�FDVH"

7KH�ILUVW�OLQH�RI�WKH�VXEURXWLQH�VHWV�$max_so_far�E\�XVLQJ�shift�RQ�@_��WKH��QRZ�HPSW\�SDUDPHWHU�DUUD\��7KDW¦V�KDUPOHVV��WKH�DUUD\�LV�OHIW�HPSW\��DQG�shift�UHWXUQV�undef�WR$max_so_far�

1RZ�WKH�foreach�ORRS�ZDQWV�WR�LWHUDWH�RYHU�@_��EXW�VLQFH�WKDW¦V�HPSW\��WKH�ORRS�ERG\LV�H[HFXWHG�]HUR�WLPHV�

6R�LQ�VKRUW�RUGHU��3HUO�UHWXUQV�WKH�YDOXH�RI�$max_so_far¢undef¢DV�WKH�UHWXUQ�YDOXH�RIWKH�VXEURXWLQH��,Q�VRPH�VHQVH��WKDW¦V�WKH�ULJKW�DQVZHU�EHFDXVH�WKHUH�LV�QR�ODUJHVW�YDOXHLQ�DQ�HPSW\�OLVW�

2I�FRXUVH��ZKRHYHU�LV�FDOOLQJ�WKLV�VXEURXWLQH�VKRXOG�EH�DZDUH�WKDW�WKH�UHWXUQ�YDOXH�PD\EH�undef¢RU�WKH\�FRXOG�VLPSO\�HQVXUH�WKDW�WKH�SDUDPHWHU�OLVW�LV�QHYHU�HPSW\�

62 | Chapter 4:ಗSubroutines

Notes on Lexical (my) Variables7KRVH�OH[LFDO�YDULDEOHV�FDQ�DFWXDOO\�EH�XVHG�LQ�DQ\�EORFN��QRW�PHUHO\�LQ�D�VXEURXWLQH¦VEORFN��)RU�H[DPSOH��WKH\�FDQ�EH�XVHG�LQ�WKH�EORFN�RI�DQ�if��while��RU�foreach�

foreach (1..10) { my($square) = $_ * $_; # private variable in this loop print "$_ squared is $square.\n";}

7KH�YDULDEOH�$square�LV�SULYDWH�WR�WKH�HQFORVLQJ�EORFN��LQ�WKLV�FDVH��WKDW¦V�WKH�EORFN�RIWKH�foreach�ORRS��,I�WKHUH¦V�QR�HQFORVLQJ�EORFN��WKH�YDULDEOH�LV�SULYDWH�WR�WKH�HQWLUH�VRXUFHILOH��)RU�QRZ��\RXU�SURJUDPV�DUHQ¦W�JRLQJ�WR�XVH�PRUH�WKDQ�RQH�VRXUFH�ILOH��VR�WKLV�LVQ¦WDQ� LVVXH��%XW� WKH� LPSRUWDQW�FRQFHSW� LV� WKDW� WKH�VFRSH�RI�D� OH[LFDO�YDULDEOH¦V�QDPH� LVOLPLWHG�WR�WKH�VPDOOHVW�HQFORVLQJ�EORFN�RU�ILOH��7KH�RQO\�FRGH�WKDW�FDQ�VD\�$square�DQGPHDQ�WKDW�YDULDEOH�LV�WKH�FRGH�LQVLGH�WKDW�WH[WXDO�VFRSH��7KLV�LV�D�ELJ�ZLQ�IRU�PDLQWDLQ�DELOLW\¢LI�WKH�ZURQJ�YDOXH�LV�IRXQG�LQ�$square��WKH�FXOSULW�ZLOO�EH�IRXQG�ZLWKLQ�D�OLPLWHGDPRXQW�RI�VRXUFH�FRGH��$V�H[SHULHQFHG�SURJUDPPHUV�KDYH�OHDUQHG��RIWHQ�WKH�KDUG�ZD\��OLPLWLQJ�WKH�VFRSH�RI�D�YDULDEOH�WR�D�SDJH�RI�FRGH��RU�HYHQ�WR�D�IHZ�OLQHV�RI�FRGH��UHDOO\VSHHGV�DORQJ�WKH�GHYHORSPHQW�DQG�WHVWLQJ�F\FOH�

1RWH�DOVR�WKDW�WKH�my�RSHUDWRU�GRHVQ¦W�FKDQJH�WKH�FRQWH[W�RI�DQ�DVVLJQPHQW�

my($num) = @_; # list context, same as ($num) = @_;my $num = @_; # scalar context, same as $num = @_;

,Q�WKH�ILUVW�RQH��$num�JHWV�WKH�ILUVW�SDUDPHWHU��DV�D�OLVW�FRQWH[W�DVVLJQPHQW��LQ�WKH�VHFRQG�LW�JHWV�WKH�QXPEHU�RI�SDUDPHWHUV��LQ�D�VFDODU�FRQWH[W��(LWKHU�OLQH�RI�FRGH�FRXOG�EH�ZKDWWKH�SURJUDPPHU�ZDQWHG��\RX�FDQ¦W�WHOO�IURP�WKDW�RQH�OLQH�DORQH��DQG�VR�3HUO�FDQ¦W�ZDUQ\RX�LI�\RX�XVH�WKH�ZURQJ�RQH���2I�FRXUVH��\RX�ZRXOGQ¦W�KDYH�ERWK�RI�WKRVH�OLQHV�LQ�WKHVDPH�VXEURXWLQH��VLQFH�\RX�FDQ¦W�KDYH�WZR�OH[LFDO�YDULDEOHV�ZLWK�WKH�VDPH�QDPH�GH�FODUHG�LQ�WKH�VDPH�VFRSH��WKLV�LV�MXVW�DQ�H[DPSOH���6R��ZKHQ�UHDGLQJ�FRGH�OLNH�WKLV��\RXFDQ�DOZD\V� WHOO� WKH�FRQWH[W�RI� WKH�DVVLJQPHQW�E\�VHHLQJ�ZKDW� WKH�FRQWH[W�ZRXOG�EHZLWKRXW�WKH�ZRUG�my�

6R�ORQJ�DV�ZH¦UH�GLVFXVVLQJ�XVLQJ�my()�ZLWK�SDUHQWKHVHV��LW¦V�ZRUWK�UHPHPEHULQJ�WKDWZLWKRXW�WKH�SDUHQWKHVHV��my�RQO\�GHFODUHV�D�VLQJOH�OH[LFDO�YDULDEOH�

my $fred, $barney; # WRONG! Fails to declare $barneymy($fred, $barney); # declares both

2I�FRXUVH��\RX�FDQ�XVH�my�WR�FUHDWH�QHZ��SULYDWH�DUUD\V�DV�ZHOO��

my @phone_number;

$Q\�QHZ�YDULDEOH�ZLOO�VWDUW�RXW�HPSW\¢undef�IRU�VFDODUV��RU�WKH�HPSW\�OLVW�IRU�DUUD\V�

$V�XVXDO��WXUQLQJ�RQ�ZDUQLQJV�ZLOO�JHQHUDOO\�UHSRUW�WKLV�DEXVH�RI�my��RU�\RX�FDQ�FDOO�������/(;,&$/�$%86(DQG�UHSRUW�LW�\RXUVHOI��8VLQJ�WKH�strict�SUDJPD��ZKLFK�ZH¦OO�VHH�LQ�D�PRPHQW��VKRXOG�IRUELG�LW�RXWULJKW�

� 2U�KDVKHV��ZKLFK�\RX¦OO�VHH�LQ�&KDSWHU���

Notes on Lexical (my) Variables | 63

The use strict Pragma3HUO�WHQGV�WR�EH�D�SUHWW\�SHUPLVVLYH�ODQJXDJH� �%XW�PD\EH�\RX�ZDQW�3HUO�WR�LPSRVH�DOLWWOH�GLVFLSOLQH��WKDW�FDQ�EH�DUUDQJHG�ZLWK�WKH�use strict�SUDJPD�

$�SUDJPD�LV�D�KLQW�WR�D�FRPSLOHU��WHOOLQJ�LW�VRPHWKLQJ�DERXW�WKH�FRGH��,Q�WKLV�FDVH��WKHuse strict�SUDJPD�WHOOV�3HUO¦V�LQWHUQDO�FRPSLOHU�WKDW�LW�VKRXOG�HQIRUFH�VRPH�JRRG�SUR�JUDPPLQJ�UXOHV�IRU�WKH�UHVW�RI�WKLV�EORFN�RU�VRXUFH�ILOH�

:K\�ZRXOG�WKLV�EH�LPSRUWDQW"�:HOO��LPDJLQH�WKDW�\RX¦UH�FRPSRVLQJ�\RXU�SURJUDP�DQG�\RX�W\SH�D�OLQH�OLNH�WKLV�RQH�

$bamm_bamm = 3; # Perl creates that variable automatically

1RZ��\RX�NHHS�W\SLQJ�IRU�D�ZKLOH��$IWHU�WKDW�OLQH�KDV�VFUROOHG�RII�WKH�WRS�RI�WKH�VFUHHQ�\RX�W\SH�WKLV�OLQH�WR�LQFUHPHQW�WKH�YDULDEOH�

$bammbamm += 1; # Oops!

6LQFH�3HUO�VHHV�D�QHZ�YDULDEOH�QDPH��WKH�XQGHUVFRUH�LV�VLJQLILFDQW�LQ�D�YDULDEOH�QDPH��LW�FUHDWHV�D�QHZ�YDULDEOH�DQG�LQFUHPHQWV�WKDW�RQH��,I�\RX¦UH�OXFN\�DQG�VPDUW��\RX¦YHWXUQHG�RQ�ZDUQLQJV��DQG�3HUO�FDQ�WHOO�\RX�WKDW�\RX�XVHG�RQH�RU�ERWK�RI�WKRVH�JOREDOYDULDEOH�QDPHV�RQO\�D�VLQJOH�WLPH�LQ�\RXU�SURJUDP��%XW�LI�\RX¦UH�PHUHO\�VPDUW��\RX�XVHGHDFK�QDPH�PRUH�WKDQ�RQFH��DQG�3HUO�ZRQ¦W�EH�DEOH�WR�ZDUQ�\RX�

7R�WHOO�3HUO�WKDW�\RX¦UH�UHDG\�WR�EH�PRUH�UHVWULFWLYH��SXW�WKH�use strict�SUDJPD�DW�WKHWRS�RI�\RXU�SURJUDP��RU�LQ�DQ\�EORFN�RU�ILOH�ZKHUH�\RX�ZDQW�WR�HQIRUFH�WKHVH�UXOHV��

use strict; # Enforce some good programming rules

1RZ��DPRQJ�RWKHU�UHVWULFWLRQV���3HUO�ZLOO�LQVLVW�WKDW�\RX�GHFODUH�HYHU\�QHZ�YDULDEOH�XVXDOO\�GRQH�ZLWK�my�®

my $bamm_bamm = 3; # New lexical variable

1RZ�LI�\RX�WU\�WR�VSHOO�LW�WKH�RWKHU�ZD\��3HUO�FDQ�FRPSODLQ�WKDW�\RX�KDYHQ¦W�GHFODUHGDQ\�YDULDEOH�FDOOHG�$bammbamm��VR�\RXU�PLVWDNH�LV�DXWRPDWLFDOO\�FDXJKW�DW�FRPSLOH�WLPH�

$bammbamm += 1; # No such variable: Compile time fatal error

2I�FRXUVH��WKLV�DSSOLHV�RQO\�WR�QHZ�YDULDEOHV��\RX�GRQ¦W�QHHG�WR�GHFODUH�3HUO¦V�EXLOW�LQYDULDEOHV��VXFK�DV�$_�DQG�@_��,I�\RX�DGG�use strict�WR�D�SURJUDP�WKDW�LV�DOUHDG\�ZULWWHQ�

%HW�\RX�KDGQ¦W�QRWLFHG�

� 7R�OHDUQ�DERXW�WKH�RWKHU�UHVWULFWLRQV��VHH�WKH�GRFXPHQWDWLRQ�IRU�strict��7KH�GRFXPHQWDWLRQ�IRU�DQ\�SUDJPDLV�ILOHG�XQGHU�WKDW�SUDJPD¦V�QDPH��VR�WKH�FRPPDQG�SHUOGRF�VWULFW��RU�\RXU�V\VWHP¦V�QDWLYH�GRFXPHQWDWLRQPHWKRG��VKRXOG�ILQG�LW�IRU�\RX��,Q�EULHI��WKH�RWKHU�UHVWULFWLRQV�UHTXLUH�WKDW�VWULQJV�EH�TXRWHG�LQ�PRVW�FDVHV�DQG�WKDW�UHIHUHQFHV�EH�WUXH��KDUG��UHIHUHQFHV��1HLWKHU�RI�WKHVH�UHVWULFWLRQV�VKRXOG�DIIHFW�EHJLQQHUV�LQ�3HUO�

® 7KHUH�DUH�VRPH�RWKHU�ZD\V�WR�GHFODUH�YDULDEOHV��WRR�

$QG��DW�OHDVW�LQ�VRPH�FLUFXPVWDQFHV��\RX�GRQ¦W�ZDQW�WR�GHFODUH�$a�DQG�$b�EHFDXVH�WKH\¦UH�XVHG�LQWHUQDOO\�E\sort��6R��LI�\RX¦UH�WHVWLQJ�WKLV�IHDWXUH��XVH�RWKHU�YDULDEOH�QDPHV�WKDQ�WKRVH�WZR��7KH�IDFW�WKDW�use strictGRHVQ¦W�IRUELG�WKHVH�WZR�LV�RQH�RI�WKH�PRVW�IUHTXHQWO\�UHSRUWHG�QRQEXJV�LQ�3HUO�

64 | Chapter 4:ಗSubroutines

\RX¦OO�JHQHUDOO\�JHW�D�IORRG�RI�ZDUQLQJ�PHVVDJHV��VR�LW¦V�EHWWHU�WR�XVH�LW�IURP�WKH�VWDUW�ZKHQ�LW¦V�QHHGHG�

0RVW�SHRSOH�UHFRPPHQG�WKDW�SURJUDPV�WKDW�DUH�ORQJHU�WKDQ�D�VFUHHQIXO�RI�WH[W�JHQHUDOO\QHHG�use strict��$QG�ZH�DJUHH�

)URP�KHUH�RQ��PRVW��EXW�QRW�DOO��RI�RXU�H[DPSOHV�ZLOO�EH�ZULWWHQ�DV�LI�use strict�LV�LQHIIHFW��HYHQ�ZKHUH�ZH�GRQ¦W�VKRZ�LW��7KDW�LV��ZH¦OO�JHQHUDOO\�GHFODUH�YDULDEOHV�ZLWK�myZKHUH�LW¦V�DSSURSULDWH��%XW��HYHQ�WKRXJK�ZH�GRQ¦W�DOZD\V�GR�VR�KHUH��ZH�HQFRXUDJH�\RXWR�LQFOXGH�use strict�LQ�\RXU�SURJUDPV�DV�RIWHQ�DV�SRVVLEOH�

The return Operator7KH�return�RSHUDWRU�LPPHGLDWHO\�UHWXUQV�D�YDOXH�IURP�D�VXEURXWLQH�

my @names = qw/ fred barney betty dino wilma pebbles bamm-bamm /;my $result = &which_element_is("dino", @names);

sub which_element_is { my($what, @array) = @_; foreach (0..$#array) { # indices of @array's elements if ($what eq $array[$_]) { return $_; # return early once found } } !1; # element not found (return is optional here)}

7KLV�VXEURXWLQH�LV�EHLQJ�XVHG�WR�ILQG�WKH�LQGH[�RI�"dino"�LQ�WKH�DUUD\�@names��)LUVW��WKHmy�GHFODUDWLRQ�QDPHV�WKH�SDUDPHWHUV��WKHUH¦V�$what��ZKLFK�LV�ZKDW�ZH¦UH�VHDUFKLQJ�IRU�DQG�@array��DQ�DUUD\�RI�YDOXHV�WR�VHDUFK�ZLWKLQ��7KDW¦V�D�FRS\�RI�WKH�DUUD\�@names��LQWKLV�FDVH��7KH�foreach�ORRS�VWHSV�WKURXJK�WKH�LQGLFHV�RI�@array��WKH�ILUVW�LQGH[�LV�0��DQGWKH�ODVW�RQH�LV�$#array��DV�\RX�VDZ�LQ�&KDSWHU����

(DFK�WLPH�WKURXJK�WKH�foreach� ORRS��ZH�FKHFN�WR�VHH�ZKHWKHU�WKH�VWULQJ�LQ�$what� LVHTXDO �WR�WKH�HOHPHQW�IURP�@array�DW�WKH�FXUUHQW�LQGH[��,I�LW¦V�HTXDO��ZH�UHWXUQ�WKDW�LQGH[DW�RQFH��7KLV�LV�WKH�PRVW�FRPPRQ�XVH�RI�WKH�NH\ZRUG�return�LQ�3HUO¢WR�UHWXUQ�D�YDOXHLPPHGLDWHO\��ZLWKRXW�H[HFXWLQJ�WKH�UHVW�RI�WKH�VXEURXWLQH�

%XW�ZKDW�LI�ZH�QHYHU�IRXQG�WKDW�HOHPHQW"�,Q�WKDW�FDVH��WKH�DXWKRU�RI�WKLV�VXEURXWLQH�KDVFKRVHQ�WR�UHWXUQ�!1�DV�D�£YDOXH�QRW�IRXQG¤�FRGH��,W�ZRXOG�EH�PRUH�3HUOLVK��SHUKDSV��WRUHWXUQ�undef�LQ�WKDW�FDVH��EXW�WKLV�SURJUDPPHU�XVHG�!1��6D\LQJ�return !1�RQ�WKDW�ODVWOLQH�ZRXOG�EH�FRUUHFW��EXW�WKH�ZRUG�return�LVQ¦W�UHDOO\�QHHGHG�

6RPH�SURJUDPPHUV�OLNH�WR�XVH�return�HYHU\�WLPH�WKHUH¦V�D�UHWXUQ�YDOXH��DV�D�PHDQV�RIGRFXPHQWLQJ�WKDW�LW� LV�D�UHWXUQ�YDOXH��)RU�H[DPSOH��\RX�PLJKW�XVH�return�ZKHQ�WKHUHWXUQ� YDOXH� LV� QRW� WKH� ODVW� OLQH� RI� WKH� VXEURXWLQH�� VXFK� DV� LQ� WKH� VXEURXWLQH

<RX�QRWLFHG�WKDW�ZH�XVHG�WKH�VWULQJ�HTXDOLW\�WHVW��eq��LQVWHDG�RI�WKH�QXPHULF�HTXDOLW\�WHVW��==��GLGQ¦W�\RX"

The return Operator | 65

&larger_of_fred_or_barney��HDUOLHU�LQ�WKLV�FKDSWHU��,W¦V�QRW�UHDOO\�QHHGHG��EXW�LW�GRHVQ¦WKXUW�DQ\WKLQJ��+RZHYHU��PDQ\�3HUO�SURJUDPPHUV�EHOLHYH�LW¦V�MXVW�DQ�H[WUD�VHYHQ�FKDU�DFWHUV�RI�W\SLQJ�

Omitting the Ampersand$V� SURPLVHG�� QRZ�ZH¦OO� WHOO� \RX� WKH� UXOH� IRU�ZKHQ� D� VXEURXWLQH� FDOO� FDQ� RPLW� WKHDPSHUVDQG��,I�WKH�FRPSLOHU�VHHV�WKH�VXEURXWLQH�GHILQLWLRQ�EHIRUH�LQYRFDWLRQ��RU�LI�3HUOFDQ�WHOO�IURP�WKH�V\QWD[�WKDW�LW¦V�D�VXEURXWLQH�FDOO��WKH�VXEURXWLQH�FDQ�EH�FDOOHG�ZLWKRXWDQ�DPSHUVDQG��MXVW�OLNH�D�EXLOW�LQ�IXQFWLRQ���%XW�WKHUH¦V�D�FDWFK�KLGGHQ�LQ�WKDW�UXOH��DV\RX¦OO�VHH�LQ�D�PRPHQW��

7KLV�PHDQV�WKDW�LI�3HUO�FDQ�VHH�WKDW�LW¦V�D�VXEURXWLQH�FDOO�ZLWKRXW�WKH�DPSHUVDQG��IURPWKH� V\QWD[� DORQH�� WKDW¦V� JHQHUDOO\� ILQH�� 7KDW� LV�� LI� \RX¦YH� JRW� WKH� SDUDPHWHU� OLVW� LQSDUHQWKHVHV��LW¦V�JRW�WR�EH�D�IXQFWLRQ �FDOO�

my @cards = shuffle(@deck_of_cards); # No & necessary on &shuffle

2U�LI�3HUO¦V�LQWHUQDO�FRPSLOHU�KDV�DOUHDG\�VHHQ�WKH�VXEURXWLQH�GHILQLWLRQ��WKDW¦V�JHQHUDOO\RND\��WRR��LQ�WKDW�FDVH��\RX�FDQ�HYHQ�RPLW�WKH�SDUHQWKHVHV�DURXQG�WKH�DUJXPHQW�OLVW�

sub division { $_[0] / $_[1]; # Divide first param by second}

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

7KLV�ZRUNV�EHFDXVH�RI�WKH�UXOH�WKDW�SDUHQWKHVHV�PD\�DOZD\V�EH�RPLWWHG��H[FHSW�ZKHQGRLQJ�VR�ZRXOG�FKDQJH�WKH�PHDQLQJ�RI�WKH�FRGH�

%XW�GRQ¦W�SXW�WKDW�VXEURXWLQH�GHFODUDWLRQ�DIWHU�WKH�LQYRFDWLRQ��RU�WKH�FRPSLOHU�ZRQ¦WNQRZ�ZKDW�WKH�DWWHPSWHG�LQYRFDWLRQ�RI�division�LV�DOO�DERXW��7KH�FRPSLOHU�KDV�WR�VHHWKH�GHILQLWLRQ�EHIRUH�WKH�LQYRFDWLRQ�LQ�RUGHU�WR�XVH�WKH�VXEURXWLQH�FDOO�DV�LI�LW�ZHUH�DEXLOW�LQ�

7KDW¦V�QRW�WKH�FDWFK��WKRXJK��7KH�FDWFK�LV�WKLV��LI�WKH�VXEURXWLQH�KDV�WKH�VDPH�QDPH�DVD�3HUO�EXLOW�LQ��\RX�PXVW�XVH�WKH�DPSHUVDQG�WR�FDOO�LW��:LWK�DQ�DPSHUVDQG��\RX¦UH�VXUHWR�FDOO�WKH�VXEURXWLQH��ZLWKRXW�LW��\RX�FDQ�JHW�WKH�VXEURXWLQH�RQO\�LI�WKHUH¦V�QR�EXLOW�LQZLWK�WKH�VDPH�QDPH�

sub chomp { print "Munch, munch!\n";}

&chomp; # That ampersand is not optional!

:LWKRXW�WKH�DPSHUVDQG��ZH¦G�EH�FDOOLQJ�WKH�EXLOW�LQ�chomp��HYHQ�WKRXJK�ZH¦YH�GHILQHGWKH�VXEURXWLQH�&chomp��6R��WKH�UHDO�UXOH�WR�XVH�LV�WKLV�RQH��XQWLO�\RX�NQRZ�WKH�QDPHV�RIDOO�RI�3HUO¦V�EXLOW�LQ�IXQFWLRQV��DOZD\V�XVH�WKH�DPSHUVDQG�RQ�IXQFWLRQ�FDOOV��7KDW�PHDQV

,Q�WKLV�FDVH��WKH�IXQFWLRQ�LV�WKH�VXEURXWLQH�&shuffle��%XW�LW�PD\�EH�D�EXLOW�LQ�IXQFWLRQ��DV�\RX¦OO�VHH�LQ�D�PRPHQW�

66 | Chapter 4:ಗSubroutines

WKDW�\RX�ZLOO�XVH�LW�IRU�\RXU�ILUVW�KXQGUHG�SURJUDPV�RU�VR��%XW�ZKHQ�\RX�VHH�VRPHRQHHOVH�KDV�RPLWWHG�WKH�DPSHUVDQG�LQ�KLV�RZQ�FRGH��LW¦V�QRW�QHFHVVDULO\�D�PLVWDNH��SHUKDSVKH�VLPSO\�NQRZV�WKDW�3HUO�KDV�QR�EXLOW�LQ�ZLWK�WKDW�QDPH� �:KHQ�SURJUDPPHUV�SODQ�WRFDOO�WKHLU�VXEURXWLQHV�DV�LI�WKH\�ZHUH�FDOOLQJ�3HUO¦V�EXLOW�LQV��XVXDOO\�ZKHQ�ZULWLQJ�PRG�XOHV�� WKH\�RIWHQ�XVH�SURWRW\SHV� WR� WHOO� 3HUO� DERXW� WKH�SDUDPHWHUV� WR� H[SHFW��0DNLQJPRGXOHV�LV�DQ�DGYDQFHG�WRSLF��WKRXJK��ZKHQ�\RX¦UH�UHDG\�IRU�WKDW��VHH�3HUO¦V�GRFX�PHQWDWLRQ��LQ�SDUWLFXODU��WKH�SHUOPRG�DQG�SHUOVXE�GRFXPHQWV��IRU�PRUH�LQIRUPDWLRQDERXW�VXEURXWLQH�SURWRW\SHV�DQG�PDNLQJ�PRGXOHV�

Nonscalar Return Values$�VFDODU� LVQ¦W� WKH�RQO\�NLQG�RI�UHWXUQ�YDOXH�D�VXEURXWLQH�PD\�KDYH�� ,I�\RX�FDOO�\RXUVXEURXWLQH�LQ�D�OLVW�FRQWH[W���LW�FDQ�UHWXUQ�D�OLVW�RI�YDOXHV�

6XSSRVH�\RX�ZDQWHG�WR�JHW�D�UDQJH�RI�QXPEHUV��DV�IURP�WKH�UDQJH�RSHUDWRU��..���H[FHSWWKDW�\RX�ZDQW�WR�EH�DEOH�WR�FRXQW�GRZQ�DV�ZHOO�DV�XS��7KH�UDQJH�RSHUDWRU�RQO\�FRXQWVXSZDUG��EXW�WKDW¦V�HDVLO\�IL[HG�

sub list_from_fred_to_barney { if ($fred < $barney) { # Count upwards from $fred to $barney $fred..$barney; } else { # Count downwards from $fred to $barney reverse $barney..$fred; }}$fred = 11;$barney = 6;@c = &list_from_fred_to_barney; # @c gets (11, 10, 9, 8, 7, 6)

,Q�WKLV�FDVH��WKH�UDQJH�RSHUDWRU�JLYHV�XV�WKH�OLVW�IURP�6�WR�11��WKHQ�reverse�UHYHUVHV�WKHOLVW�VR�WKDW�LW�JRHV�IURP�$fred��11��WR�$barney��6���MXVW�DV�ZH�ZDQWHG�

7KH� OHDVW� \RX�FDQ� UHWXUQ� LV�QRWKLQJ�DW� DOO��$�return�ZLWK�QR�DUJXPHQWV�ZLOO� UHWXUQundef�LQ�D�VFDODU�FRQWH[W�RU�DQ�HPSW\�OLVW�LQ�D�OLVW�FRQWH[W��7KLV�FDQ�EH�XVHIXO�IRU�DQ�HUURUUHWXUQ�IURP�D�VXEURXWLQH��VLJQDOLQJ�WR�WKH�FDOOHU�WKDW�D�PRUH�PHDQLQJIXO�UHWXUQ�YDOXH�LVXQDYDLODEOH�

7KHQ�DJDLQ��PD\EH�LW�LV�D�PLVWDNH��\RX�FDQ�VHDUFK�WKH�SHUOIXQF�DQG�SHUORS�PDQSDJHV�IRU�WKDW�QDPH��WKRXJK�WR�VHH�ZKHWKHU�LW¦V�WKH�VDPH�DV�D�EXLOW�LQ��$QG�3HUO�ZLOO�XVXDOO\�EH�DEOH�WR�ZDUQ�\RX�DERXW�WKLV�ZKHQ�\RX�KDYHZDUQLQJV�WXUQHG�RQ�

� <RX�FDQ�GHWHFW�ZKHWKHU�D�VXEURXWLQH�LV�EHLQJ�HYDOXDWHG�LQ�D�VFDODU�RU�OLVW�FRQWH[W�XVLQJ�WKH�wantarray�IXQFWLRQ�ZKLFK�OHWV�\RX�HDVLO\�ZULWH�VXEURXWLQHV�ZLWK�VSHFLILF�OLVW�RU�VFDODU�FRQWH[W�YDOXHV�

Nonscalar Return Values | 67

Persistent, Private Variables:LWK�my�ZH�ZHUH�DEOH�WR�PDNH�YDULDEOHV�SULYDWH�WR�D�VXEURXWLQH��DOWKRXJK�HDFK�WLPH�ZHFDOOHG�WKH�VXEURXWLQH�ZH�KDG�WR�GHILQH�WKHP�DJDLQ��:LWK�state��ZH�FDQ�VWLOO�KDYH�SULYDWHYDULDEOHV�VFRSHG�WR�WKH�VXEURXWLQH�EXW�3HUO�ZLOO�NHHS�WKHLU�YDOXHV�EHWZHHQ�FDOOV�

*RLQJ�EDFN�WR�RXU�ILUVW�H[DPSOH�LQ�WKLV�FKDSWHU��ZH�KDG�D�VXEURXWLQH�QDPHG�marine�WKDWLQFUHPHQWHG�D�YDULDEOH�

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

1RZ�WKDW�ZH�NQRZ�DERXW�strict��ZH�DGG�WKDW�WR�RXU�SURJUDP�DQG�UHDOL]H�WKDW�RXU�XVHRI�WKH�JOREDO�YDULDEOH�$n�LVQ¦W�DOORZHG�DQ\PRUH��:H�FDQ¦W�PDNH�$n�D�OH[LFDO�YDULDEOHZLWK�my�EHFDXVH�LW�ZRXOGQ¦W�UHWDLQ�LWV�YDOXH�

'HFODULQJ�RXU�YDULDEOH�ZLWK�state�WHOOV�3HUO�WR�UHWDLQ�WKH�YDULDEOH¦V�YDOXH�EHWZHHQ�FDOOVWR�WKH�VXEURXWLQH�DQG�WR�PDNH�WKH�YDULDEOH�SULYDWH�WR�WKH�VXEURXWLQH�

use 5.010;

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

1RZ�ZH�FDQ�JHW�WKH�VDPH�RXWSXW�ZKLOH�EHLQJ�strict�FOHDQ�DQG�QRW�XVLQJ�D�JOREDO�YDU�LDEOH��7KH�ILUVW�WLPH�ZH�FDOO�WKH�VXEURXWLQH��3HUO�GHFODUHV�DQG�LQLWLDOL]HV�$n��3HUO�LJQRUHVWKH�VWDWHPHQW�RQ�DOO�VXEVHTXHQW�FDOOV��%HWZHHQ�FDOOV��3HUO�UHWDLQV�WKH�YDOXH�RI�$n�IRU�WKHQH[W�FDOO�WR�WKH�VXEURXWLQH�

:H�FDQ�PDNH�DQ\�YDULDEOH�W\SH�D�state�YDULDEOH��LW¦V�QRW�MXVW�IRU�VFDODUV��+HUH¦V�D�VXE�URXWLQH�WKDW�UHPHPEHUV�LWV�DUJXPHQWV�DQG�SURYLGHV�D�UXQQLQJ�VXP�E\�XVLQJ�D�stateDUUD\�

use 5.010;

running_sum( 5, 6 );running_sum( 1..3 );running_sum( 4 );

sub running_sum { state $sum = 0; state @numbers;

foreach my $number ( @_ ) { push @numbers, $number; $sum += $number; }

68 | Chapter 4:ಗSubroutines

say "The sum of (@numbers) is $sum"; }

7KLV�RXWSXWV�D�QHZ�VXP�HDFK�WLPH�ZH�FDOO�LW��DGGLQJ�WKH�QHZ�DUJXPHQWV�WR�DOO�RI�WKHSUHYLRXV�RQHV�

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

7KHUH¦V�D�VOLJKW�UHVWULFWLRQ�RQ�DUUD\V�DQG�KDVKHV�DV�state�YDULDEOHV��WKRXJK��:H�FDQ¦WLQLWLDOL]H�WKHP�LQ�OLVW�FRQWH[W�DV�RI�3HUO������

state @array = qw(a b c); # Error!

7KLV�JLYHV�XV�DQ�HUURU�WKDW�KLQWV�WKDW�ZH�PLJKW�EH�DEOH�WR�GR�LW�LQ�D�IXWXUH�YHUVLRQ�RI�3HUO�

Initialization of state variables in list context currently forbidden ...

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >��@�:ULWH�D�VXEURXWLQH��QDPHG�total��WKDW�UHWXUQV�WKH�WRWDO�RI�D�OLVW�RI�QXPEHUV��+LQW�� WKH�VXEURXWLQH�VKRXOG�QRW�SHUIRUP�DQ\� ,�2�� LW� VKRXOG�VLPSO\�SURFHVV� LWVSDUDPHWHUV�DQG�UHWXUQ�D�YDOXH�WR�LWV�FDOOHU���7U\�LW�RXW�LQ�WKLV�VDPSOH�SURJUDP��ZKLFKPHUHO\�H[HUFLVHV�WKH�VXEURXWLQH�WR�VHH�WKDW�LW�ZRUNV��7KH�ILUVW�JURXS�RI�QXPEHUVVKRXOG�DGG�XS�WR����

my @fred = qw{ 1 3 5 7 9 };my $fred_total = total(@fred);print "The total of \@fred is $fred_total.\n";print "Enter some numbers on separate lines: ";my $user_total = total(<STDIN>);print "The total of those numbers is $user_total.\n";

�� >�@�8VLQJ�WKH�VXEURXWLQH�IURP�WKH�SUHYLRXV�SUREOHP��PDNH�D�SURJUDP�WR�FDOFXODWHWKH�VXP�RI�WKH�QXPEHUV�IURP���WR������

�� >��@�([WUD�FUHGLW�H[HUFLVH��ZULWH�D�VXEURXWLQH��FDOOHG�&above_average��WKDW�WDNHV�DOLVW�RI�QXPEHUV�DQG�UHWXUQV�WKH�RQHV�WKDW�DUH�DERYH�WKH�DYHUDJH��PHDQ����+LQW��PDNHDQRWKHU�VXEURXWLQH�WKDW�FDOFXODWHV�WKH�DYHUDJH�E\�GLYLGLQJ�WKH�WRWDO�E\�WKH�QXPEHURI�LWHPV���7U\�\RXU�VXEURXWLQH�LQ�WKLV�WHVW�SURJUDP�

my @fred = above_average(1..10);print "\@fred is @fred\n";print "(Should be 6 7 8 9 10)\n";my @barney = above_average(100, 1..10);print "\@barney is @barney\n";print "(Should be just 100)\n";

�� >��@�:ULWH�D�VXEURXWLQH��QDPHG�greet�� WKDW�ZHOFRPHV� WKH�SHUVRQ�\RX�QDPH�E\WHOOLQJ�WKHP�WKH�QDPH�RI�WKH�ODVW�SHUVRQ�LW�JUHHWHG�

Exercises | 69

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

7KLV�VHTXHQFH�RI�VWDWHPHQWV�VKRXOG�SULQW�

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

�� >��@�0RGLI\�WKH�SUHYLRXV�SURJUDP�WR�WHOO�HDFK�QHZ�SHUVRQ�WKH�QDPHV�RI�DOO�RI�WKHSHRSOH�LW�KDV�SUHYLRXVO\�JUHHWHG�

greet( "Fred" );greet( "Barney" );greet( "Wilma" );greet( "Betty" );

7KLV�VHTXHQFH�RI�VWDWHPHQWV�VKRXOG�SULQW�

Hi Fred! You are the first one here!Hi Barney! I've seen: FredHi Wilma! I've seen: Fred BarneyHi Betty! I've seen: Fred Barney Wilma

70 | Chapter 4:ಗSubroutines

CHAPTER 5

Input and Output

:H¦YH�DOUHDG\�VHHQ�KRZ�WR�GR�VRPH�LQSXW�RXWSXW��,�2��LQ�RUGHU�WR�PDNH�VRPH�RI�WKHHDUOLHU�H[HUFLVHV�SRVVLEOH��%XW�QRZ�ZH¦OO�OHDUQ�PRUH�DERXW�WKRVH�RSHUDWLRQV�E\�FRYHULQJWKH�����RI�WKH�,�2�\RX¦OO�QHHG�IRU�PRVW�SURJUDPV��,I�\RX¦UH�DOUHDG\�IDPLOLDU�ZLWK�WKHZRUNLQJV�RI�VWDQGDUG�LQSXW��RXWSXW��DQG�HUURU�VWUHDPV��\RX¦UH�DKHDG�RI�WKH�JDPH��,IQRW��ZH¦OO�JHW�\RX�FDXJKW�XS�E\�WKH�HQG�RI�WKLV�FKDSWHU��)RU�QRZ��MXVW�WKLQN�RI�£VWDQGDUGLQSXW¤�DV�EHLQJ�£WKH�NH\ERDUG�¤�DQG�£VWDQGDUG�RXWSXW¤�DV�EHLQJ�£WKH�GLVSOD\�VFUHHQ�¤

Input from Standard Input5HDGLQJ�IURP�WKH�VWDQGDUG�LQSXW�VWUHDP�LV�HDV\��:H¦YH�EHHQ�GRLQJ�LW�DOUHDG\�ZLWK�WKH<STDIN>�RSHUDWRU� �(YDOXDWLQJ�WKLV�RSHUDWRU�LQ�D�VFDODU�FRQWH[W�JLYHV�\RX�WKH�QH[W�OLQHRI�LQSXW�

$line = <STDIN>; # read the next linechomp($line); # and chomp it

chomp($line = <STDIN>); # same thing, more idiomatically

6LQFH�WKH�OLQH�LQSXW�RSHUDWRU�ZLOO�UHWXUQ�undef�ZKHQ�\RX�UHDFK�HQG�RI�ILOH��WKLV�LV�KDQG\IRU�GURSSLQJ�RXW�RI�ORRSV�

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

:KDW�ZH¦UH�FDOOLQJ�WKH�OLQH�LQSXW�RSHUDWRU�KHUH��<STDIN>��LV�DFWXDOO\�D�OLQH�LQSXW�RSHUDWRU��UHSUHVHQWHG�E\�WKHDQJOH�EUDFNHWV��DURXQG�D�ILOHKDQGOH��<RX¦OO�OHDUQ�DERXW�ILOHKDQGOHV�ODWHU�LQ�WKLV�FKDSWHU�

71

7KHUH¦V�D�ORW�JRLQJ�RQ�LQ�WKDW�ILUVW�OLQH��ZH¦UH�UHDGLQJ�WKH�LQSXW�LQWR�D�YDULDEOH��FKHFNLQJWKDW�LW¦V�GHILQHG��DQG�LI�LW�LV��PHDQLQJ�WKDW�ZH�KDYHQ¦W�UHDFKHG�WKH�HQG�RI�WKH�LQSXW�ZH¦UH�UXQQLQJ�WKH�ERG\�RI�WKH�while�ORRS��6R��LQVLGH�WKH�ERG\�RI�WKH�ORRS��ZH¦OO�VHH�HDFKOLQH��RQH�DIWHU�DQRWKHU��LQ�$line� �7KLV�LV�VRPHWKLQJ�\RX¦OO�ZDQW�WR�GR�IDLUO\�RIWHQ��VRQDWXUDOO\�3HUO�KDV�D�VKRUWFXW�IRU�LW��7KH�VKRUWFXW�ORRNV�OLNH�WKLV�

while (<STDIN>) { print "I saw $_";}

1RZ��WR�PDNH�WKLV�VKRUWFXW��/DUU\�FKRVH�VRPH�XVHOHVV�V\QWD[��7KDW�LV��WKLV�LV�OLWHUDOO\VD\LQJ��£5HDG�D�OLQH�RI�LQSXW��DQG�VHH�LI�LW¦V�WUXH���1RUPDOO\�LW�LV���$QG�LI�LW�LV�WUXH��HQWHUWKH�while�ORRS��EXW�WKURZ�DZD\�WKDW�OLQH�RI�LQSXW�¤�/DUU\�NQHZ�WKDW�LW�ZDV�D�XVHOHVV�WKLQJWR�GR��QRERG\�VKRXOG�HYHU�QHHG�WR�GR�WKDW�LQ�D�UHDO�3HUO�SURJUDP��6R��/DUU\�WRRN�WKLVXVHOHVV�V\QWD[�DQG�PDGH�LW�XVHIXO�

:KDW�WKLV�LV�DFWXDOO\�VD\LQJ�LV�WKDW�3HUO�VKRXOG�GR�WKH�VDPH�WKLQJ�DV�ZH�VDZ�LQ�RXU�HDUOLHUORRS��LW�WHOOV�3HUO�WR�UHDG�WKH�LQSXW�LQWR�D�YDULDEOH��DQG��DV�ORQJ�DV�WKH�UHVXOW�ZDV�GHILQHG�VR�ZH�KDYHQ¦W�UHDFKHG�HQG�RI�ILOH��WKHQ�HQWHU�WKH�while�ORRS��+RZHYHU��LQVWHDG�RI�VWRULQJWKH�LQSXW�LQWR�$line��3HUO�ZLOO�XVH�LWV�IDYRULWH�GHIDXOW�YDULDEOH��$_�� MXVW�DV� LI�\RX�KDGZULWWHQ�WKLV�

while (defined($_ = <STDIN>)) { print "I saw $_";}

1RZ��EHIRUH�ZH�JR�DQ\�IXUWKHU��ZH�PXVW�EH�YHU\�FOHDU�DERXW�VRPHWKLQJ��WKLV�VKRUWFXWZRUNV�RQO\�LI�\RX�ZULWH�LW�MXVW�DV�ZH�GLG��,I�\RX�SXW�D�OLQH�LQSXW�RSHUDWRU�DQ\ZKHUH�HOVH�LQ�SDUWLFXODU��DV�D�VWDWHPHQW�DOO�RQ�LWV�RZQ���LW�ZRQ¦W�UHDG�D�OLQH�LQWR�$_�E\�GHIDXOW��,WZRUNV�RQO\�LI�WKHUH¦V�QRWKLQJ�EXW�WKH�OLQH�LQSXW�RSHUDWRU�LQ�WKH�FRQGLWLRQDO�RI�D�whileORRS��� ,I�\RX�SXW�DQ\WKLQJ�HOVH� LQWR� WKH�FRQGLWLRQDO�H[SUHVVLRQ�� WKLV�VKRUWFXW�ZRQ¦WDSSO\�

7KHUH¦V�RWKHUZLVH�QR�FRQQHFWLRQ�EHWZHHQ�WKH�OLQH�LQSXW�RSHUDWRU��<STDIN>��DQG�3HUO¦VIDYRULWH�GHIDXOW�YDULDEOH��$_���,Q�WKLV�FDVH��WKRXJK��LW�MXVW�KDSSHQV�WKDW�WKH�LQSXW�LV�EHLQJVWRUHG�LQ�WKDW�YDULDEOH�

2Q�WKH�RWKHU�KDQG��HYDOXDWLQJ�WKH�OLQH�LQSXW�RSHUDWRU�LQ�D�OLVW�FRQWH[W�JLYHV�\RX�DOO�RIWKH��UHPDLQLQJ��OLQHV�RI�LQSXW�DV�D�OLVW¢HDFK�HOHPHQW�RI�WKH�OLVW�LV�RQH�OLQH�

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

<RX�SUREDEO\�QRWLFHG�WKDW�ZH�QHYHU�FKRPSHG�WKDW�LQSXW��,Q�WKLV�NLQG�RI�D�ORRS��\RX�FDQ¦W�UHDOO\�SXW�chompLQWR�WKH�FRQGLWLRQDO�H[SUHVVLRQ��VR� LW¦V�RIWHQ�WKH�ILUVW� LWHP�LQ�WKH� ORRS�ERG\��ZKHQ�LW¦V�QHHGHG��:H¦OO�VHHH[DPSOHV�RI�WKDW�LQ�WKH�QH[W�VHFWLRQ�

� :HOO��RND\��WKH�FRQGLWLRQDO�RI�D�for�ORRS�LV�MXVW�D�while�FRQGLWLRQDO�LQ�GLVJXLVH��VR�LW�ZRUNV�WKHUH��WRR�

72 | Chapter 5:ಗInput and Output

2QFH�DJDLQ��WKHUH¦V�QR�FRQQHFWLRQ�EHWZHHQ�WKH�OLQH�LQSXW�RSHUDWRU�DQG�3HUO¦V�IDYRULWHGHIDXOW�YDULDEOH��,Q�WKLV�FDVH��WKRXJK��WKH�GHIDXOW�FRQWURO�YDULDEOH�IRU�foreach�LV�$_��6RLQ�WKLV�ORRS��ZH¦OO�VHH�HDFK�OLQH�RI�LQSXW�LQ�$_��RQH�DIWHU�WKH�RWKHU�

7KDW�PD\�VRXQG�IDPLOLDU��DQG�IRU�JRRG�UHDVRQ��WKDW¦V�WKH�VDPH�EHKDYLRU�WKH�while�ORRSZRXOG�GR��,VQ¦W�LW"

7KH�GLIIHUHQFH�LV�XQGHU�WKH�KRRG��,Q�WKH�while�ORRS��3HUO�UHDGV�D�OLQH�RI�LQSXW��SXWV�LWLQWR�D�YDULDEOH��DQG�UXQV�WKH�ERG\�RI�WKH�ORRS��7KHQ��LW�JRHV�EDFN�WR�ILQG�DQRWKHU�OLQHRI�LQSXW��%XW�LQ�WKH�foreach�ORRS��WKH�OLQH�LQSXW�RSHUDWRU�LV�EHLQJ�XVHG�LQ�D�OLVW�FRQWH[W�VLQFH�foreach�QHHGV�D�OLVW�WR�LWHUDWH�WKURXJK���6R�LW�KDV�WR�UHDG�DOO�RI�WKH�LQSXW�EHIRUHWKH�ORRS�FDQ�VWDUW�UXQQLQJ��7KDW�GLIIHUHQFH�ZLOO�EHFRPH�DSSDUHQW�ZKHQ�WKH�LQSXW�LVFRPLQJ�IURP�\RXU�����0%�ZHE�VHUYHU�ORJILOH��,W¦V�JHQHUDOO\�EHVW�WR�XVH�FRGH�OLNH�WKHwhile�ORRS¦V�VKRUWFXW��ZKLFK�ZLOO�SURFHVV�LQSXW�D�OLQH�DW�D�WLPH��ZKHQHYHU�SRVVLEOH�

Input from the Diamond Operator$QRWKHU�ZD\�WR�UHDG�LQSXW�LV�ZLWK�WKH�GLDPRQG �RSHUDWRU��<>��7KLV�LV�XVHIXO�IRU�PDNLQJSURJUDPV�WKDW�ZRUN�OLNH�VWDQGDUG�8QL[��XWLOLWLHV��ZLWK�UHVSHFW�WR�WKH�LQYRFDWLRQ�DUJX�PHQWV��ZKLFK�ZH¦OO�VHH�LQ�D�PRPHQW���,I�\RX�ZDQW�WR�PDNH�D�3HUO�SURJUDP�WKDW�FDQ�EHXVHG�OLNH�WKH�XWLOLWLHV�FDW��VHG��DZN��VRUW��JUHS��OSU��DQG�PDQ\�RWKHUV��WKH�GLDPRQG�RS�HUDWRU�ZLOO�EH�\RXU�IULHQG��,I�\RX�ZDQW�WR�PDNH�DQ\WKLQJ�HOVH��WKH�GLDPRQG�RSHUDWRUSUREDEO\�ZRQ¦W�KHOS�

7KH�LQYRFDWLRQ�DUJXPHQWV�WR�D�SURJUDP�DUH�QRUPDOO\�D�QXPEHU�RI�£ZRUGV¤�RQ�WKH�FRP�PDQG�OLQH�DIWHU�WKH�QDPH�RI�WKH�SURJUDP�®�,Q�WKLV�FDVH��WKH\�JLYH�WKH�QDPHV�RI�WKH�ILOHV\RXU�SURJUDP�ZLOO�SURFHVV�LQ�VHTXHQFH�

$ ./my_program fred barney betty

7KDW�FRPPDQG�PHDQV�WR�UXQ�WKH�FRPPDQG�P\BSURJUDP��ZKLFK�ZLOO�EH�IRXQG�LQ�WKHFXUUHQW�GLUHFWRU\���DQG�WKDW�WKH�SURJUDP�VKRXOG�SURFHVV�ILOH�IUHG��IROORZHG�E\�ILOH�EDU�QH\��IROORZHG�E\�ILOH�EHWW\�

7KH�GLDPRQG�RSHUDWRU�ZDV�QDPHG�E\�/DUU\¦V�GDXJKWHU��+HLGL��ZKHQ�5DQGDO�ZHQW�RYHU�WR�/DUU\¦V�KRXVH�RQHGD\�WR�VKRZ�RII�WKH�QHZ�WUDLQLQJ�PDWHULDOV�KH¦G�EHHQ�ZULWLQJ�DQG�FRPSODLQHG�WKDW�WKHUH�ZDV�QR�VSRNHQ�QDPHIRU�£WKDW�WKLQJ�¤�/DUU\�GLGQ¦W�KDYH�D�QDPH�IRU�LW��HLWKHU��+HLGL��HLJKW�\HDUV�ROG�DW�WKH�WLPH��TXLFNO\�FKLPHG�LQ�£7KDW¦V�D�GLDPRQG��'DGG\�¤�6R�WKH�QDPH�VWXFN��7KDQNV��+HLGL�

� %XW�QRW�MXVW�RQ�8QL[�V\VWHPV��0DQ\�RWKHU�V\VWHPV�KDYH�DGRSWHG�WKLV�ZD\�RI�XVLQJ�LQYRFDWLRQ�DUJXPHQWV�

® :KHQHYHU�D�SURJUDP�LV�VWDUWHG��LW�KDV�D�OLVW�RI�]HUR�RU�PRUH�LQYRFDWLRQ�DUJXPHQWV��VXSSOLHG�E\�ZKDWHYHUSURJUDP�LV�VWDUWLQJ�LW��2IWHQ�WKLV�LV�WKH�VKHOO��ZKLFK�PDNHV�XS�WKH�OLVW�GHSHQGLQJ�XSRQ�ZKDW�\RX�W\SH�RQ�WKHFRPPDQG�OLQH��%XW�ZH¦OO�VHH�ODWHU�WKDW�\RX�FDQ�LQYRNH�D�SURJUDP�ZLWK�SUHWW\�PXFK�DQ\�VWULQJV�DV�WKH�LQYRFDWLRQDUJXPHQWV��%HFDXVH�WKH\�RIWHQ�FRPH�IURP�WKH�VKHOO¦V�FRPPDQG�OLQH��WKH\�DUH�VRPHWLPHV�FDOOHG�£FRPPDQG�OLQH�DUJXPHQWV¤�DV�ZHOO�

Input from the Diamond Operator | 73

,I�\RX�JLYH�QR�LQYRFDWLRQ�DUJXPHQWV��WKH�SURJUDP�VKRXOG�SURFHVV�WKH�VWDQGDUG�LQSXWVWUHDP��2U��DV�D�VSHFLDO�FDVH��LI�\RX�JLYH�MXVW�D�K\SKHQ�DV�RQH�RI�WKH�DUJXPHQWV��WKDWPHDQV� VWDQGDUG� LQSXW� DV� ZHOO� � 6R�� LI� WKH� LQYRFDWLRQ� DUJXPHQWV� KDG� EHHQ� fred -betty��WKDW�ZRXOG�KDYH�PHDQW�WKDW�WKH�SURJUDP�VKRXOG�SURFHVV�ILOH�IUHG��IROORZHG�E\WKH�VWDQGDUG�LQSXW�VWUHDP��IROORZHG�E\�ILOH�EHWW\�

7KH�EHQHILW�RI�PDNLQJ�\RXU�SURJUDPV�ZRUN�OLNH�WKLV�LV�WKDW�\RX�PD\�FKRRVH�ZKHUH�WKHSURJUDP�JHWV�LWV�LQSXW�DW�UXQWLPH��IRU�H[DPSOH��\RX�ZRQ¦W�KDYH�WR�UHZULWH�WKH�SURJUDPWR�XVH�LW�LQ�D�SLSHOLQH��ZKLFK�ZH¦OO�GLVFXVV�PRUH�ODWHU���/DUU\�SXW�WKLV�IHDWXUH�LQWR�3HUOEHFDXVH�KH�ZDQWHG�WR�PDNH�LW�HDV\�IRU�\RX�WR�ZULWH�\RXU�RZQ�SURJUDPV�WKDW�ZRUN�OLNHVWDQGDUG�8QL[�XWLOLWLHV¢HYHQ�RQ�QRQ�8QL[�PDFKLQHV��$FWXDOO\��KH�GLG�LW�VR�KH�FRXOGPDNH�KLV�RZQ�SURJUDPV�ZRUN�OLNH�VWDQGDUG�8QL[�XWLOLWLHV��VLQFH�VRPH�YHQGRUV¦�XWLOLWLHVGRQ¦W�ZRUN� MXVW� OLNH�RWKHUV¦��/DUU\� FRXOG�PDNH�KLV�RZQ�XWLOLWLHV��GHSOR\� WKHP�RQ�DQXPEHU�RI�PDFKLQHV��DQG�NQRZ�WKDW�WKH\¦G�DOO�KDYH�WKH�VDPH�EHKDYLRU��2I�FRXUVH��WKLVPHDQW�SRUWLQJ�3HUO�WR�HYHU\�PDFKLQH�KH�FRXOG�ILQG�

7KH�GLDPRQG�RSHUDWRU�LV�DFWXDOO\�D�VSHFLDO�NLQG�RI�OLQH�LQSXW�RSHUDWRU��%XW�LQVWHDG�RIJHWWLQJ�WKH�LQSXW�IURP�WKH�NH\ERDUG��LW�FRPHV�IURP�WKH�XVHU¦V�FKRLFH�RI�LQSXW��

while (defined($line = <>)) { chomp($line); print "It was $line that I saw!\n";}

6R��LI�ZH�UXQ�WKLV�SURJUDP�ZLWK�WKH�LQYRFDWLRQ�DUJXPHQWV�fred��barney��DQG�betty��LWZLOO�VD\�VRPHWKLQJ�OLNH��£,W�ZDV�>D�OLQH�IURP�ILOH�IUHG@�WKDW�,�VDZ�¤��£,W�ZDV�>DQRWKHU�OLQHIURP�ILOH�IUHG@�WKDW�,�VDZ�¤��RQ�DQG�RQ�XQWLO�LW�UHDFKHV�WKH�HQG�RI�ILOH�IUHG��7KHQ��LW�ZLOODXWRPDWLFDOO\�JR�RQ�WR�ILOH�EDUQH\��SULQWLQJ�RXW�RQH� OLQH�DIWHU�DQRWKHU��DQG�WKHQ�RQWKURXJK�ILOH�EHWW\��1RWH�WKDW�WKHUH¦V�QR�EUHDN�ZKHQ�ZH�JR�IURP�RQH�ILOH�WR�DQRWKHU�ZKHQ�\RX�XVH�WKH�GLDPRQG�� LW¦V�DV� LI� WKH� LQSXW� ILOHV�KDYH�EHHQ�PHUJHG� LQWR�RQH�ELJILOH�®�7KH�GLDPRQG�ZLOO�UHWXUQ�undef��DQG�ZH¦OO�GURS�RXW�RI�WKH�while�ORRS��RQO\�DW�WKHHQG�RI�DOO�RI�WKH�LQSXW�

,Q�IDFW��VLQFH�WKLV�LV� MXVW�D�VSHFLDO�NLQG�RI�OLQH�LQSXW�RSHUDWRU��ZH�PD\�XVH�WKH�VDPHVKRUWFXW�ZH�VDZ�HDUOLHU�WR�UHDG�WKH�LQSXW�LQWR�$_�E\�GHIDXOW�

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

+HUH¦V� D� SRVVLEO\� XQIDPLOLDU�8QL[� IDFW��PRVW� RI� WKRVH� VWDQGDUG� XWLOLWLHV�� OLNH� FDW� DQG� VHG�� XVH� WKLV� VDPHFRQYHQWLRQ��ZKHUH�D�K\SKHQ�VWDQGV�IRU�WKH�VWDQGDUG�LQSXW�VWUHDP�

� :KLFK�PD\�RU�PD\�QRW�LQFOXGH�JHWWLQJ�LQSXW�IURP�WKH�NH\ERDUG�

® ,I�LW�PDWWHUV�WR�\RX��RU�HYHQ�LI�LW�GRHVQ¦W��WKH�FXUUHQW�ILOH¦V�QDPH�LV�NHSW�LQ�3HUO¦V�VSHFLDO�YDULDEOH�$ARGV��7KLVQDPH�PD\�EH�"-"�LQVWHDG�RI�D�UHDO�ILOHQDPH�LI�WKH�LQSXW�LV�FRPLQJ�IURP�WKH�VWDQGDUG�LQSXW�VWUHDP��WKRXJK�

74 | Chapter 5:ಗInput and Output

7KLV�ZRUNV�OLNH�WKH�ORRS�DERYH��EXW�ZLWK�OHVV�W\SLQJ��$QG�\RX�PD\�KDYH�QRWLFHG�WKDWZH¦UH�XVLQJ�WKH�GHIDXOW�IRU�chomp��ZLWKRXW�DQ�DUJXPHQW��chomp�ZLOO�ZRUN�RQ�$_��(YHU\OLWWOH�ELW�RI�VDYHG�W\SLQJ�KHOSV�

6LQFH� WKH�GLDPRQG�RSHUDWRU� LV� JHQHUDOO\�EHLQJ�XVHG� WR�SURFHVV� DOO� RI� WKH� LQSXW�� LW¦VW\SLFDOO\�D�PLVWDNH�WR�XVH�LW�LQ�PRUH�WKDQ�RQH�SODFH�LQ�\RXU�SURJUDP��,I�\RX�ILQG�\RXUVHOISXWWLQJ�WZR�GLDPRQGV�LQWR�WKH�VDPH�SURJUDP��HVSHFLDOO\�XVLQJ�WKH�VHFRQG�GLDPRQGLQVLGH�WKH�while�ORRS�WKDW�LV�UHDGLQJ�IURP�WKH�ILUVW�RQH��LW¦V�DOPRVW�FHUWDLQO\�QRW�JRLQJWR�GR�ZKDW�\RX�ZRXOG�OLNH� �,Q�RXU�H[SHULHQFH��ZKHQ�EHJLQQHUV�SXW�D�VHFRQG�GLDPRQGLQWR� D� SURJUDP�� WKH\� PHDQW� WR� XVH� $_� LQVWHDG�� 5HPHPEHU�� WKH� GLDPRQG� RSHUDWRUUHDGV�WKH�LQSXW��EXW�WKH�LQSXW�LWVHOI�LV��JHQHUDOO\��E\�GHIDXOW��IRXQG�LQ�$_�

,I� WKH�GLDPRQG�RSHUDWRU� FDQ¦W� RSHQ�RQH�RI� WKH� ILOHV� DQG� UHDG� IURP� LW�� LW¦OO� SULQW� DQDOOHJHGO\�KHOSIXO�GLDJQRVWLF�PHVVDJH��VXFK�DV�

can't open wimla: No such file or directory

7KH�GLDPRQG�RSHUDWRU�ZLOO�WKHQ�JR�RQ�WR�WKH�QH[W�ILOH�DXWRPDWLFDOO\��PXFK�OLNH�ZKDW\RX¦G�H[SHFW�IURP�FDW�RU�DQRWKHU�VWDQGDUG�XWLOLW\�

The Invocation Arguments7HFKQLFDOO\��WKH�LQYRFDWLRQ�GLDPRQG�RSHUDWRU�LVQ¦W�OLWHUDOO\�ORRNLQJ�DW�WKH�LQYRFDWLRQDUJXPHQWV¢LW�ZRUNV�IURP�WKH�@ARGV�DUUD\��7KLV�DUUD\�LV�D�VSHFLDO�DUUD\�WKDW�LV�SUHVHWE\�WKH�3HUO�LQWHUSUHWHU�DV�WKH�OLVW�RI�WKH�LQYRFDWLRQ�DUJXPHQWV��,Q�RWKHU�ZRUGV��WKLV�LVMXVW�OLNH�DQ\�RWKHU�DUUD\���H[FHSW�IRU�LWV�IXQQ\��DOO�FDSV�QDPH���EXW�ZKHQ�\RXU�SURJUDPVWDUWV��@ARGV�LV�DOUHDG\�VWXIIHG�IXOO�RI�WKH�OLVW�RI�LQYRFDWLRQ�DUJXPHQWV��

<RX�FDQ�XVH�@ARGV�MXVW�OLNH�DQ\�RWKHU�DUUD\��\RX�FRXOG�shift�LWHPV�RII�RI�LW��SHUKDSV��RUXVH�foreach�WR�LWHUDWH�RYHU�LW��<RX�FRXOG�HYHQ�FKHFN�WR�VHH�LI�DQ\�DUJXPHQWV�VWDUW�ZLWKD�K\SKHQ��VR�WKDW�\RX�FRXOG�SURFHVV�WKHP�DV�LQYRFDWLRQ�RSWLRQV��OLNH�3HUO�GRHV�ZLWK�LWVRZQ�-w�RSWLRQ��®

7KH�GLDPRQG�RSHUDWRU�ORRNV�LQ�@ARGV�WR�GHWHUPLQH�ZKDW�ILOHQDPHV�LW�VKRXOG�XVH��,I�LWILQGV�DQ�HPSW\�OLVW��LW�XVHV�WKH�VWDQGDUG�LQSXW�VWUHDP��RWKHUZLVH�LW�XVHV�WKH�OLVW�RI�ILOHVWKDW�LW�ILQGV��7KLV�PHDQV�WKDW�DIWHU�\RXU�SURJUDP�VWDUWV�DQG�EHIRUH�\RX�VWDUW�XVLQJ�WKH

,I�\RX�UHLQLWLDOL]H�@ARGV�EHIRUH�XVLQJ�WKH�VHFRQG�GLDPRQG��WKHQ�\RX¦UH�RQ�VROLG�JURXQG��:H¦OO�VHH�@ARGV�LQ�WKHQH[W�VHFWLRQ�

� &�SURJUDPPHUV�PD\�EH�ZRQGHULQJ�DERXW�argc��WKHUH�LVQ¦W�RQH�LQ�3HUO���DQG�ZKDW�KDSSHQHG�WR�WKH�SURJUDP¦VRZQ�QDPH��WKDW¦V�IRXQG�LQ�3HUO¦V�VSHFLDO�YDULDEOH�$0��QRW�@ARGV���$OVR��GHSHQGLQJ�XSRQ�KRZ�\RX¦YH�LQYRNHG\RXU�SURJUDP��WKHUH�PD\�EH�D�OLWWOH�PRUH�KDSSHQLQJ�WKDQ�ZH�VD\�KHUH��6HH�WKH�SHUOUXQ�PDQSDJH�IRU�WKH�IXOOGHWDLOV�

® ,I�\RX�QHHG�PRUH�WKDQ�MXVW�RQH�RU�WZR�VXFK�RSWLRQV��\RX�VKRXOG�DOPRVW�FHUWDLQO\�XVH�D�PRGXOH�WR�SURFHVVWKHP�LQ�D�VWDQGDUG�ZD\��6HH�WKH�GRFXPHQWDWLRQ�IRU�WKH�Getopt::Long�DQG�Getopt::Std�PRGXOHV��ZKLFK�DUHSDUW�RI�WKH�VWDQGDUG�GLVWULEXWLRQ�

The Invocation Arguments | 75

GLDPRQG��\RX¦YH�JRW�D�FKDQFH�WR�WLQNHU�ZLWK�@ARGV��)RU�H[DPSOH��KHUH�ZH�FDQ�SURFHVVWKUHH�VSHFLILF�ILOHV��UHJDUGOHVV�RI�ZKDW�WKH�XVHU�FKRVH�RQ�WKH�FRPPDQG�OLQH�

@ARGV = qw# larry moe curly #; # force these three files to be readwhile (<>) { chomp; print "It was $_ that I saw in some stooge-like file!\n";}

Output to Standard Output7KH�print�RSHUDWRU�WDNHV�D�OLVW�RI�YDOXHV�DQG�VHQGV�HDFK�LWHP��DV�D�VWULQJ��RI�FRXUVH��WRVWDQGDUG�RXWSXW�LQ�WXUQ��RQH�DIWHU�DQRWKHU��,W�GRHVQ¦W�DGG�DQ\�H[WUD�FKDUDFWHUV�EHIRUH�DIWHU��RU�LQ�EHWZHHQ�WKH�LWHPV� �LI�\RX�ZDQW�VSDFHV�EHWZHHQ�LWHPV�DQG�D�QHZOLQH�DW�WKHHQG��\RX�KDYH�WR�VD\�VR�

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

2I�FRXUVH��WKDW�PHDQV�WKDW�WKHUH¦V�D�GLIIHUHQFH�EHWZHHQ�SULQWLQJ�DQ�DUUD\�DQG�LQWHUSR�ODWLQJ�DQ�DUUD\�

print @array; # print a list of itemsprint "@array"; # print a string (containing an interpolated array)

7KDW�ILUVW�print�VWDWHPHQW�ZLOO�SULQW�D�OLVW�RI�LWHPV��RQH�DIWHU�DQRWKHU��ZLWK�QR�VSDFHV�LQEHWZHHQ��7KH�VHFRQG�RQH�ZLOO�SULQW�H[DFWO\�RQH�LWHP��ZKLFK�LV�WKH�VWULQJ�\RX�JHW�E\LQWHUSRODWLQJ�@array� LQWR�WKH�HPSW\�VWULQJ¢WKDW� LV�� LW�SULQWV�WKH�FRQWHQWV�RI�@array�VHSDUDWHG�E\�VSDFHV���6R��LI�@array�KROGV�qw/ fred barney betty /�®�WKH�ILUVW�RQH�SULQWVfredbarneybetty��ZKLOH�WKH�VHFRQG�SULQWV�fred barney betty�VHSDUDWHG�E\�VSDFHV�

%XW�EHIRUH�\RX�GHFLGH�WR�DOZD\V�XVH�WKH�VHFRQG�IRUP��LPDJLQH�WKDW�@array�LV�D�OLVW�RIXQFKRPSHG�OLQHV�RI�LQSXW��7KDW�LV��LPDJLQH�WKDW�HDFK�RI�LWV�VWULQJV�KDV�D�WUDLOLQJ�QHZOLQHFKDUDFWHU��1RZ��WKH�ILUVW�print�VWDWHPHQW�SULQWV�fred��barney��DQG�betty�RQ�WKUHH�VHS�DUDWH�OLQHV��%XW�WKH�VHFRQG�RQH�SULQWV�WKLV�

fred barney betty

'R�\RX�VHH�ZKHUH�WKH�VSDFHV�FRPH�IURP"�3HUO�LV�LQWHUSRODWLQJ�DQ�DUUD\��VR�LW�SXWV�VSDFHVEHWZHHQ�WKH�HOHPHQWV��6R��ZH�JHW�WKH�ILUVW�HOHPHQW�RI�WKH�DUUD\��fred�DQG�D�QHZOLQHFKDUDFWHU��� WKHQ�D� VSDFH�� WKHQ� WKH�QH[W� HOHPHQW�RI� WKH� DUUD\� �barney� DQG�D�QHZOLQH

:HOO��LW�GRHVQ¦W�DGG�DQ\WKLQJ�H[WUD�E\�GHIDXOW��EXW�WKLV�GHIDXOW��OLNH�VR�PDQ\�RWKHUV�LQ�3HUO��PD\�EH�FKDQJHG�&KDQJLQJ�WKHVH�GHIDXOWV�ZLOO�OLNHO\�FRQIXVH�\RXU�PDLQWHQDQFH�SURJUDPPHU��WKRXJK��VR�DYRLG�GRLQJ�VR�H[FHSWLQ�VPDOO��TXLFN�DQG�GLUW\�SURJUDPV��RU��UDUHO\��LQ�D�VPDOO�VHFWLRQ�RI�D�QRUPDO�SURJUDP��6HH�WKH�SHUOYDU�PDQSDJHWR�OHDUQ�DERXW�FKDQJLQJ�WKH�GHIDXOWV�

� <HV��WKH�VSDFHV�DUH�DQRWKHU�GHIDXOW��VHH�WKH�SHUOYDU�PDQSDJH�DJDLQ�

® <RX�NQRZ�WKDW�ZH�PHDQ�D�WKUHH�HOHPHQW�OLVW�KHUH��ULJKW"�7KLV�LV�MXVW�3HUO�QRWDWLRQ�

76 | Chapter 5:ಗInput and Output

FKDUDFWHU���WKHQ�D�VSDFH��WKHQ�WKH�ODVW�HOHPHQW�RI�WKH�DUUD\��betty�DQG�D�QHZOLQH�FKDU�DFWHU���7KH�UHVXOW�LV�WKDW�WKH�OLQHV�VHHP�WR�KDYH�EHFRPH�LQGHQWHG��H[FHSW�IRU�WKH�ILUVWRQH��(YHU\�ZHHN�RU�WZR��D�PDLOLQJ�OLVW�RU�IRUXP�KDV�D�PHVVDJH�ZLWK�D�VXEMHFW�OLQH�VRPH�WKLQJ�OLNH�

3HUO�LQGHQWV�HYHU\WKLQJ�DIWHU�WKH�ILUVW�OLQH

:LWKRXW�HYHQ� UHDGLQJ� WKH�PHVVDJH��ZH�FDQ� LPPHGLDWHO\� VHH� WKDW� WKH�SURJUDP�XVHGGRXEOH�TXRWHV�DURXQG�DQ�DUUD\�FRQWDLQLQJ�XQFKRPSHG�VWULQJV��£'LG�\RX�SHUKDSV�SXWDQ�DUUD\�RI�XQFKRPSHG�VWULQJV�LQVLGH�GRXEOH�TXRWHV"¤�ZH�DVN��DQG�WKH�DQVZHU�LV�DOZD\V\HV�

*HQHUDOO\��LI�\RXU�VWULQJV�FRQWDLQ�QHZOLQHV��\RX�VLPSO\�ZDQW�WR�SULQW�WKHP��DIWHU�DOO�

print @array;

%XW�LI�WKH\�GRQ¦W�FRQWDLQ�QHZOLQHV��\RX¦OO�JHQHUDOO\�ZDQW�WR�DGG�RQH�DW�WKH�HQG�

print "@array\n";

6R��LI�\RX¦UH�XVLQJ�WKH�TXRWH�PDUNV��\RX¦OO�EH��JHQHUDOO\��DGGLQJ�WKH�\n�DW�WKH�HQG�RI�WKHVWULQJ�DQ\ZD\��WKLV�VKRXOG�KHOS�\RX�WR�UHPHPEHU�ZKLFK�LV�ZKLFK�

,W¦V�QRUPDO�IRU�\RXU�SURJUDP¦V�RXWSXW�WR�EH�EXIIHUHG��7KDW�LV��LQVWHDG�RI�VHQGLQJ�RXWHYHU\�OLWWOH�ELW�RI�RXWSXW�DW�RQFH��LW¦OO�EH�VDYHG�XQWLO�WKHUH¦V�HQRXJK�WR�ERWKHU�ZLWK��,I�IRU�H[DPSOH��\RX¦UH�JRLQJ�WR�VDYH�WKH�RXWSXW�WR�GLVN��LW¦V��UHODWLYHO\��VORZ�DQG�LQHIILFLHQWWR�VSLQ�WKH�GLVN�HYHU\�WLPH�ZH�DGG�RQH�RU�WZR�FKDUDFWHUV�WR�WKH�ILOH��*HQHUDOO\��WKHQ�WKH�RXWSXW�ZLOO�JR�LQWR�D�EXIIHU�WKDW�LV�IOXVKHG��WKDW�LV��DFWXDOO\�ZULWWHQ�WR�GLVN�RU�ZKHU�HYHU��RQO\�ZKHQ�WKH�EXIIHU�JHWV�IXOO�RU�ZKHQ�WKH�RXWSXW�LV�RWKHUZLVH�ILQLVKHG��VXFK�DVDW�WKH�HQG�RI�UXQWLPH���8VXDOO\��WKDW¦V�ZKDW�\RX�ZDQW�

%XW�LI�\RX��RU�D�SURJUDP��PD\�EH�ZDLWLQJ�LPSDWLHQWO\�IRU�WKH�RXWSXW��\RX�PD\�ZLVK�WRWDNH�WKDW�SHUIRUPDQFH�KLW�DQG�IOXVK�WKH�RXWSXW�EXIIHU�HDFK�WLPH�\RX�print��6HH�WKH�3HUOPDQSDJHV�IRU�PRUH�LQIRUPDWLRQ�RQ�FRQWUROOLQJ�EXIIHULQJ�LQ�WKDW�FDVH�

6LQFH�print�LV�ORRNLQJ�IRU�D�OLVW�RI�VWULQJV�WR�SULQW��LWV�DUJXPHQWV�DUH�HYDOXDWHG�LQ�OLVWFRQWH[W��6LQFH�WKH�GLDPRQG�RSHUDWRU��DV�D�VSHFLDO�NLQG�RI�OLQH�LQSXW�RSHUDWRU��ZLOO�UHWXUQD�OLVW�RI�OLQHV�LQ�D�OLVW�FRQWH[W��WKHVH�FDQ�ZRUN�ZHOO�WRJHWKHU�

print <>; # source code for 'cat'

print sort <>; # source code for 'sort'

Output to Standard Output | 77

:HOO��WR�EH�IDLU��WKH�VWDQGDUG�8QL[�FRPPDQGV�FDW�DQG�VRUW�GR�KDYH�VRPH�DGGLWLRQDOIXQFWLRQDOLW\�WKDW�WKHVH�UHSODFHPHQWV�ODFN��%XW�\RX�FDQ¦W�EHDW�WKHP�IRU�WKH�SULFH��<RXFDQ�QRZ�UHLPSOHPHQW�DOO�RI�\RXU�VWDQGDUG�8QL[�XWLOLWLHV�LQ�3HUO�DQG�SDLQOHVVO\�SRUW�WKHPWR�DQ\�PDFKLQH�WKDW�KDV�3HUO��ZKHWKHU�WKDW�PDFKLQH�LV�UXQQLQJ�8QL[�RU�QRW��$QG�\RXFDQ�EH�VXUH�WKDW�WKH�SURJUDPV�RQ�HYHU\�GLIIHUHQW�W\SH�RI�PDFKLQH�ZLOO�QHYHUWKHOHVV�KDYHWKH�VDPH�EHKDYLRU�

:KDW�PLJKW�QRW�EH�REYLRXV�LV�WKDW�print�KDV�RSWLRQDO�SDUHQWKHVHV��ZKLFK�FDQ�VRPH�WLPHV� FDXVH� FRQIXVLRQ��5HPHPEHU� WKH� UXOH� WKDW� SDUHQWKHVHV� LQ�3HUO�PD\� DOZD\V�EHRPLWWHG��H[FHSW�ZKHQ�GRLQJ�VR�ZRXOG�FKDQJH�WKH�PHDQLQJ�RI�D�VWDWHPHQW��6R��KHUH�DUHWZR�ZD\V�WR�SULQW�WKH�VDPH�WKLQJ�

print("Hello, world!\n");print "Hello, world!\n";

6R�IDU��VR�JRRG��%XW�DQRWKHU�UXOH�LQ�3HUO�LV�WKDW�LI�WKH�LQYRFDWLRQ�RI�print�ORRNV�OLNH�DIXQFWLRQ�FDOO��WKHQ�LW� LV�D�IXQFWLRQ�FDOO��,W¦V�D�VLPSOH�UXOH��EXW�ZKDW�GRHV�LW�PHDQ�IRUVRPHWKLQJ�WR�ORRN�OLNH�D�IXQFWLRQ�FDOO"

,Q� D� IXQFWLRQ� FDOO�� WKHUH¦V� D� IXQFWLRQ� QDPH� LPPHGLDWHO\�� IROORZHG� E\� SDUHQWKHVHVDURXQG�WKH�IXQFWLRQ¦V�DUJXPHQWV��OLNH�WKLV�

print (2+3);

7KDW�ORRNV�OLNH�D�IXQFWLRQ�FDOO��VR�LW�LV�D�IXQFWLRQ�FDOO��,W�SULQWV�5��EXW�WKHQ�LW�UHWXUQV�DYDOXH�OLNH�DQ\�RWKHU�IXQFWLRQ��7KH�UHWXUQ�YDOXH�RI�print�LV�D�WUXH�RU�IDOVH�YDOXH��LQGLFDWLQJWKH�VXFFHVV�RI�WKH�SULQW��,W�QHDUO\�DOZD\V�VXFFHHGV��XQOHVV�\RX�JHW�VRPH�,�2�HUURU��VRWKH�$result�LQ�WKH�IROORZLQJ�VWDWHPHQW�ZLOO�QRUPDOO\�EH�1�

$result = print("hello world!\n");

%XW�ZKDW�LI�\RX�XVHG�WKH�UHVXOW�LQ�VRPH�RWKHU�ZD\"�/HW¦V�VXSSRVH�\RX�GHFLGH�WR�PXOWLSO\WKH�UHWXUQ�YDOXH�WLPHV�IRXU�

print (2+3)*4; # Oops!

:KHQ�3HUO�VHHV�WKLV�OLQH�RI�FRGH��LW�SULQWV�5��MXVW�DV�\RX�DVNHG��7KHQ�LW�WDNHV�WKH�UHWXUQYDOXH�IURP�print��ZKLFK�LV�1��DQG�PXOWLSOLHV�WKDW�WLPHV�4��,W�WKHQ�WKURZV�DZD\�WKH�SURG�XFW��ZRQGHULQJ�ZK\�\RX�GLGQ¦W�WHOO�LW�WR�GR�VRPHWKLQJ�HOVH�ZLWK�LW��$QG�DW�WKLV�SRLQW�VRPHRQH�ORRNLQJ�RYHU�\RXU�VKRXOGHU�VD\V��£+H\��3HUO�FDQ¦W�GR�PDWK��7KDW�VKRXOG�KDYHSULQWHG�20��UDWKHU�WKDQ�5�¤

,Q�IDFW��WKH�337��3HUO�3RZHU�7RROV��SURMHFW��ZKRVH�JRDO�ZDV�WR�LPSOHPHQW�DOO�RI�WKH�FODVVLF�8QL[�XWLOLWLHV�LQ3HUO�� FRPSOHWHG�QHDUO\�DOO� WKH�XWLOLWLHV� �DQG�PRVW�RI� WKH�JDPHV���EXW�JRW�ERJJHG�GRZQ�ZKHQ� WKH\�JRW� WRUHLPSOHPHQWLQJ� WKH�VKHOO��7KH�337�SURMHFW�KDV�EHHQ�KHOSIXO�EHFDXVH� LW�KDV�PDGH� WKHVH�VWDQGDUG�XWLOLWLHVDYDLODEOH�RQ�PDQ\�QRQ�8QL[�PDFKLQHV�

� :H�VD\�£LPPHGLDWHO\¤�KHUH�EHFDXVH�3HUO�ZRQ¦W�SHUPLW�D�QHZOLQH�FKDUDFWHU�EHWZHHQ�WKH�IXQFWLRQ�QDPH�DQGWKH�RSHQLQJ�SDUHQWKHVLV�LQ�WKLV�NLQG�RI�IXQFWLRQ�FDOO��,I�WKHUH�LV�D�QHZOLQH�WKHUH��3HUO�VHHV�\RXU�FRGH�DV�PDNLQJD�OLVW�RSHUDWRU��UDWKHU�WKDQ�D�IXQFWLRQ�FDOO��7KLV�LV�WKH�NLQG�RI�SLGGOLQJ�WHFKQLFDO�GHWDLO�WKDW�ZH�PHQWLRQ�RQO\IRU�FRPSOHWHQHVV��,I�\RX¦UH�WHUPLQDOO\�FXULRXV��VHH�WKH�IXOO�VWRU\�LQ�WKH�PDQSDJHV�

78 | Chapter 5:ಗInput and Output

7KLV�LV�WKH�SUREOHP�ZLWK�WKH�RSWLRQDO�SDUHQWKHVHV��VRPHWLPHV�ZH�KXPDQV�IRUJHW�ZKHUHWKH�SDUHQWKHVHV�UHDOO\�EHORQJ��:KHQ�WKHUH�DUH�QR�SDUHQWKHVHV��print�LV�D�OLVW�RSHUDWRU�SULQWLQJ�DOO�RI�WKH�LWHPV�LQ�WKH�IROORZLQJ�OLVW��WKDW¦V�JHQHUDOO\�ZKDW�\RX¦G�H[SHFW��%XWZKHQ�WKH�ILUVW�WKLQJ�DIWHU�print�LV�D�OHIW�SDUHQWKHVLV��print�LV�D�IXQFWLRQ�FDOO��DQG�LW�ZLOOSULQW�RQO\�ZKDW¦V�IRXQG�LQVLGH�WKH�SDUHQWKHVHV��6LQFH�WKDW�OLQH�KDG�SDUHQWKHVHV��LW¦V�WKHVDPH�WR�3HUO�DV�LI�\RX¦G�VDLG�WKLV�

( print(2+3) ) * 4; # Oops!

)RUWXQDWHO\��3HUO�LWVHOI�FDQ�DOPRVW�DOZD\V�KHOS�\RX�ZLWK�WKLV��LI�\RX�DVN�IRU�ZDUQLQJV¢VR�XVH�-w��RU�use warnings��DW�OHDVW�GXULQJ�SURJUDP�GHYHORSPHQW�DQG�GHEXJJLQJ�

$FWXDOO\��WKLV�UXOH¢£,I�LW�ORRNV�OLNH�D�IXQFWLRQ�FDOO��LW�LV�D�IXQFWLRQ�FDOO¤¢DSSOLHV�WR�DOOOLVW�IXQFWLRQV �LQ�3HUO��QRW�MXVW�WR�print��,W¦V�MXVW�WKDW�\RX¦UH�PRVW�OLNHO\�WR�QRWLFH�LW�ZLWKprint��,I�print��RU�DQRWKHU�IXQFWLRQ�QDPH��LV�IROORZHG�E\�DQ�RSHQLQJ�SDUHQWKHVLV��PDNHVXUH�WKDW�WKH�FRUUHVSRQGLQJ�FORVLQJ�SDUHQWKHVLV�FRPHV�DIWHU�DOO�RI�WKH�DUJXPHQWV�WR�WKDWIXQFWLRQ�

Formatted Output with printf<RX�PD\�ZLVK�WR�KDYH�D�OLWWOH�PRUH�FRQWURO�ZLWK�\RXU�RXWSXW�WKDQ�print�SURYLGHV��,QIDFW��\RX�PD\�EH�DFFXVWRPHG�WR�WKH�IRUPDWWHG�RXWSXW�RI�&¦V�printf�IXQFWLRQ��)HDU�QRW¢3HUO�SURYLGHV�D�FRPSDUDEOH�RSHUDWLRQ�ZLWK�WKH�VDPH�QDPH�

7KH�printf�RSHUDWRU� WDNHV�D� IRUPDW�VWULQJ� IROORZHG�E\�D� OLVW�RI� WKLQJV� WR�SULQW��7KHIRUPDW��VWULQJ�LV�D�ILOO�LQ�WKH�EODQNV�WHPSODWH�VKRZLQJ�WKH�GHVLUHG�IRUP�RI�WKH�RXWSXW�

printf "Hello, %s; your password expires in %d days!\n", $user, $days_to_die;

7KH�IRUPDW�VWULQJ�KROGV�D�QXPEHU�RI�VR�FDOOHG�FRQYHUVLRQV��HDFK�FRQYHUVLRQ�EHJLQV�ZLWKD�SHUFHQW� VLJQ� �%�� DQG�HQGV�ZLWK�D� OHWWHU�� �$V�ZH¦OO� VHH� LQ�D�PRPHQW�� WKHUH�PD\�EHVLJQLILFDQW�H[WUD�FKDUDFWHUV�EHWZHHQ�WKHVH� WZR�V\PEROV���7KHUH�VKRXOG�EH� WKH�VDPHQXPEHU�RI�LWHPV�LQ�WKH�IROORZLQJ�OLVW�DV�WKHUH�DUH�FRQYHUVLRQV��LI�WKHVH�GRQ¦W�PDWFK�XS�LW�ZRQ¦W�ZRUN�FRUUHFWO\��,Q�WKH�H[DPSOH�DERYH��WKHUH�DUH�WZR�LWHPV�DQG�WZR�FRQYHUVLRQV�VR�WKH�RXWSXW�PLJKW�ORRN�VRPHWKLQJ�OLNH�WKLV�

Hello, merlyn; your password expires in 3 days!

7KHUH�DUH�PDQ\�SRVVLEOH�printf�FRQYHUVLRQV��VR�ZH¦OO�WDNH�WLPH�KHUH�WR�GHVFULEH�MXVW�WKHPRVW�FRPPRQ�RQHV��2I�FRXUVH��WKH�IXOO�GHWDLOV�DUH�DYDLODEOH�LQ�WKH�SHUOIXQF�PDQSDJH�

)XQFWLRQV�WKDW�WDNH�]HUR�RU�RQH�DUJXPHQWV�GRQ¦W�VXIIHU�IURP�WKLV�SUREOHP�

� +HUH��ZH¦UH�XVLQJ�£IRUPDW¤�LQ�WKH�JHQHULF�VHQVH��3HUO�KDV�D�UHSRUW�JHQHUDWLQJ�IHDWXUH�FDOOHG�£IRUPDWV¤�WKDW�ZHZRQ¦W�HYHQ�EH�PHQWLRQLQJ��H[FHSW�LQ�WKLV�IRRWQRWH��XQWLO�$SSHQGL[�%��DQG�WKHQ�RQO\�WR�VD\�WKDW�ZH�UHDOO\DUHQ¦W�JRLQJ�WR�WDON�DERXW�LW��6R��\RX¦UH�RQ�\RXU�RZQ�WKHUH��-XVW�ZDQWHG�WR�NHHS�\RX�IURP�JHWWLQJ�ORVW�

Formatted Output with printf | 79

7R�SULQW�D�QXPEHU�LQ�ZKDW¦V�JHQHUDOO\�D�JRRG�ZD\��XVH�%g� �ZKLFK�DXWRPDWLFDOO\�FKRRVHVIORDWLQJ�SRLQW��LQWHJHU��RU�HYHQ�H[SRQHQWLDO�QRWDWLRQ�DV�QHHGHG�

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

7KH�%d�IRUPDW�PHDQV�D�GHFLPDO��LQWHJHU��WUXQFDWHG�DV�QHHGHG�

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

1RWH�WKDW�WKLV� LV�WUXQFDWHG��QRW�URXQGHG��ZH¦OO�VHH�KRZ�WR�URXQG�RII�D�QXPEHU�LQ�DPRPHQW�

,Q�3HUO��printf�LV�PRVW�RIWHQ�XVHG�IRU�FROXPQDU�GDWD��VLQFH�PRVW�IRUPDWV�DFFHSW�D�ILHOGZLGWK��,I�WKH�GDWD�ZRQ¦W�ILW��WKH�ILHOG�ZLOO�JHQHUDOO\�EH�H[SDQGHG�DV�QHHGHG�

printf "%6d\n", 42; # output like ````42 (the ` symbol stands for a space)printf "%2d\n", 2e3 + 1.95; # 2001

7KH�%s�FRQYHUVLRQ�PHDQV�D�VWULQJ��VR�LW�HIIHFWLYHO\�LQWHUSRODWHV�WKH�JLYHQ�YDOXH�DV�D�VWULQJ�EXW�ZLWK�D�JLYHQ�ILHOG�ZLGWK�

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

$�QHJDWLYH�ILHOG�ZLGWK�LV�OHIW�MXVWLILHG��LQ�DQ\�RI�WKHVH�FRQYHUVLRQV��

printf "%-15s\n", "flintstone"; # looks like flintstone`````

7KH�%f�FRQYHUVLRQ��IORDWLQJ�SRLQW��URXQGV�RII�LWV�RXWSXW�DV�QHHGHG��DQG�HYHQ�OHWV�\RXUHTXHVW�D�FHUWDLQ�QXPEHU�RI�GLJLWV�DIWHU�WKH�GHFLPDO�SRLQW�

printf "%12f\n", 6 * 7 + 2/3; # looks like ```42.666667printf "%12.3f\n", 6 * 7 + 2/3; # looks like ``````42.667printf "%12.0f\n", 6 * 7 + 2/3; # looks like ``````````43

7R�SULQW�D�UHDO�SHUFHQW�VLJQ��XVH�%%��ZKLFK�LV�VSHFLDO�LQ�WKDW�LW�XVHV�QR�HOHPHQW�IURP�WKHOLVW�®

printf "Monthly interest rate: %.2f%%\n", 5.25/12; # the value looks like "0.44%"

£*HQHUDO¤�QXPHULF�FRQYHUVLRQ��2U�PD\EH�D�£*RRG�FRQYHUVLRQ�IRU�WKLV�QXPEHU¤�RU�£*XHVV�ZKDW�,�ZDQW�WKHRXWSXW�WR�ORRN�OLNH�¤

� 7KHUH¦V�DOVR�%x�IRU�KH[DGHFLPDO�DQG�%o�IRU�RFWDO�LI�\RX�QHHG�WKRVH��%XW�ZH�UHDOO\�VD\�£GHFLPDO¤�KHUH�DV�DPHPRU\�DLG��%d�IRU�GHFLPDO�LQWHJHU�

® 0D\EH�\RX�WKRXJKW�\RX�FRXOG�VLPSO\�SXW�D�EDFNVODVK�LQ�IURQW�RI�WKH�SHUFHQW�VLJQ��1LFH�WU\��EXW�QR��7KH�UHDVRQWKDW�ZRQ¦W�ZRUN�LV�WKDW�WKH�IRUPDW�LV�DQ�H[SUHVVLRQ��DQG�WKH�H[SUHVVLRQ�"\%"�PHDQV�WKH�RQH�FKDUDFWHU�VWULQJ'%'��(YHQ�LI�ZH�JRW�D�EDFNVODVK�LQWR�WKH�IRUPDW�VWULQJ��printf�ZRXOGQ¦W�NQRZ�ZKDW�WR�GR�ZLWK�LW��%HVLGHV��&SURJUDPPHUV�DUH�XVHG�WR�printf�ZRUNLQJ�OLNH�WKLV�

80 | Chapter 5:ಗInput and Output

Arrays and printf*HQHUDOO\��\RX�ZRQ¦W�XVH�DQ�DUUD\�DV�DQ�DUJXPHQW�WR�printf��7KDW¦V�EHFDXVH�DQ�DUUD\PD\�KROG�DQ\�QXPEHU�RI�LWHPV��DQG�D�JLYHQ�IRUPDW�VWULQJ�ZLOO�ZRUN�ZLWK�RQO\�D�FHUWDLQIL[HG�QXPEHU�RI�LWHPV��LI�WKHUH�DUH�WKUHH�FRQYHUVLRQV�LQ�WKH�IRUPDW��WKHUH�PXVW�EH�H[DFWO\WKUHH�LWHPV�

%XW�WKHUH¦V�QR�UHDVRQ�\RX�FDQ¦W�ZKLS�XS�D�IRUPDW�VWULQJ�RQ�WKH�IO\��VLQFH�LW�PD\�EH�DQ\H[SUHVVLRQ��7KLV�FDQ�EH�WULFN\�WR�JHW�ULJKW��WKRXJK��VR�LW�PD\�EH�KDQG\��HVSHFLDOO\�ZKHQGHEXJJLQJ��WR�VWRUH�WKH�IRUPDW�LQWR�D�YDULDEOH�

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

7KLV�XVHV�WKH�x�RSHUDWRU��ZKLFK�ZH�OHDUQHG�DERXW�LQ�&KDSWHU����WR�UHSOLFDWH�WKH�JLYHQVWULQJ�D�QXPEHU�RI�WLPHV�JLYHQ�E\�@items��ZKLFK�LV�EHLQJ�XVHG�LQ�D�VFDODU�FRQWH[W���,QWKLV�FDVH��WKDW¦V�3��VLQFH�WKHUH�DUH�WKUHH�LWHPV��VR�WKH�UHVXOWLQJ�IRUPDW�VWULQJ�LV�WKH�VDPHDV�LI�ZH�KDG�ZULWWHQ�LW�DV�The items are:\n%10s\n%10s\n%10s\n��$QG�WKH�RXWSXW�SULQWVHDFK�LWHP�RQ�LWV�RZQ�OLQH��ULJKW�MXVWLILHG�LQ�D����FKDUDFWHU�FROXPQ��XQGHU�D�KHDGLQJOLQH��3UHWW\�FRRO��KXK"�%XW�QRW�FRRO�HQRXJK�EHFDXVH�\RX�FDQ�HYHQ�FRPELQH�WKHVH�

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

1RWH�WKDW�KHUH�ZH�KDYH�@items�EHLQJ�XVHG�RQFH�LQ�D�VFDODU�FRQWH[W��WR�JHW�LWV�OHQJWK��DQGRQFH�LQ�D�OLVW�FRQWH[W��WR�JHW�LWV�FRQWHQWV��&RQWH[W�LV�LPSRUWDQW�

Filehandles$�ILOHKDQGOH�LV�WKH�QDPH�LQ�D�3HUO�SURJUDP�IRU�DQ�,�2�FRQQHFWLRQ�EHWZHHQ�\RXU�3HUOSURFHVV�DQG�WKH�RXWVLGH�ZRUOG��7KDW�LV��LW¦V�WKH�QDPH�RI�D�FRQQHFWLRQ��QRW�QHFHVVDULO\WKH�QDPH�RI�D�ILOH�

)LOHKDQGOHV�DUH�QDPHG�OLNH�RWKHU�3HUO�LGHQWLILHUV��ZLWK�OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV�EXW�WKH\�FDQ¦W�VWDUW�ZLWK�D�GLJLW���WKRXJK�VLQFH�WKH\�GRQ¦W�KDYH�DQ\�SUHIL[�FKDUDFWHU�WKH\PLJKW�EH�FRQIXVHG�ZLWK�SUHVHQW�RU�IXWXUH�UHVHUYHG�ZRUGV��RU�ZLWK�ODEHOV��ZKLFK�ZH�FRYHULQ�&KDSWHU�����2QFH�DJDLQ��DV�ZLWK�ODEHOV��WKH�UHFRPPHQGDWLRQ�IURP�/DUU\�LV�WKDW�\RXXVH�DOO�XSSHUFDVH�OHWWHUV�LQ�WKH�QDPH�RI�\RXU�ILOHKDQGOH¢QRW�RQO\�ZLOO�LW�VWDQG�RXW�EHWWHU�EXW�LW�ZLOO�DOVR�JXDUDQWHH�WKDW�\RXU�SURJUDP�ZRQ¦W�IDLO�ZKHQ�D�IXWXUH��ORZHUFDVH��UH�VHUYHG�ZRUG�LV�LQWURGXFHG�

Filehandles | 81

%XW�WKHUH�DUH�DOVR�VL[�VSHFLDO�ILOHKDQGOH�QDPHV�WKDW�3HUO�DOUHDG\�XVHV�IRU�LWV�RZQ�SXU�SRVHV��STDIN��STDOUT��STDERR��DATA��ARGV��DQG�ARGVOUT� �$OWKRXJK�\RX�PD\�FKRRVH�DQ\ILOHKDQGOH�QDPH�\RX¦G�OLNH��\RX�VKRXOGQ¦W�FKRRVH�RQH�RI�WKRVH�VL[�XQOHVV�\RX�LQWHQG�WRXVH�WKDW�RQH¦V�VSHFLDO�SURSHUWLHV��

0D\EH� \RX� UHFRJQL]HG� VRPH� RI� WKRVH� QDPHV� DOUHDG\��:KHQ� \RXU� SURJUDP� VWDUWV�STDIN�LV�WKH�ILOHKDQGOH�QDPLQJ�WKH�FRQQHFWLRQ�EHWZHHQ�WKH�3HUO�SURFHVV�DQG�ZKHUHYHUWKH�SURJUDP�VKRXOG�JHW�LWV�LQSXW��NQRZQ�DV�WKH�VWDQGDUG�LQSXW�VWUHDP��7KLV�LV�JHQHUDOO\WKH�XVHU¦V�NH\ERDUG�XQOHVV�WKH�XVHU�DVNHG�IRU�VRPHWKLQJ�HOVH�WR�EH�WKH�VRXUFH�RI�LQSXW�VXFK� DV� D� ILOH� RU� WKH� RXWSXW� RI� DQRWKHU� SURJUDP� WKURXJK� D� SLSH�®�7KHUH¦V� DOVR� WKHVWDQGDUG�RXWSXW�VWUHDP��ZKLFK�LV�STDOUT��%\�GHIDXOW��WKLV�RQH�JRHV�WR�WKH�XVHU¦V�GLVSOD\VFUHHQ��EXW�WKH�XVHU�PD\�VHQG�WKH�RXWSXW�WR�D�ILOH�RU�WR�DQRWKHU�SURJUDP��DV�ZH¦OO�VHHVKRUWO\��7KHVH�VWDQGDUG�VWUHDPV�FRPH�WR�XV�IURP�WKH�8QL[�£VWDQGDUG�,�2¤�OLEUDU\��EXWWKH\�ZRUN�LQ�PXFK�WKH�VDPH�ZD\�RQ�PRVW�PRGHUQ�RSHUDWLQJ�V\VWHPV��7KH�JHQHUDO�LGHDLV�WKDW�\RXU�SURJUDP�VKRXOG�EOLQGO\�UHDG�IURP�STDIN�DQG�EOLQGO\�ZULWH�WR�STDOUT��WUXVWLQJLQ�WKH�XVHU��RU�JHQHUDOO\�ZKLFKHYHU�SURJUDP�LV�VWDUWLQJ�\RXU�SURJUDP��WR�KDYH�VHW�WKRVHXS��,Q�WKDW�ZD\��WKH�XVHU�FDQ�W\SH�D�FRPPDQG�OLNH�WKLV�RQH�DW�WKH�VKHOO�SURPSW�

$ ./your_program <dino >wilma

7KDW�FRPPDQG�WHOOV�WKH�VKHOO�WKDW�WKH�SURJUDP¦V�LQSXW�VKRXOG�EH�UHDG�IURP�WKH�ILOHGLQR��DQG�WKH�RXWSXW�VKRXOG�JR�WR�WKH�ILOH�ZLOPD��$V�ORQJ�DV�WKH�SURJUDP�EOLQGO\�UHDGVLWV� LQSXW� IURP�STDIN��SURFHVVHV� LW� �LQ�ZKDWHYHU�ZD\�ZH�QHHG���DQG�EOLQGO\�ZULWHV� LWVRXWSXW�WR�STDOUT��WKLV�ZLOO�ZRUN�MXVW�ILQH�

$QG�DW�QR�H[WUD�FKDUJH��WKH�SURJUDP�ZLOO�ZRUN�LQ�D�SLSHOLQH��7KLV�LV�DQRWKHU�FRQFHSWIURP�8QL[��ZKLFK�OHWV�XV�ZULWH�FRPPDQG�OLQHV�OLNH�WKLV�RQH�

$ cat fred barney | sort | ./your_program | grep something | lpr

1RZ��LI�\RX¦UH�QRW�IDPLOLDU�ZLWK�WKHVH�8QL[�FRPPDQGV��WKDW¦V�RND\��7KLV�OLQH�VD\V�WKDWWKH�FDW�FRPPDQG�VKRXOG�SULQW�RXW�DOO�RI�WKH�OLQHV�RI�ILOH�IUHG�IROORZHG�E\�DOO�RI�WKH�OLQHVRI�ILOH�EDUQH\��7KHQ�WKDW�RXWSXW�VKRXOG�EH�WKH�LQSXW�RI�WKH�VRUW�FRPPDQG��ZKLFK�VRUWVWKRVH� OLQHV� DQG� SDVVHV� WKHP�RQ� WR� \RXUBSURJUDP�� $IWHU� LW� KDV� GRQH� LWV� SURFHVVLQJ�\RXUBSURJUDP�ZLOO�VHQG�WKH�GDWD�RQ�WR�JUHS��ZKLFK�GLVFDUGV�FHUWDLQ�OLQHV�LQ�WKH�GDWD�

6RPH�SHRSOH�KDWH�W\SLQJ�LQ�DOO�FDSV��HYHQ�IRU�D�PRPHQW��DQG�ZLOO�WU\�VSHOOLQJ�WKHVH�LQ�ORZHUFDVH��OLNH�stdin�3HUO�PD\�HYHQ�OHW�\RX�JHW�DZD\�ZLWK�WKDW�IURP�WLPH�WR�WLPH��EXW�QRW�DOZD\V��7KH�GHWDLOV�RI�ZKHQ�WKHVH�ZRUNDQG�ZKHQ�WKH\�IDLO�DUH�EH\RQG�WKH�VFRSH�RI�WKLV�ERRN��%XW�WKH�LPSRUWDQW�WKLQJ�LV�WKDW�SURJUDPV�WKDW�UHO\�XSRQWKLV�NLQGQHVV�ZLOO�RQH�GD\�EUHDN��VR�LW�LV�EHVW�WR�DYRLG�ORZHUFDVH�KHUH�

� ,Q�VRPH�FDVHV��\RX�FRXOG��UH�XVH�WKHVH�QDPHV�ZLWKRXW�D�SUREOHP��%XW�\RXU�PDLQWHQDQFH�SURJUDPPHU�PD\WKLQN�WKDW�\RX¦UH�XVLQJ�WKH�QDPH�IRU�LWV�EXLOW�LQ�IHDWXUHV��DQG�WKXV�PD\�EH�FRQIXVHG�

® 7KH�GHIDXOWV�ZH�VSHDN�RI�LQ�WKLV�FKDSWHU�IRU�WKH�WKUHH�PDLQ�,�2�VWUHDPV�DUH�ZKDW�WKH�8QL[�VKHOOV�GR�E\�GHIDXOW�%XW�LW¦V�QRW�MXVW�VKHOOV�WKDW�ODXQFK�SURJUDPV��RI�FRXUVH��:H¦OO�VHH�LQ�&KDSWHU����ZKDW�KDSSHQV�ZKHQ�\RXODXQFK�DQRWKHU�SURJUDP�IURP�3HUO�

,I�\RX¦UH�QRW�DOUHDG\�IDPLOLDU�ZLWK�KRZ�\RXU�QRQ�8QL[�V\VWHP�SURYLGHV�VWDQGDUG�LQSXW�DQG�RXWSXW��VHH�WKHSHUOSRUW�PDQSDJH�DQG�WKH�GRFXPHQWDWLRQ�IRU�WKDW�V\VWHP¦V�HTXLYDOHQW�WR�WKH�8QL[�VKHOO��WKH�SURJUDP�WKDWUXQV�SURJUDPV�EDVHG�XSRQ�\RXU�NH\ERDUG�LQSXW��

82 | Chapter 5:ಗInput and Output

VHQGLQJ�WKH�RWKHUV�RQ�WR�WKH�OSU�FRPPDQG��ZKLFK�VKRXOG�SULQW�HYHU\WKLQJ�WKDW�LW�JHWVRQ�D�SULQWHU��:KHZ�

3LSHOLQHV�OLNH�WKDW�DUH�FRPPRQ�LQ�8QL[�DQG�PDQ\�RWKHU�V\VWHPV�WRGD\�EHFDXVH�WKH\�OHW\RX�EXLOG�SRZHUIXO��FRPSOH[�FRPPDQGV�RXW�RI�VLPSOH��VWDQGDUG�EXLOGLQJ�EORFNV��(DFKEXLOGLQJ�EORFN�GRHV�RQH�WKLQJ�YHU\�ZHOO��DQG�LW¦V�\RXU�MRE�WR�XVH�WKHP�WRJHWKHU�LQ�WKHULJKW�ZD\�

7KHUH¦V�RQH�PRUH�VWDQGDUG�,�2�VWUHDP��,I��LQ�WKH�SUHYLRXV�H[DPSOH��\RXUBSURJUDP�KDGWR�HPLW�DQ\�ZDUQLQJV�RU�RWKHU�GLDJQRVWLF�PHVVDJHV��WKRVH�VKRXOGQ¦W�JR�GRZQ�WKH�SLSH�OLQH��7KH�JUHS�FRPPDQG�LV�VHW�WR�GLVFDUG�DQ\WKLQJ�WKDW�LW�KDVQ¦W�VSHFLILFDOO\�EHHQ�WROGWR� ORRN� IRU��DQG�VR� LW�ZLOO�PRVW� OLNHO\�GLVFDUG� WKH�ZDUQLQJV��(YHQ� LI� LW�GLG�NHHS� WKHZDUQLQJV��\RX�SUREDEO\�GRQ¦W�ZDQW�WR�SDVV�WKHP�GRZQVWUHDP�WR�WKH�RWKHU�SURJUDPVLQ�WKH�SLSHOLQH��6R�WKDW¦V�ZK\�WKHUH¦V�DOVR�WKH�VWDQGDUG�HUURU�VWUHDP��STDERR��(YHQ�LI�WKHVWDQGDUG�RXWSXW�LV�JRLQJ�WR�DQRWKHU�SURJUDP�RU�ILOH��WKH�HUURUV�ZLOO�JR�WR�ZKHUHYHU�WKHXVHU�GHVLUHV��%\�GHIDXOW��WKH�HUURUV�ZLOO�JHQHUDOO\�JR�WR�WKH�XVHU¦V�GLVSOD\�VFUHHQ� �EXWWKH�XVHU�PD\�VHQG�WKH�HUURUV�WR�D�ILOH�ZLWK�D�VKHOO�FRPPDQG�OLNH�WKLV�RQH�

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

Opening a Filehandle6R�\RX¦YH�VHHQ�WKDW�3HUO�SURYLGHV�WKUHH�ILOHKDQGOHV¢STDIN��STDOUT��DQG�STDERR¢ZKLFKDUH�DXWRPDWLFDOO\�RSHQ�WR�ILOHV�RU�GHYLFHV�HVWDEOLVKHG�E\�WKH�SURJUDP¦V�SDUHQW�SURFHVV�SUREDEO\�WKH�VKHOO���:KHQ�\RX�QHHG�RWKHU�ILOHKDQGOHV��XVH�WKH�open�RSHUDWRU�WR�WHOO�3HUOWR�DVN�WKH�RSHUDWLQJ�V\VWHP�WR�RSHQ�WKH�FRQQHFWLRQ�EHWZHHQ�\RXU�SURJUDP�DQG�WKHRXWVLGH�ZRUOG��+HUH�DUH�VRPH�H[DPSOHV�

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

$OVR��JHQHUDOO\��HUURUV�DUHQ¦W�EXIIHUHG��7KDW�PHDQV�WKDW�LI�WKH�VWDQGDUG�HUURU�DQG�VWDQGDUG�RXWSXW�VWUHDPV�DUHERWK�JRLQJ�WR�WKH�VDPH�SODFH��VXFK�DV�WKH�PRQLWRU���WKH�HUURUV�PD\�DSSHDU�HDUOLHU�WKDQ�WKH�QRUPDO�RXWSXW�)RU�H[DPSOH��LI�\RXU�SURJUDP�SULQWV�D�OLQH�RI�RUGLQDU\�WH[W��WKHQ�WULHV�WR�GLYLGH�E\�]HUR��WKH�RXWSXW�PD\�VKRZWKH�PHVVDJH�DERXW�GLYLGLQJ�E\�]HUR�ILUVW��DQG�WKH�RUGLQDU\�WH[W�VHFRQG�

Opening a Filehandle | 83

7KH�ILUVW�RQH�RSHQV�D�ILOHKDQGOH�FDOOHG�CONFIG�WR�D�ILOH�FDOOHG�GLQR��7KDW�LV��WKH��H[LVWLQJ�ILOH�GLQR�ZLOO�EH�RSHQHG�DQG�ZKDWHYHU�LW�KROGV�ZLOO�FRPH�LQWR�RXU�SURJUDP�WKURXJK�WKHILOHKDQGOH�QDPHG�CONFIG��7KLV�LV�VLPLODU�WR�WKH�ZD\�WKDW�GDWD�IURP�D�ILOH�FRXOG�FRPH�LQWKURXJK�STDIN�LI�WKH�FRPPDQG�OLQH�KDG�D�VKHOO�UHGLUHFWLRQ�OLNH�<dino��,Q�IDFW��WKH�VHFRQGH[DPSOH�XVHV�H[DFWO\�WKDW�VHTXHQFH��7KH�VHFRQG�GRHV�WKH�VDPH�DV�WKH�ILUVW��EXW�WKH�OHVV�WKDQ�VLJQ�H[SOLFLWO\�VD\V�£XVH�WKLV�ILOHQDPH�IRU�LQSXW�¤�HYHQ�WKRXJK�WKDW¦V�WKH�GHIDXOW�

$OWKRXJK�\RX�GRQ¦W�KDYH�WR�XVH�WKH�OHVV�WKDQ�VLJQ�WR�RSHQ�D�ILOH�IRU�LQSXW��ZH�LQFOXGHWKDW�EHFDXVH��DV�\RX�FDQ�VHH�LQ�WKH�WKLUG�H[DPSOH��D�JUHDWHU�WKDQ�VLJQ�PHDQV�WR�FUHDWHD�QHZ� ILOH� IRU�RXWSXW��7KLV�RSHQV� WKH� ILOHKDQGOH�BEDROCK� IRU�RXWSXW� WR� WKH�QHZ� ILOHIUHG��-XVW�DV�ZKHQ�WKH�JUHDWHU�WKDQ�VLJQ�LV�XVHG�LQ�VKHOO�UHGLUHFWLRQ��ZH¦UH�VHQGLQJ�WKHRXWSXW�WR�D�QHZ�ILOH�FDOOHG�IUHG��,I�WKHUH¦V�DOUHDG\�D�ILOH�RI�WKDW�QDPH��ZH¦UH�DVNLQJ�WRZLSH�LW�RXW�DQG�UHSODFH�LW�ZLWK�WKLV�QHZ�RQH�

7KH�IRXUWK�H[DPSOH�VKRZV�KRZ�WZR�JUHDWHU�WKDQ�VLJQV�PD\�EH�XVHG��DJDLQ��DV�WKH�VKHOOGRHV��WR�RSHQ�D�ILOH�IRU�DSSHQGLQJ��7KDW�LV��LI�WKH�ILOH�DOUHDG\�H[LVWV��ZH�ZLOO�DGG�QHZGDWD�DW�WKH�HQG��,I�LW�GRHVQ¦W�H[LVW��LW�ZLOO�EH�FUHDWHG�LQ�PXFK�WKH�VDPH�ZD\�DV�LI�ZH�KDGXVHG�MXVW�RQH�JUHDWHU�WKDQ�VLJQ��7KLV�LV�KDQG\�IRU�ORJILOHV��\RXU�SURJUDP�FRXOG�ZULWH�DIHZ�OLQHV�WR�WKH�HQG�RI�D�ORJILOH�HDFK�WLPH�LW¦V�UXQ��6R�WKDW¦V�ZK\�WKH�IRXUWK�H[DPSOHQDPHV�WKH�ILOHKDQGOH�LOG�DQG�WKH�ILOH�ORJILOH�

<RX�FDQ�XVH�DQ\�VFDODU�H[SUHVVLRQ�LQ�SODFH�RI�WKH�ILOHQDPH�VSHFLILHU��DOWKRXJK�W\SLFDOO\\RX¦OO�ZDQW�WR�EH�H[SOLFLW�DERXW�WKH�GLUHFWLRQ�VSHFLILFDWLRQ�

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

1RWH�WKH�VSDFH�DIWHU�WKH�JUHDWHU�WKDQ��3HUO�LJQRUHV�WKLV���EXW�LW�NHHSV�XQH[SHFWHG�WKLQJVIURP�KDSSHQLQJ�LI�$selected_output�ZHUH�">passwd"�IRU�H[DPSOH��ZKLFK�ZRXOG�PDNHDQ�DSSHQG�LQVWHDG�RI�D�ZULWH��

,Q�PRGHUQ�YHUVLRQV�RI�3HUO��VWDUWLQJ�ZLWK�3HUO�������\RX�FDQ�XVH�D�£WKUHH�DUJXPHQW¤�open�

open CONFIG, "<", "dino";open BEDROCK, ">", $file_name;open LOG, ">>", &logfile_name();

7KLV�PD\�EH�LPSRUWDQW�IRU�VHFXULW\�UHDVRQV��$V�ZH¦OO�VHH�LQ�D�PRPHQW��DQG�LQ�IXUWKHU�GHWDLO�LQ�&KDSWHU�����WKHUH�DUH�D�QXPEHU�RI�PDJLFDO�FKDUDFWHUV�WKDW�PD\�EH�XVHG�LQ�ILOHQDPHV��,I�$name�KROGV�D�XVHU�FKRVHQ�ILOHQDPH�VLPSO\�RSHQLQJ�$name�ZLOO�DOORZ�DQ\�RI�WKHVH�PDJLFDO�FKDUDFWHUV�WR�FRPH�LQWR�SOD\��7KLV�FRXOG�EH�D�FRQYHQLHQFHWR�WKH�XVHU��RU�LW�FRXOG�EH�D�VHFXULW\�KROH��%XW�RSHQLQJ�"< $name"�LV�PXFK�VDIHU��VLQFH�LW�H[SOLFLWO\�VD\V�WR�RSHQWKH�JLYHQ�QDPH�IRU�LQSXW��6WLOO��WKLV�GRHVQ¦W�SUHYHQW�DOO�SRVVLEOH�PLVFKLHI��)RU�PRUH�LQIRUPDWLRQ�RQ�GLIIHUHQWZD\V�RI�RSHQLQJ�ILOHV��HVSHFLDOO\�ZKHQ�VHFXULW\�PD\�EH�D�FRQFHUQ��VHH�WKH�SHUORSHQWXW�PDQSDJH�

� <HV��WKLV�PHDQV�WKDW�LI�\RXU�ILOHQDPH�ZHUH�WR�KDYH�OHDGLQJ�ZKLWHVSDFH��WKDW�ZRXOG�DOVR�EH�LJQRUHG�E\�3HUO�6HH�SHUOIXQF�DQG�SHUORSHQWXW�LI�\RX¦UH�ZRUULHG�DERXW�WKLV�

84 | Chapter 5:ಗInput and Output

7KH�DGYDQWDJH�KHUH�LV�WKDW�3HUO�QHYHU�FRQIXVHV�WKH�PRGH��WKH�VHFRQG�DUJXPHQW��ZLWKVRPH� SDUW� RI� WKH� ILOHQDPH� �WKH� WKLUG� DUJXPHQW��� ZKLFK� KDV� QLFH� DGYDQWDJHV� IRUVHFXULW\� �+RZHYHU��LI�\RX�QHHG�\RXU�3HUO�WR�EH�EDFNZDUG�FRPSDWLEOH�ZLWK�ROGHU�3HUOYHUVLRQV��VXFK�DV�ZKHQ�\RX�DUH�FRQWULEXWLQJ�WR�WKH�&3$1���HLWKHU�DYRLG�WKHVH�IRUPV�RU�PDUN�\RXU�3HUO�VRXUFHV�DV�EHLQJ�FRPSDWLEOH�RQO\�ZLWK�QHZHU�3HUOV��

:H¦OO�VHH�KRZ�WR�XVH�WKHVH�ILOHKDQGOHV�ODWHU�LQ�WKLV�FKDSWHU��%XW�ILUVW�

Bad Filehandles3HUO�FDQ¦W�DFWXDOO\�RSHQ�D�ILOH�DOO�E\�LWVHOI��/LNH�DQ\�RWKHU�SURJUDPPLQJ�ODQJXDJH��3HUOFDQ�PHUHO\�DVN�WKH�RSHUDWLQJ�V\VWHP�WR�OHW�XV�RSHQ�D�ILOH��2I�FRXUVH��WKH�RSHUDWLQJ�V\VWHPPD\�UHIXVH�EHFDXVH�RI�SHUPLVVLRQ�VHWWLQJV��DQ�LQFRUUHFW�ILOHQDPH��RU�RWKHU�UHDVRQV�

,I�\RX�WU\�WR�UHDG�IURP�D�EDG�ILOHKDQGOH��WKDW�LV��D�ILOHKDQGOH�WKDW�LVQ¦W�SURSHUO\�RSHQ��\RX¦OO�VHH�DQ�LPPHGLDWH�HQG�RI�ILOH���:LWK�WKH�,�2�PHWKRGV�ZH¦OO�VHH�LQ�WKLV�FKDSWHU�HQG�RI�ILOH�ZLOO�EH�LQGLFDWHG�E\�undef�LQ�D�VFDODU�FRQWH[W�RU�DQ�HPSW\�OLVW�LQ�D�OLVW�FRQWH[W��,I�\RX�WU\�WR�ZULWH�WR�D�EDG�ILOHKDQGOH��WKH�GDWD�LV�VLOHQWO\�GLVFDUGHG�

)RUWXQDWHO\��WKHVH�GLUH�FRQVHTXHQFHV�DUH�HDV\�WR�DYRLG��)LUVW�RI�DOO��LI�ZH�DVN�IRU�ZDUQLQJVZLWK�-w�RU�WKH�warnings�SUDJPD��3HUO�ZLOO�JHQHUDOO\�EH�DEOH�WR�WHOO�XV�ZLWK�D�ZDUQLQJZKHQ�LW�VHHV�WKDW�ZH¦UH�XVLQJ�D�EDG�ILOHKDQGOH��%XW�HYHQ�EHIRUH�WKDW��open�DOZD\V�WHOOVXV�LI�LW�VXFFHHGHG�RU�IDLOHG��E\�UHWXUQLQJ�WUXH�IRU�VXFFHVV�RU�IDOVH�IRU�IDLOXUH��6R�\RX�FRXOGZULWH�FRGH�OLNH�WKLV�

my $success = open LOG, ">>logfile"; # capture the return valueif ( ! $success) { # The open failed ...}

:HOO��\RX�FRXOG�GR�LW�OLNH�WKDW��EXW�WKHUH¦V�DQRWKHU�ZD\�WKDW�ZH¦OO�VHH�LQ�WKH�QH[W�VHFWLRQ�

Closing a Filehandle:KHQ�\RX�DUH�ILQLVKHG�ZLWK�D�ILOHKDQGOH��\RX�PD\�FORVH�LW�ZLWK�WKH�close�RSHUDWRU�OLNHWKLV�

close BEDROCK;

&ORVLQJ�D�ILOHKDQGOH�WHOOV�3HUO�WR�LQIRUP�WKH�RSHUDWLQJ�V\VWHP�WKDW�ZH¦UH�DOO�GRQH�ZLWKWKH�JLYHQ�GDWD�VWUHDP��VR�DQ\�ODVW�RXWSXW�GDWD�VKRXOG�EH�ZULWWHQ�WR�GLVN�LQ�FDVH�VRPHRQH

7KH�GLVDGYDQWDJH�IRU�VHFXULW\�LV�WKDW��SUHVXPDEO\��\RX¦UH�OHWWLQJ�D�SRVVLEO\�PDOLFLRXV�XVHU�LQMHFW�SRVVLEO\�PDOLFLRXV�FKDUDFWHUV� LQWR� WKH�GHOLFDWH�ZRUNLQJV�RI�\RXU� LQQRFHQW�SURJUDP��2QFH�ZH� OHDUQ�DERXW� UHJXODUH[SUHVVLRQV��VWDUWLQJ�LQ�&KDSWHU����\RX¦OO�EH�DEOH�WR�XVH�WKRVH�WR�HQIRUFH�VRPH�VDQLW\�FKHFNV�RQ�XVHU�LQSXW�$QG�LI�\RXU�SURJUDP�ZLOO�KDYH�SRVVLEO\�PDOLFLRXV�XVHUV��UHDG�XS�RQ�3HUO¦V�KHOSIXO�VHFXULW\�IHDWXUHV�LQ�WKH$OSDFD�ERRN��LQ�WKH�SHUOVHF�PDQSDJH��RU�ERWK�

� 9LD�use 5.6��IRU�H[DPSOH�

Opening a Filehandle | 85

LV�ZDLWLQJ�IRU�LW� �3HUO�ZLOO�DXWRPDWLFDOO\�FORVH�D�ILOHKDQGOH�LI�\RX�UHRSHQ�LW��WKDW�LV��LI�\RXUHXVH�WKH�ILOHKDQGOH�QDPH�LQ�D�QHZ�open��RU�LI�\RX�H[LW�WKH�SURJUDP��

%HFDXVH�RI�WKLV��PDQ\�VLPSOH�3HUO�SURJUDPV�GRQ¦W�ERWKHU�ZLWK�close��%XW�LW¦V�WKHUH�LI\RX�ZDQW�WR�EH�WLG\��ZLWK�RQH�close�IRU�HYHU\�open��,Q�JHQHUDO��LW¦V�EHVW�WR�FORVH�HDFKILOHKDQGOH�VRRQ�DIWHU�\RX¦UH�GRQH�ZLWK�LW��WKRXJK�WKH�HQG�RI�WKH�SURJUDP�RIWHQ�DUULYHVVRRQ�HQRXJK�®

Fatal Errors with die/HW¦V�VWHS�DVLGH� IRU�D�PRPHQW��:H�QHHG�VRPH�VWXII� WKDW� LVQ¦W�GLUHFWO\�UHODWHG�WR��RUOLPLWHG�WR��,�2��EXW�LV�PRUH�DERXW�JHWWLQJ�RXW�RI�D�SURJUDP�HDUOLHU�WKDQ�QRUPDO�

:KHQ�D�IDWDO�HUURU�KDSSHQV�LQVLGH�3HUO��IRU�H[DPSOH��LI�\RX�GLYLGH�E\�]HUR��XVH�DQ�LQYDOLGUHJXODU�H[SUHVVLRQ��RU�FDOO�D�VXEURXWLQH�WKDW�KDVQ¦W�EHHQ�GHFODUHG���\RXU�SURJUDP�VWRSVZLWK�DQ�HUURU�PHVVDJH�WHOOLQJ�ZK\��%XW�WKLV�IXQFWLRQDOLW\�LV�DYDLODEOH�WR�XV�ZLWK�WKHdie�IXQFWLRQ��VR�ZH�FDQ�PDNH�RXU�RZQ�IDWDO�HUURUV�

7KH�die�IXQFWLRQ�SULQWV�RXW�WKH�PHVVDJH�\RX�JLYH�LW��WR�WKH�VWDQGDUG�HUURU�VWUHDP��ZKHUHVXFK�PHVVDJHV�VKRXOG�JR��DQG�PDNHV�VXUH�WKDW�\RXU�SURJUDP�H[LWV�ZLWK�D�QRQ]HUR�H[LWVWDWXV�

<RX�PD\�QRW�KDYH�NQRZQ�LW��EXW�HYHU\�SURJUDP�WKDW�UXQV�RQ�8QL[��DQG�PDQ\�RWKHUPRGHUQ�RSHUDWLQJ�V\VWHPV��KDV�DQ�H[LW�VWDWXV��WHOOLQJ�ZKHWKHU�LW�ZDV�VXFFHVVIXO�RU�QRW�3URJUDPV�WKDW�UXQ�RWKHU�SURJUDPV��OLNH�WKH�PDNH�XWLOLW\�SURJUDP��ORRN�DW�WKDW�H[LW�VWDWXVWR�VHH�WKDW�HYHU\WKLQJ�KDSSHQHG�FRUUHFWO\��7KH�H[LW�VWDWXV�LV�MXVW�D�VLQJOH�E\WH��VR�LW�FDQ¦WVD\�PXFK��WUDGLWLRQDOO\��LW�LV���IRU�VXFFHVV�DQG�D�QRQ]HUR�YDOXH�IRU�IDLOXUH��3HUKDSV��PHDQV�D�V\QWD[�HUURU�LQ�WKH�FRPPDQG�DUJXPHQWV��ZKLOH���PHDQV�WKDW�VRPHWKLQJ�ZHQWZURQJ�GXULQJ�SURFHVVLQJ��DQG���PHDQV�WKH�FRQILJXUDWLRQ�ILOH�FRXOGQ¦W�EH�IRXQG��WKHGHWDLOV� GLIIHU� IURP�RQH� FRPPDQG� WR� WKH� QH[W�� %XW� �� DOZD\V�PHDQV� WKDW� HYHU\WKLQJ

,I�\RX�NQRZ�PXFK�DERXW�,�2�V\VWHPV��\RX¦OO�NQRZ�WKHUH¦V�PRUH�WR�WKH�VWRU\��*HQHUDOO\��WKRXJK��ZKHQ�DILOHKDQGOH�LV�FORVHG��KHUH¦V�ZKDW�KDSSHQV��,I�WKHUH¦V�LQSXW�UHPDLQLQJ�LQ�D�ILOH��LW¦V�LJQRUHG��,I�WKHUH¦V�LQSXWUHPDLQLQJ�LQ�D�SLSHOLQH��WKH�ZULWLQJ�SURJUDP�PD\�JHW�D�VLJQDO�WKDW�WKH�SLSHOLQH�LV�FORVHG��,I�WKHUH¦V�RXWSXWJRLQJ�WR�D�ILOH�RU�SLSHOLQH��WKH�EXIIHU�LV�IOXVKHG��WKDW�LV��SHQGLQJ�RXWSXW�LV�VHQW�RQ�LWV�ZD\���,I�WKH�ILOHKDQGOHKDG�D�ORFN��WKH�ORFN�LV�UHOHDVHG��6HH�\RXU�V\VWHP¦V�,�2�GRFXPHQWDWLRQ�IRU�IXUWKHU�GHWDLOV�

� $Q\�H[LW�IURP�WKH�SURJUDP�ZLOO�FORVH�DOO�ILOHKDQGOHV��EXW�LI�3HUO�LWVHOI�EUHDNV��SHQGLQJ�RXWSXW�EXIIHUV�ZRQ¦WJHW�IOXVKHG��7KDW�LV�WR�VD\��LI�\RX�DFFLGHQWDOO\�FUDVK�\RXU�SURJUDP�E\�GLYLGLQJ�E\�]HUR��IRU�H[DPSOH��3HUO�LWVHOILV�VWLOO�UXQQLQJ��3HUO�ZLOO�HQVXUH�WKDW�GDWD�\RX¦YH�ZULWWHQ�DFWXDOO\�JHWV�RXWSXW�LQ�WKDW�FDVH��%XW�LI�3HUO�LWVHOIFDQ¦W�UXQ��EHFDXVH�\RX�UDQ�RXW�RI�PHPRU\�RU�FDXJKW�DQ�XQH[SHFWHG�VLJQDO���WKH�ODVW�IHZ�SLHFHV�RI�RXWSXW�PD\QRW�EH�ZULWWHQ�WR�GLVN��8VXDOO\��WKLV�LVQ¦W�D�ELJ�LVVXH�

® &ORVLQJ�D�ILOHKDQGOH�ZLOO�IOXVK�DQ\�RXWSXW�EXIIHUV�DQG�UHOHDVH�DQ\�ORFNV�RQ�WKH�ILOH��6LQFH�VRPHRQH�HOVH�PD\EH�ZDLWLQJ�IRU�WKRVH�WKLQJV��D�ORQJ�UXQQLQJ�SURJUDP�VKRXOG�JHQHUDOO\�FORVH�HDFK�ILOHKDQGOH�DV�VRRQ�DV�SRVVLEOH�%XW�PDQ\�RI�RXU�SURJUDPV�ZLOO�WDNH�RQO\�RQH�RU�WZR�VHFRQGV�WR�UXQ�WR�FRPSOHWLRQ��VR�WKLV�PD\�QRW�PDWWHU�&ORVLQJ�D�ILOHKDQGOH�DOVR�UHOHDVHV�SRVVLEO\�OLPLWHG�UHVRXUFHV��VR�LW¦V�PRUH�WKDQ�MXVW�EHLQJ�WLG\�

:HOO��LW�GRHV�WKLV�E\�GHIDXOW��EXW�HUURUV�PD\�EH�WUDSSHG�ZLWK�DQ�eval�EORFN��DV�ZH¦OO�VHH�LQ�&KDSWHU����

86 | Chapter 5:ಗInput and Output

ZRUNHG��:KHQ�WKH�H[LW�VWDWXV�VKRZV�IDLOXUH��D�SURJUDP�OLNH�PDNH�NQRZV�QRW�WR�JR�RQWR�WKH�QH[W�VWHS�

6R�ZH�FRXOG�UHZULWH�WKH�SUHYLRXV�H[DPSOH��SHUKDSV�OLNH�WKLV�

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

,I�WKH�open�IDLOV��die�ZLOO�WHUPLQDWH�WKH�SURJUDP�DQG�WHOO�\RX�WKDW�LW�FDQQRW�FUHDWH�WKHORJILOH��%XW�ZKDW¦V�WKDW�$!�LQ�WKH�PHVVDJH"�7KDW¦V�WKH�KXPDQ�UHDGDEOH�FRPSODLQW�IURPWKH�V\VWHP��,Q�JHQHUDO��ZKHQ�WKH�V\VWHP�UHIXVHV�WR�GR�VRPHWKLQJ�ZH¦YH�UHTXHVWHG��OLNHRSHQLQJ�D� ILOH���$!�ZLOO�JLYH�\RX�D�UHDVRQ��SHUKDSV�£SHUPLVVLRQ�GHQLHG¤�RU�£ILOH�QRWIRXQG�¤�LQ�WKLV�FDVH���7KLV�LV�WKH�VWULQJ�WKDW�\RX�PD\�KDYH�REWDLQHG�ZLWK�perror�LQ�&�RUD�VLPLODU�ODQJXDJH��7KLV�KXPDQ�UHDGDEOH�FRPSODLQW�PHVVDJH�ZLOO�EH�DYDLODEOH�LQ�3HUO¦VVSHFLDO�YDULDEOH�$!� �,W¦V�D�JRRG�LGHD�WR�LQFOXGH�$!�LQ�WKH�PHVVDJH�ZKHQ�LW�FRXOG�KHOS�WKHXVHU�WR�ILJXUH�RXW�ZKDW�KH�RU�VKH�GLG�ZURQJ��%XW�LI�\RX�XVH�die�WR�LQGLFDWH�DQ�HUURU�WKDWLV�QRW�WKH�IDLOXUH�RI�D�V\VWHP�UHTXHVW��GRQ¦W�LQFOXGH�$!��VLQFH�LW�ZLOO�JHQHUDOO\�KROG�DQXQUHODWHG�PHVVDJH�OHIW�RYHU�IURP�VRPHWKLQJ�3HUO�GLG�LQWHUQDOO\��,W�ZLOO�KROG�D�XVHIXOYDOXH�RQO\�LPPHGLDWHO\�DIWHU�D�IDLOHG�V\VWHP�UHTXHVW��$�VXFFHVVIXO�UHTXHVW�ZRQ¦W�OHDYHDQ\WKLQJ�XVHIXO�WKHUH�

7KHUH¦V�RQH�PRUH�WKLQJ�WKDW�die�ZLOO�GR�IRU�\RX��LW�ZLOO�DXWRPDWLFDOO\�DSSHQG�WKH�3HUOSURJUDP�QDPH�DQG�OLQH�QXPEHU��WR�WKH�HQG�RI�WKH�PHVVDJH��VR�\RX�FDQ�HDVLO\�LGHQWLI\ZKLFK�die�LQ�\RXU�SURJUDP�LV�UHVSRQVLEOH�IRU�WKH�XQWLPHO\�H[LW��7KH�HUURU�PHVVDJH�IURPWKH�SUHYLRXV�FRGH�PLJKW�ORRN�OLNH�WKLV��LI�$!�FRQWDLQHG�WKH�PHVVDJH�permission denied�

Cannot create logfile: permission denied at your_program line 1234.

7KDW¦V�SUHWW\�KHOSIXO¢LQ�IDFW��ZH�DOZD\V�VHHP�WR�ZDQW�PRUH�LQIRUPDWLRQ�LQ�RXU�HUURUPHVVDJHV�WKDQ�ZH�LQFOXGHG�WKH�ILUVW�WLPH�DURXQG��,I�\RX�GRQ¦W�ZDQW�WKH�OLQH�QXPEHUDQG�ILOH�UHYHDOHG��PDNH�VXUH�WKDW�WKH�G\LQJ�ZRUGV�KDYH�D�QHZOLQH�RQ�WKH�HQG��7KDW�LV�DQRWKHU�ZD\�\RX�FRXOG�XVH�die�LV�ZLWK�D�WUDLOLQJ�QHZOLQH�RQ�WKH�PHVVDJH�

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

2Q�VRPH�QRQ�8QL[�RSHUDWLQJ�V\VWHPV��$!�PD\�VD\�VRPHWKLQJ�OLNH�error number 7��OHDYLQJ�LW�XS�WR�WKH�XVHUWR�ORRN�WKDW�RQH�XS�LQ�WKH�GRFXPHQWDWLRQ��2Q�:LQGRZV�DQG�906��WKH�YDULDEOH�$^E�PD\�KDYH�DGGLWLRQDOGLDJQRVWLF�LQIRUPDWLRQ�

� ,I�WKH�HUURU�KDSSHQHG�ZKLOH�UHDGLQJ�IURP�D�ILOH��WKH�HUURU�PHVVDJH�ZLOO�LQFOXGH�WKH�£FKXQN�QXPEHU¤��XVXDOO\WKH�OLQH�QXPEHU��IURP�WKH�ILOH�DQG�WKH�QDPH�RI�WKH�ILOHKDQGOH�DV�ZHOO��VLQFH�WKRVH�DUH�RIWHQ�XVHIXO�LQ�WUDFNLQJGRZQ�D�EXJ�

Fatal Errors with die | 87

,I�WKHUH�DUHQ¦W�DW�OHDVW�WZR�FRPPDQG�OLQH�DUJXPHQWV��WKH�SURJUDP�ZLOO�VD\�VR�DQG�TXLW�,W�ZRQ¦W�LQFOXGH�WKH�SURJUDP�QDPH�DQG�OLQH�QXPEHU��DV�WKH�OLQH�QXPEHU�LV�RI�QR�XVH�WRWKH�XVHU� �WKLV� LV� WKH�XVHU¦V� HUURU�� DIWHU� DOO���$V�D� UXOH�RI� WKXPE��SXW� WKH�QHZOLQH�RQPHVVDJHV�WKDW�LQGLFDWH�D�XVDJH�HUURU�DQG�OHDYH�LW�RII�ZKHQ�LW�WKH�HUURU�PLJKW�EH�VRPHWKLQJ\RX�ZDQW�WR�WUDFN�GRZQ�GXULQJ�GHEXJJLQJ�

<RX�VKRXOG�DOZD\V�FKHFN�WKH�UHWXUQ�YDOXH�RI�open��VLQFH�WKH�UHVW�RI�WKH�SURJUDP�LV�UHO\LQJXSRQ�LWV�VXFFHVV�

Warning Messages with warn-XVW�DV�die� FDQ� LQGLFDWH�D� IDWDO� HUURU� WKDW�DFWV� OLNH�RQH�RI�3HUO¦V�EXLOW�LQ�HUURUV� �OLNHGLYLGLQJ�E\�]HUR���\RX�FDQ�XVH�WKH�warn�IXQFWLRQ�WR�FDXVH�D�ZDUQLQJ�WKDW�DFWV�OLNH�RQHRI�3HUO¦V�EXLOW�LQ�ZDUQLQJV��OLNH�XVLQJ�DQ�undef�YDOXH�DV�LI�LW�ZHUH�GHILQHG��ZKHQ�ZDUQLQJVDUH�HQDEOHG��

7KH�warn�IXQFWLRQ�ZRUNV�MXVW�OLNH�die�GRHV��H[FHSW�IRU�WKDW�ODVW�VWHS¢LW�GRHVQ¦W�DFWXDOO\TXLW�WKH�SURJUDP��%XW�LW�DGGV�WKH�SURJUDP�QDPH�DQG�OLQH�QXPEHU�LI�QHHGHG��DQG�LW�SULQWVWKH�PHVVDJH�WR�VWDQGDUG�HUURU��MXVW�DV�die�ZRXOG��

$QG�KDYLQJ�WDONHG�DERXW�GHDWK�DQG�GLUH�ZDUQLQJV��ZH�QRZ�UHWXUQ�\RX�WR�\RXU�UHJXODUO\VFKHGXOHG�,�2�LQVWUXFWLRQDO�PDWHULDO��5HDG�RQ�

Using Filehandles2QFH�D�ILOHKDQGOH�LV�RSHQ�IRU�UHDGLQJ��\RX�FDQ�UHDG�OLQHV�IURP�LW�MXVW�OLNH�\RX�FDQ�UHDGIURP�VWDQGDUG�LQSXW�ZLWK�STDIN��6R��IRU�H[DPSOH��WR�UHDG�OLQHV�IURP�WKH�8QL[�SDVVZRUGILOH�

if ( ! open PASSWD, "/etc/passwd") { die "How did you get logged in? ($!)";}

while (<PASSWD>) { chomp; ...}

,Q�WKLV�H[DPSOH��WKH�die�PHVVDJH�XVHV�SDUHQWKHVHV�DURXQG�$!��7KRVH�DUH�PHUHO\�SDUHQ�WKHVHV�DURXQG� WKH�PHVVDJH� LQ� WKH�RXWSXW�� �6RPHWLPHV�D�SXQFWXDWLRQ�PDUN� LV� MXVW�D

7KH�SURJUDP¦V�QDPH�LV�LQ�3HUO¦V�VSHFLDO�YDULDEOH�$0��VR�\RX�PD\�ZLVK�WR�LQFOXGH�WKDW�LQ�WKH�VWULQJ��$0:Notenough arguments\n��7KLV�LV�XVHIXO�LI�WKH�SURJUDP�PD\�EH�XVHG�LQ�D�SLSHOLQH�RU�VKHOO�VFULSW��IRU�H[DPSOH��ZKHUHLW¦V�QRW�REYLRXV�ZKLFK�FRPPDQG�LV�FRPSODLQLQJ��$0�FDQ�EH�FKDQJHG�GXULQJ�WKH�H[HFXWLRQ�RI�WKH�SURJUDP�KRZHYHU��<RX�PLJKW�DOVR�ZDQW�WR�ORRN�LQWR�WKH�VSHFLDO�__FILE__�DQG�__LINE__�WRNHQV��RU�WKH�caller�IXQFWLRQ�WR�JHW�WKH�LQIRUPDWLRQ�WKDW�LV�EHLQJ�OHIW�RXW�E\�DGGLQJ�WKH�QHZOLQH��VR�\RX�FDQ�SULQW�LW�LQ�\RXU�RZQ�FKRLFH�RIIRUPDW�

� :DUQLQJV�FDQ¦W�EH�WUDSSHG�ZLWK�DQ�eval�EORFN��OLNH�IDWDO�HUURUV�FDQ�EH��%XW�VHH�WKH�GRFXPHQWDWLRQ�IRU�WKHBBWARNBB�SVHXGRVLJQDO��LQ�WKH�SHUOYDU�PDQSDJH��LI�\RX�QHHG�WR�WUDS�D�ZDUQLQJ�

88 | Chapter 5:ಗInput and Output

SXQFWXDWLRQ�PDUN���$V�\RX�FDQ�VHH��ZKDW�ZH¦YH�EHHQ�FDOOLQJ�WKH�£OLQH�LQSXW�RSHUDWRU¤LV�UHDOO\�PDGH�RI�WZR�FRPSRQHQWV��WKH�DQJOH�EUDFNHWV��WKH�UHDO�OLQH�LQSXW�RSHUDWRU��DUHDURXQG�DQ�LQSXW�ILOHKDQGOH�

$�ILOHKDQGOH�RSHQ�IRU�ZULWLQJ�RU�DSSHQGLQJ�PD\�EH�XVHG�ZLWK�print�RU�printf��DSSHDULQJLPPHGLDWHO\�DIWHU�WKH�NH\ZRUG�EXW�EHIRUH�WKH�OLVW�RI�DUJXPHQWV�

print LOG "Captain's log, stardate 3.14159\n"; # output goes to LOGprintf STDERR "%d percent complete.\n", $done/$total * 100;

'LG�\RX�QRWLFH�WKDW�WKHUH¦V�QR�FRPPD�EHWZHHQ�WKH�ILOHKDQGOH�DQG�WKH�LWHPV�WR�EH�SULQ�WHG" �7KLV�ORRNV�HVSHFLDOO\�ZHLUG�LI�\RX�XVH�SDUHQWKHVHV��(LWKHU�RI�WKHVH�IRUPV�LV�FRUUHFW�

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

Changing the Default Output Filehandle%\�GHIDXOW��LI�\RX�GRQ¦W�JLYH�D�ILOHKDQGOH�WR�print��RU�WR�printf��DV�HYHU\WKLQJ�ZH�VD\KHUH�DERXW�RQH�DSSOLHV�HTXDOO\�ZHOO�WR�WKH�RWKHU���WKH�RXWSXW�ZLOO�JR�WR�STDOUT��%XW�WKDWGHIDXOW�PD\�EH�FKDQJHG�ZLWK�WKH�select�RSHUDWRU��+HUH�ZH¦OO�VHQG�VRPH�RXWSXW�OLQHVWR�BEDROCK�

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

2QFH�\RX¦YH�VHOHFWHG�D�ILOHKDQGOH�DV�WKH�GHIDXOW�IRU�RXWSXW��LW�ZLOO�VWD\�WKDW�ZD\��%XWLW¦V�XVXDOO\�D�EDG�LGHD�WR�FRQIXVH�WKH�UHVW�RI�WKH�SURJUDP��VR�\RX�VKRXOG�JHQHUDOO\�VHW�LWEDFN�WR�STDOUT�ZKHQ�\RX¦UH�GRQH���$OVR�E\�GHIDXOW��WKH�RXWSXW�WR�HDFK�ILOHKDQGOH�LVEXIIHUHG��6HWWLQJ�WKH�VSHFLDO�$|�YDULDEOH�WR�1�ZLOO�VHW�WKH�FXUUHQWO\�VHOHFWHG�ILOHKDQGOH�WKDW�LV��WKH�RQH�VHOHFWHG�DW�WKH�WLPH�WKDW�WKH�YDULDEOH�LV�PRGLILHG��WR�DOZD\V�IOXVK�WKHEXIIHU�DIWHU�HDFK�RXWSXW�RSHUDWLRQ��6R�LI�\RX�ZDQWHG�WR�EH�VXUH�WKDW�WKH�ORJILOH�JHWV�LWVHQWULHV�DW�RQFH��LQ�FDVH�\RX�PLJKW�EH�UHDGLQJ�WKH�ORJ�WR�PRQLWRU�SURJUHVV�RI�\RXU�ORQJ�UXQQLQJ�SURJUDP��\RX�FRXOG�XVH�VRPHWKLQJ�OLNH�WKLV�

select LOG;$| = 1; # don't keep LOG entries sitting in the bufferselect STDOUT;# ... time passes, babies learn to walk, tectonic plates shift, and then...print LOG "This gets written to the LOG at once!\n";

,I�\RX�JRW�VWUDLJKW�$¦V�LQ�IUHVKPDQ�(QJOLVK�RU�/LQJXLVWLFV��ZKHQ�ZH�VD\�WKDW�WKLV�LV�FDOOHG�£LQGLUHFW�REMHFWV\QWD[�¤�\RX�PD\�VD\�£$K��RI�FRXUVH��,�VHH�ZK\�WKHUH¦V�QR�FRPPD�DIWHU�WKH�ILOHKDQGOH�QDPH¢LW¦V�DQ�LQGLUHFWREMHFW�¤�:H�GLGQ¦W�JHW�VWUDLJKW�$¦V��:H�GRQ¦W�XQGHUVWDQG�ZK\�WKHUH¦V�QR�FRPPD��ZH�PHUHO\�RPLW�LW�EHFDXVH/DUU\�WROG�XV�WKDW�ZH�VKRXOG�RPLW�WKH�FRPPD�

� ,Q�WKH�XQOLNHO\�FDVH�WKDW�STDOUT�PLJKW�QRW�EH�WKH�VHOHFWHG�ILOHKDQGOH��\RX�FRXOG�VDYH�DQG�UHVWRUH�WKH�ILOHKDQGOH�XVLQJ�WKH�WHFKQLTXH�VKRZQ�LQ�WKH�GRFXPHQWDWLRQ�IRU�select�LQ�WKH�SHUOIXQF�PDQSDJH��$QG�DV�ORQJ�DV�ZH¦UHVHQGLQJ�\RX�WR�WKDW�PDQSDJH��ZH�PD\�DV�ZHOO�WHOO�\RX�WKDW�WKHUH�DUH�DFWXDOO\�WZR�EXLOW�LQ�IXQFWLRQV�LQ�3HUOQDPHG�select��DQG�ERWK�DUH�FRYHUHG�LQ�WKH�SHUOIXQF�PDQSDJH��7KH�RWKHU�select�DOZD\V�KDV�IRXU�DUJXPHQWV�VR�LW¦V�VRPHWLPHV�FDOOHG�£IRXU�DUJXPHQW�select�¤

Using Filehandles | 89

Reopening a Standard Filehandle:H�PHQWLRQHG�HDUOLHU�WKDW�LI�\RX�ZHUH�WR�UHRSHQ�D�ILOHKDQGOH��WKDW�LV��LI�\RX�ZHUH�WRRSHQ�D�ILOHKDQGOH�FRED�ZKHQ�\RX¦YH�DOUHDG\�JRW�DQ�RSHQ�ILOHKDQGOH�QDPHG�FRED��VD\��WKH�ROG�RQH�ZRXOG�EH�FORVHG�IRU�\RX�DXWRPDWLFDOO\��$QG�ZH�VDLG�WKDW�\RX�VKRXOGQ¦WUHXVH�RQH�RI�WKH�VL[�VWDQGDUG�ILOHKDQGOH�QDPHV�XQOHVV�\RX�LQWHQGHG�WR�JHW�WKDW�RQH¦VVSHFLDO�IHDWXUHV��$QG�ZH�DOVR�VDLG�WKDW�WKH�PHVVDJHV�IURP�die�DQG�warn��DORQJ�ZLWK�3HUO¦VLQWHUQDOO\� JHQHUDWHG� FRPSODLQWV�� JR� DXWRPDWLFDOO\� WR�STDERR�� ,I� \RX�SXW� WKRVH� WKUHHSLHFHV�RI�LQIRUPDWLRQ�WRJHWKHU��\RX�QRZ�KDYH�DQ�LGHD�DERXW�KRZ�\RX�FRXOG�VHQG�HUURUPHVVDJHV�WR�D�ILOH��UDWKHU�WKDQ�WR�\RXU�SURJUDP¦V�VWDQGDUG�HUURU�VWUHDP�

# Send errors to my private error logif ( ! open STDERR, ">>/home/barney/.error_log") { die "Can't open error log for append: $!";}

$IWHU�UHRSHQLQJ�STDERR��DQ\�HUURU�PHVVDJHV�IURP�3HUO�ZLOO�JR�LQWR�WKH�QHZ�ILOH��%XW�ZKDWKDSSHQV�LI�WKH�die�LV�H[HFXWHG¢ZKHUH�ZLOO�WKDW�PHVVDJH�JR��LI�WKH�QHZ�ILOH�FRXOGQ¦W�EHRSHQHG�WR�DFFHSW�WKH�PHVVDJHV"

7KH�DQVZHU�LV�WKDW�LI�RQH�RI�WKH�WKUHH�V\VWHP�ILOHKDQGOHV¢STDIN��STDOUT��RU�STDERR¢IDLOV�WR�UHRSHQ��3HUO�NLQGO\�UHVWRUHV�WKH�RULJLQDO�RQH���7KDW�LV��3HUO�FORVHV�WKH�RULJLQDORQH��RI�WKRVH�WKUHH��RQO\�ZKHQ�LW�VHHV�WKDW�RSHQLQJ�WKH�QHZ�FRQQHFWLRQ�LV�VXFFHVVIXO�7KXV��WKLV�WHFKQLTXH�FRXOG�EH�XVHG�WR�UHGLUHFW�DQ\��RU�DOO��RI�WKRVH�WKUHH�V\VWHP�ILOH�KDQGOHV�IURP�LQVLGH�\RXU�SURJUDP�®�DOPRVW�DV�LI�WKH�SURJUDP�KDG�EHHQ�UXQ�ZLWK�WKDW,�2�UHGLUHFWLRQ�IURP�WKH�VKHOO�LQ�WKH�ILUVW�SODFH�

Output with say3HUO������ERUURZV�WKH�say�EXLOW�LQ�IURP�WKH�RQJRLQJ�GHYHORSPHQW�RI�3HUO����ZKLFK�PD\KDYH�ERUURZHG�LWV�say�IURP�3DVFDO¦V�println���,W¦V�WKH�VDPH�DV�print��DOWKRXJK�LW�DGGVD�QHZOLQH�WR�WKH�HQG��7KHVH�IRUPV�DOO�RXWSXW�WKH�VDPH�WKLQJ�

use 5.010;

print "Hello!\n";print "Hello!", "\n";say "Hello!";

'RQ¦W�GR�WKLV�ZLWKRXW�D�UHDVRQ��,W¦V�QHDUO\�DOZD\V�EHWWHU�WR�OHW�WKH�XVHU�VHW�XS�UHGLUHFWLRQ�ZKHQ�ODXQFKLQJ\RXU�SURJUDP��UDWKHU�WKDQ�KDYH�UHGLUHFWLRQ�KDUGFRGHG��%XW�WKLV�LV�KDQG\�LQ�FDVHV�ZKHUH�\RXU�SURJUDP�LV�EHLQJUXQ�DXWRPDWLFDOO\�E\�DQRWKHU�SURJUDP��VD\��E\�D�ZHE�VHUYHU�RU�D�VFKHGXOLQJ�XWLOLW\�OLNH�cron�RU�at���$QRWKHUUHDVRQ�PLJKW�EH�WKDW�\RXU�SURJUDP�LV�JRLQJ�WR�VWDUW�DQRWKHU�SURFHVV��SUREDEO\�ZLWK�system�RU�exec��ZKLFKZH¦OO�VHH�LQ���&KDSWHU�����DQG�\RX�QHHG�WKDW�SURFHVV�WR�KDYH�GLIIHUHQW�,�2�FRQQHFWLRQV�

� $W�OHDVW��WKLV�LV�WUXH�LI�\RX�KDYHQ¦W�FKDQJHG�3HUO¦V�VSHFLDO�$^F�YDULDEOH��ZKLFK�WHOOV�3HUO�WKDW�RQO\�WKRVH�WKUHHDUH�VSHFLDO�OLNH�WKLV��%XW�\RX¦G�QHYHU�FKDQJH�WKDW�

® %XW�GRQ¦W�RSHQ�STDIN�IRU�RXWSXW�RU�WKH�RWKHUV�IRU�LQSXW��-XVW�WKLQNLQJ�DERXW�WKDW�PDNHV�RXU�KHDGV�KXUW�

90 | Chapter 5:ಗInput and Output

7R�MXVW�SULQW�D�YDULDEOH¦V�YDOXH�IROORZHG�E\�D�QHZOLQH��\RX�GRQ¦W�QHHG�WR�FUHDWH�DQ�H[WUDVWULQJ�RU�print�D�OLVW��<RX�MXVW�say�WKH�YDULDEOH��7KLV�LV�HVSHFLDOO\�KDQG\�LQ�WKH�FRPPRQFDVH�RI�VLPSO\�ZDQWLQJ�WR�SXW�D�QHZOLQH�DIWHU�ZKDWHYHU�\RX�ZDQW�WR�RXWSXW�

use 5.010;

my $name = 'Fred';print "$name\n";print $name, "\n";say $name;

7R�LQWHUSRODWH�DQ�DUUD\��\RX�VWLOO�QHHG�WR�TXRWH�LW�WKRXJK��,W¦V�WKH�TXRWLQJ�WKDW�SXWV�WKHVSDFHV�EHWZHHQ�WKH�HOHPHQWV�

use 5.010;

my @array = qw( a b c d );

say @array; # "abcd\n"

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

-XVW�OLNH�ZLWK�print��\RX�FDQ�VSHFLI\�D�ILOHKDQGOH�ZLWK�say�

use 5.010;

say BEDROCK "Hello!";

6LQFH�WKLV�LV�D�3HUO������IHDWXUH�WKRXJK��ZH¦OO�RQO\�XVH�LW�ZKHQ�ZH�DUH�RWKHUZLVH�XVLQJD�3HUO������IHDWXUH��7KH�ROG��WUXVW\�print�LV�VWLOO�DV�JRRG�DV�LW�HYHU�ZDV��EXW�ZH�VXVSHFWWKDW�WKHUH�DUH�VRPH�3HUO�SURJUDPPHUV�RXW�WKHUH�ZKR�ZLOO�ZDQW�WKH�LPPHGLDWH�VDYLQJVRI�QRW�W\SLQJ�WKH�IRXU�H[WUD�FKDUDFWHUV��WZR�LQ�WKH�QDPH�DQG�WKH�\n��

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >�@�:ULWH�D�SURJUDP�WKDW�DFWV�OLNH�FDW��EXW�UHYHUVHV�WKH�RUGHU�RI�WKH�RXWSXW�OLQHV��6RPH�V\VWHPV�KDYH�D�XWLOLW\�OLNH�WKLV�QDPHG�WDF���,I�\RX�UXQ�\RXUV�DV�./tac fredbarney betty�� WKH�RXWSXW� VKRXOG�EH� DOO� RI� ILOH�EHWW\� IURP� ODVW� OLQH� WR� ILUVW�� WKHQEDUQH\�DQG�WKHQ� IUHG��DOVR� IURP�ODVW� OLQH� WR� ILUVW�� �%H�VXUH� WR�XVH� WKH�./� LQ�\RXUSURJUDP¦V� LQYRFDWLRQ� LI�\RX�FDOO� LW� WDF� VR�WKDW�\RX�GRQ¦W�JHW� WKH�V\VWHP¦V�XWLOLW\LQVWHDG��

�� >�@�:ULWH�D�SURJUDP�WKDW�DVNV�WKH�XVHU�WR�HQWHU�D�OLVW�RI�VWULQJV�RQ�VHSDUDWH�OLQHV�SULQWLQJ�HDFK�VWULQJ�LQ�D�ULJKW�MXVWLILHG�����FKDUDFWHU�FROXPQ��7R�EH�FHUWDLQ�WKDW�WKHRXWSXW�LV�LQ�WKH�SURSHU�FROXPQV��SULQW�D�£UXOHU�OLQH¤�RI�GLJLWV�DV�ZHOO���7KLV�LV�VLPSO\D�GHEXJJLQJ�DLG���0DNH�VXUH�WKDW�\RX¦UH�QRW�XVLQJ�D����FKDUDFWHU�FROXPQ�E\�PLV�WDNH��)RU�H[DPSOH��HQWHULQJ�hello��good-bye�VKRXOG�JLYH�RXWSXW�VRPHWKLQJ�OLNH�WKLV�

Exercises | 91

123456789012345678901234567890123456789012345678901234567890 hello good-bye

�� >�@�0RGLI\�WKH�SUHYLRXV�SURJUDP�WR�OHW�WKH�XVHU�FKRRVH�WKH�FROXPQ�ZLGWK�VR�WKDWHQWHULQJ�30��hello��good-bye��RQ�VHSDUDWH�OLQHV��ZRXOG�SXW�WKH�VWULQJV�DW�WKH���WKFROXPQ���+LQW��VHH�WKH�VHFWLRQ�LQ�&KDSWHU���DERXW�FRQWUROOLQJ�YDULDEOH�LQWHUSROD�WLRQ���)RU�H[WUD�FUHGLW��PDNH�WKH�UXOHU�OLQH�ORQJHU�ZKHQ�WKH�VHOHFWHG�ZLGWK�LV�ODUJHU�

92 | Chapter 5:ಗInput and Output

CHAPTER 6

Hashes

,Q�WKLV�FKDSWHU��\RX�ZLOO�VHH�D�IHDWXUH�WKDW�PDNHV�3HUO�RQH�RI�WKH�ZRUOG¦V�WUXO\�JUHDWSURJUDPPLQJ�ODQJXDJHV��KDVKHV� �$OWKRXJK�KDVKHV�DUH�D�SRZHUIXO�DQG�XVHIXO�IHDWXUH�\RX�PD\�KDYH�XVHG�RWKHU�SRZHUIXO�ODQJXDJHV�IRU�\HDUV�ZLWKRXW�HYHU�KHDULQJ�RI�KDVKHV�%XW�\RX¦OO�XVH�KDVKHV�LQ�QHDUO\�HYHU\�3HUO�SURJUDP�\RX¦OO�ZULWH�IURP�QRZ�RQ��WKH\¦UHWKDW�LPSRUWDQW�

What Is a Hash?$�KDVK�LV�D�GDWD�VWUXFWXUH��QRW�XQOLNH�DQ�DUUD\�LQ�WKDW�LW�FDQ�KROG�DQ\�QXPEHU�RI�YDOXHVDQG�UHWULHYH�WKHP�DW�ZLOO��%XW�LQVWHDG�RI�LQGH[LQJ�WKH�YDOXHV�E\�QXPEHU��DV�ZH�GLG�ZLWKDUUD\V��ZH¦OO� ORRN�XS� WKH�YDOXHV�E\�QDPH��7KDW� LV�� WKH� LQGLFHV� �KHUH��ZH¦OO� FDOO� WKHPNH\V��DUHQ¦W�QXPEHUV��EXW�LQVWHDG�WKH\�DUH�DUELWUDU\�XQLTXH�VWULQJV��VHH�)LJXUH������

7KH�NH\V�DUH�VWULQJV��ILUVW�RI�DOO��VR�LQVWHDG�RI�JHWWLQJ�HOHPHQW�QXPEHU�3�IURP�DQ�DUUD\�ZH¦OO�EH�DFFHVVLQJ�WKH�KDVK�HOHPHQW�QDPHG�wilma�

7KHVH�NH\V�DUH�DUELWUDU\�VWULQJV¢\RX�FDQ�XVH�DQ\�VWULQJ�H[SUHVVLRQ�IRU�D�KDVK�NH\��$QGWKH\�DUH�XQLTXH�VWULQJV¢MXVW�DV�WKHUH¦V�RQO\�RQH�DUUD\�HOHPHQW�QXPEHUHG�3��WKHUH¦V�RQO\RQH�KDVK�HOHPHQW�QDPHG�wilma�

$QRWKHU�ZD\�WR�WKLQN�RI�D�KDVK�LV�WKDW�LW¦V�OLNH�D�EDUUHO�RI�GDWD��VHH�)LJXUH�������ZKHUHHDFK�SLHFH�RI�GDWD�KDV�D�WDJ�DWWDFKHG��<RX�FDQ�UHDFK�LQWR�WKH�EDUUHO�DQG�SXOO�RXW�DQ\WDJ�DQG�VHH�ZKDW�SLHFH�RI�GDWD�LV�DWWDFKHG��%XW�WKHUH¦V�QR�£ILUVW¤�LWHP�LQ�WKH�EDUUHO��LW¦VMXVW�D�MXPEOH��,Q�DQ�DUUD\��ZH¦G�VWDUW�ZLWK�HOHPHQW�0��WKHQ�HOHPHQW�1��WKHQ�HOHPHQW�2�DQG�VR�RQ��%XW�LQ�D�KDVK��WKHUH¦V�QR�IL[HG�RUGHU��QR�ILUVW�HOHPHQW��,W¦V�MXVW�D�FROOHFWLRQRI�NH\�YDOXH�SDLUV�

,Q�WKH�ROGHQ�GD\V��ZH�FDOOHG�WKHVH�£DVVRFLDWLYH�DUUD\V�¤�%XW�WKH�3HUO�FRPPXQLW\�GHFLGHG�LQ�DERXW������WKLVZDV�WRR�PDQ\�OHWWHUV�WR�W\SH�DQG�WRR�PDQ\�V\OODEOHV�WR�VD\��VR�ZH�FKDQJHG�WKH�QDPH�WR�£KDVKHV�¤

93

KEYS

VALUES

35

12.4

“hello”

1.72e30

“bye\n”

“foo”

“bar”

“2.5”

“wilma”

“betty”

)LJXUH������+DVK�NH\V�DQG�YDOXHV

time2.5piquark

apple Q5hammer cow

larry

)LJXUH������$�KDVK�DV�D�EDUUHO�RI�GDWD

94 | Chapter 6:ಗHashes

7KH�NH\V�DQG�YDOXHV�DUH�ERWK�DUELWUDU\�VFDODUV��EXW�WKH�NH\V�DUH�DOZD\V�FRQYHUWHG�WRVWULQJV��6R��LI�\RX�XVHG�WKH�QXPHULF�H[SUHVVLRQ�50/20�DV�WKH�NH\� �LW�ZRXOG�EH�WXUQHGLQWR�WKH�WKUHH�FKDUDFWHU�VWULQJ�"2.5"��ZKLFK�LV�RQH�RI�WKH�NH\V�VKRZQ�LQ�WKH�GLDJUDPDERYH�

$V�XVXDO��3HUO¦V�£QR�XQQHFHVVDU\�OLPLWV�SKLORVRSK\¤�DSSOLHV��D�KDVK�PD\�EH�RI�DQ\�VL]H�IURP�DQ�HPSW\�KDVK�ZLWK�]HUR�NH\�YDOXH�SDLUV��XS�WR�ZKDWHYHU�ILOOV�XS�\RXU�PHPRU\�

6RPH�LPSOHPHQWDWLRQV�RI�KDVKHV��VXFK�DV�LQ�WKH�RULJLQDO�DZN�ODQJXDJH��IURP�ZKLFK/DUU\�ERUURZHG�WKH�LGHD��VORZ�GRZQ�DV�WKH�KDVKHV�JHW�ODUJHU�DQG�ODUJHU��7KLV�LV�QRW�WKHFDVH�LQ�3HUO¢LW�KDV�D�JRRG��HIILFLHQW��VFDODEOH�DOJRULWKP���6R��LI�D�KDVK�KDV�RQO\�WKUHHNH\�YDOXH�SDLUV��LW¦V�YHU\�TXLFN�WR�£UHDFK�LQWR�WKH�EDUUHO¤�DQG�SXOO�RXW�DQ\�RQH�RI�WKRVH�,I�WKH�KDVK�KDV�WKUHH�PLOOLRQ�NH\�YDOXH�SDLUV��LW�VKRXOG�EH�MXVW�DERXW�DV�TXLFN�WR�SXOO�RXWDQ\�RQH�RI�WKRVH��$�ELJ�KDVK�LV�QRWKLQJ�WR�IHDU�

,W¦V�ZRUWK�PHQWLRQLQJ�DJDLQ�WKDW�WKH�NH\V�DUH�DOZD\V�XQLTXH��DOWKRXJK�WKH�YDOXHV�PD\EH�GXSOLFDWHG��7KH�YDOXHV�RI�D�KDVK�PD\�EH�DOO�QXPEHUV��DOO�VWULQJV��undef�YDOXHV��RU�DPL[WXUH�®�%XW�WKH�NH\V�DUH�DOO�DUELWUDU\��XQLTXH�VWULQJV�

Why Use a Hash?:KHQ�\RX�ILUVW�KHDU�DERXW�KDVKHV��HVSHFLDOO\�LI�\RX¦YH�OLYHG�D�ORQJ�DQG�SURGXFWLYH�OLIHDV�D�SURJUDPPHU�XVLQJ�ODQJXDJHV�WKDW�GRQ¦W�KDYH�KDVKHV��\RX�PD\�ZRQGHU�ZK\�DQ\RQHZRXOG�ZDQW�RQH�RI�WKHVH�VWUDQJH�EHDVWV��:HOO��WKH�JHQHUDO�LGHD�LV�WKDW�\RX¦OO�KDYH�RQHVHW�RI�GDWD�£UHODWHG�WR¤�DQRWKHU�VHW�RI�GDWD��)RU�H[DPSOH��KHUH�DUH�VRPH�KDVKHV�\RXPLJKW�ILQG�LQ�W\SLFDO�DSSOLFDWLRQV�RI�3HUO�

*LYHQ�QDPH��IDPLO\�QDPH7KH�JLYHQ�QDPH��ILUVW�QDPH�� LV� WKH�NH\��DQG�WKH� IDPLO\�QDPH� LV� WKH�YDOXH��7KLVUHTXLUHV�XQLTXH�JLYHQ�QDPHV��RI�FRXUVH��LI�WKHUH�ZHUH�WZR�SHRSOH�QDPHG�randal�WKLV�ZRXOGQ¦W�ZRUN��:LWK�WKLV�KDVK��\RX�FDQ�ORRN�XS�DQ\RQH¦V�JLYHQ�QDPH��DQGILQG� WKH� FRUUHVSRQGLQJ� IDPLO\�QDPH�� ,I� \RX�XVH� WKH� NH\� tom�� \RX� JHW� WKH� YDOXHphoenix�

+RVWQDPH��,3�DGGUHVV<RX�PD\�NQRZ�WKDW�HDFK�FRPSXWHU�RQ�WKH�,QWHUQHW�KDV�ERWK�D�KRVWQDPH��OLNH�KWWS���ZZZ�VWRQHKHQJH�FRP��DQG�DQ�,3�DGGUHVV�QXPEHU��OLNH����������������7KDW¦V�EH�FDXVH�PDFKLQHV�OLNH�ZRUNLQJ�ZLWK�WKH�QXPEHUV��EXW�ZH�KXPDQV�KDYH�DQ�HDVLHU�WLPHUHPHPEHULQJ�WKH�QDPHV��7KH�KRVWQDPHV�DUH�XQLTXH�VWULQJV��VR�WKH\�FDQ�EH�XVHG

7KDW¦V�D�QXPHULF�H[SUHVVLRQ��QRW�WKH�ILYH�FKDUDFWHU�VWULQJ�"50/20"��,I�ZH�XVHG�WKDW�ILYH�FKDUDFWHU�VWULQJ�DV�DKDVK�NH\��LW�ZRXOG�VWD\�WKH�VDPH�ILYH�FKDUDFWHU�VWULQJ��RI�FRXUVH�

� 7HFKQLFDOO\��3HUO�UHEXLOGV�WKH�KDVK�WDEOH�DV�QHHGHG�IRU�ODUJHU�KDVKHV��,Q�IDFW��WKH�WHUP�£KDVKHV¤�FRPHV�IURPWKH�IDFW�WKDW�D�KDVK�WDEOH�LV�XVHG�IRU�LPSOHPHQWLQJ�WKHP�

® 2U��LQ�IDFW��DQ\�VFDODU�YDOXHV��LQFOXGLQJ�RWKHU�VFDODU�W\SHV�WKDQ�WKH�RQHV�ZH¦OO�VHH�LQ�WKLV�ERRN�

What Is a Hash? | 95

WR�PDNH�WKLV�KDVK��:LWK�WKLV�KDVK��\RX�FRXOG�ORRN�XS�D�KRVWQDPH�DQG�ILQG�WKHFRUUHVSRQGLQJ�,3�DGGUHVV�

,3�DGGUHVV��KRVWQDPH2U�\RX�FRXOG�JR�LQ�WKH�RSSRVLWH�GLUHFWLRQ��:H�JHQHUDOO\�WKLQN�RI�WKH�,3�DGGUHVV�DVD�QXPEHU��EXW�LW�FDQ�DOVR�EH�D�XQLTXH�VWULQJ��VR�LW¦V�VXLWDEOH�IRU�XVH�DV�D�KDVK�NH\�,Q�WKLV�KDVK��ZH�FDQ�XVH�WKH�,3�DGGUHVV�WR�ORRN�XS�WKH�FRUUHVSRQGLQJ�KRVWQDPH�1RWH�WKDW�WKLV�LV�QRW�WKH�VDPH�KDVK�DV�WKH�SUHYLRXV�H[DPSOH��KDVKHV�DUH�D�RQH�ZD\VWUHHW��UXQQLQJ�IURP�NH\�WR�YDOXH��WKHUH¦V�QR�ZD\�WR�ORRN�XS�D�YDOXH�LQ�D�KDVK�DQGILQG�WKH�FRUUHVSRQGLQJ�NH\��6R�WKHVH�WZR�DUH�D�SDLU�RI�KDVKHV��RQH�IRU�VWRULQJ�,3DGGUHVVHV��RQH�IRU�KRVWQDPHV��,W¦V�HDV\�HQRXJK�WR�FUHDWH�RQH�RI�WKHVH�JLYHQ�WKHRWKHU��WKRXJK��DV�ZH¦OO�VHH�EHORZ�

:RUG��FRXQW�RI�QXPEHU�RI�WLPHV�WKDW�ZRUG�DSSHDUV7KLV�LV�D�YHU\�FRPPRQ�XVH�RI�D�KDVK��,W¦V�VR�FRPPRQ��LQ�IDFW��WKDW�LW�MXVW�PLJKW�WXUQXS�LQ�WKH�H[HUFLVHV�DW�WKH�HQG�RI�WKH�FKDSWHU�

7KH�LGHD�KHUH�LV�WKDW�\RX�ZDQW�WR�NQRZ�KRZ�RIWHQ�HDFK�ZRUG�DSSHDUV�LQ�D�JLYHQGRFXPHQW��3HUKDSV�\RX¦UH�EXLOGLQJ�DQ�LQGH[�WR�D�QXPEHU�RI�GRFXPHQWV�VR�WKDWZKHQ� D� XVHU� VHDUFKHV� IRU� fred�� \RX¦OO� NQRZ� WKDW� D� FHUWDLQ� GRFXPHQW�PHQWLRQVfred�ILYH�WLPHV��DQRWKHU�PHQWLRQV�fred�VHYHQ�WLPHV��DQG�\HW�DQRWKHU�GRHVQ¦W�PHQ�WLRQ�fred�DW�DOO¢VR�\RX¦OO�NQRZ�ZKLFK�GRFXPHQWV�WKH�XVHU�LV�OLNHO\�WR�ZDQW��$V�WKHLQGH[�PDNLQJ�SURJUDP�UHDGV�WKURXJK�D�JLYHQ�GRFXPHQW��HDFK�WLPH�LW�VHHV�D�PHQ�WLRQ�RI�fred��LW�DGGV�RQH�WR�WKH�YDOXH�ILOHG�XQGHU�WKH�NH\�RI�fred��7KDW�LV��LI�ZH�KDGVHHQ�fred� WZLFH�DOUHDG\� LQ� WKLV�GRFXPHQW�� WKH�YDOXH�ZRXOG�EH�2��EXW�QRZ�ZH¦OOLQFUHPHQW�LW�WR�3��,I�ZH�KDG�QHYHU�VHHQ�fred�EHIRUH��ZH¦G�FKDQJH�WKH�YDOXH�IURPundef��WKH�LPSOLFLW��GHIDXOW�YDOXH��WR�1�

8VHUQDPH��QXPEHU�RI�GLVN�EORFNV�WKH\�DUH�XVLQJ�>ZDVWLQJ@6\VWHP�DGPLQLVWUDWRUV�OLNH�WKLV�RQH��WKH�XVHUQDPHV�RQ�D�JLYHQ�V\VWHP�DUH�DOO�XQLTXHVWULQJV��VR�WKH\�FDQ�EH�XVHG�DV�NH\V�LQ�D�KDVK�WR�ORRN�XS�LQIRUPDWLRQ�DERXW�WKDW�XVHU�

'ULYHU¦V�OLFHQVH�QXPEHU��QDPH7KHUH�PD\�EH�PDQ\��PDQ\�SHRSOH�QDPHG�-RKQ�6PLWK��EXW�ZH�KRSH�WKDW�HDFK�RQHKDV�D�GLIIHUHQW�GULYHU¦V�OLFHQVH�QXPEHU��7KDW�QXPEHU�PDNHV�IRU�D�XQLTXH�NH\��DQGWKH�SHUVRQ¦V�QDPH�LV�WKH�YDOXH�

<HW�DQRWKHU�ZD\�WR�WKLQN�RI�D�KDVK�LV�DV�D�YHU\�VLPSOH�GDWDEDVH��LQ�ZKLFK�MXVW�RQH�SLHFHRI�GDWD�PD\�EH�ILOHG�XQGHU�HDFK�NH\��,Q�IDFW��LI�\RXU�WDVN�GHVFULSWLRQ�LQFOXGHV�SKUDVHVOLNH�£ILQGLQJ�GXSOLFDWHV�¤�£XQLTXH�¤�£FURVV�UHIHUHQFH�¤�RU�£ORRNXS�WDEOH�¤�LW¦V�OLNHO\�WKDWD�KDVK�ZLOO�EH�XVHIXO�LQ�WKH�LPSOHPHQWDWLRQ�

Hash Element Access7R�DFFHVV�DQ�HOHPHQW�RI�D�KDVK��XVH�V\QWD[�WKDW�ORRNV�OLNH�WKLV�

$hash{$some_key}

96 | Chapter 6:ಗHashes

7KLV�LV�VLPLODU�WR�ZKDW�ZH�XVHG�IRU�DUUD\�DFFHVV��EXW�KHUH�ZH�XVH�FXUO\�EUDFHV�LQVWHDGRI�VTXDUH�EUDFNHWV�DURXQG�WKH�VXEVFULSW��NH\�� �$QG�WKDW�NH\�H[SUHVVLRQ�LV�QRZ�D�VWULQJ�UDWKHU�WKDQ�D�QXPEHU�

$family_name{"fred"} = "flintstone";$family_name{"barney"} = "rubble";

)LJXUH�����VKRZV�KRZ�WKH�UHVXOWLQJ�KDVK�NH\V�DUH�DVVLJQHG�

flintstone

rubble

fred

barney

)LJXUH������$VVLJQHG�KDVK�NH\V

7KLV�OHWV�XV�XVH�FRGH�OLNH�WKLV�

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

7KH�QDPH�RI�WKH�KDVK�LV�OLNH�DQ\�RWKHU�3HUO�LGHQWLILHU��OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV�EXW�FDQ¦W�VWDUW�ZLWK�D�GLJLW���$QG�LW¦V�IURP�D�VHSDUDWH�QDPHVSDFH��WKDW� LV��WKHUH¦V�QRFRQQHFWLRQ� EHWZHHQ� WKH� KDVK� HOHPHQW� $family_name{"fred"}� DQG� D� VXEURXWLQH&family_name��IRU�H[DPSOH��2I�FRXUVH��WKHUH¦V�QR�UHDVRQ�WR�FRQIXVH�HYHU\RQH�E\�JLYLQJHYHU\WKLQJ� WKH� VDPH� QDPH�� %XW� 3HUO� ZRQ¦W� PLQG� LI� \RX� DOVR� KDYH� D� VFDODU� FDOOHG$family_name�DQG�DUUD\�HOHPHQWV�OLNH�$family_name[5]��:H�KXPDQV�ZLOO�KDYH�WR�GR�DV3HUO�GRHV��WKDW�LV��ZH¦OO�KDYH�WR�ORRN�WR�VHH�ZKDW�SXQFWXDWLRQ�DSSHDUV�EHIRUH�DQG�DIWHUWKH�LGHQWLILHU�WR�VHH�ZKDW�LW�PHDQV��:KHQ�WKHUH�LV�D�GROODU�VLJQ�LQ�IURQW�RI�WKH�QDPH�DQGFXUO\�EUDFHV�DIWHUZDUG��LW¦V�D�KDVK�HOHPHQW�WKDW¦V�EHLQJ�DFFHVVHG�

:KHQ�FKRRVLQJ�WKH�QDPH�RI�D�KDVK��LW¦V�RIWHQ�QLFH�WR�WKLQN�RI�WKH�ZRUG�£IRU¤�EHWZHHQWKH�QDPH�RI�WKH�KDVK�DQG�WKH�NH\��$V�LQ��£WKH�family_name�IRU�fred�LV�flintstone¤��6RWKH�KDVK�LV�QDPHG�family_name��7KHQ�WKH�UHODWLRQVKLS�EHWZHHQ�WKH�NH\V�DQG�WKHLU�YDOXHVEHFRPHV�FOHDU�

2I�FRXUVH��WKH�KDVK�NH\�PD\�EH�DQ\�H[SUHVVLRQ��QRW�MXVW�WKH�OLWHUDO�VWULQJV�DQG�VLPSOHVFDODU�YDULDEOHV�WKDW�ZH¦UH�VKRZLQJ�KHUH�

$foo = "bar";print $family_name{ $foo . "ney" }; # prints "rubble"

:KHQ�\RX�VWRUH�VRPHWKLQJ�LQWR�DQ�H[LVWLQJ�KDVK�HOHPHQW��LW�RYHUZULWHV�WKH�SUHYLRXVYDOXH�

+HUH¦V�D�SHHN�LQWR�WKH�PLQG�RI�/DUU\�:DOO��/DUU\�VD\V�WKDW�ZH�XVH�FXUO\�EUDFHV�LQVWHDG�RI�VTXDUH�EUDFNHWVEHFDXVH�ZH¦UH�GRLQJ�VRPHWKLQJ�IDQFLHU�WKDQ�RUGLQDU\�DUUD\�DFFHVV��VR�ZH�VKRXOG�XVH�IDQFLHU�SXQFWXDWLRQ�

Hash Element Access | 97

$family_name{"fred"} = "astaire"; # gives new value to existing element$bedrock = $family_name{"fred"}; # gets "astaire"; old value is lost

7KDW¦V�DQDORJRXV�WR�ZKDW�KDSSHQV�ZLWK�DUUD\V�DQG�VFDODUV��LI�\RX�VWRUH�VRPHWKLQJ�QHZLQWR�$pebbles[17]�RU�$dino��WKH�ROG�YDOXH�LV�UHSODFHG��,I�\RX�VWRUH�VRPHWKLQJ�QHZ�LQWR$family_name{"fred"}��WKH�ROG�YDOXH�LV�UHSODFHG�DV�ZHOO�

+DVK�HOHPHQWV�ZLOO�VSULQJ�LQWR�H[LVWHQFH�E\�DVVLJQPHQW�

$family_name{"wilma"} = "flintstone"; # adds a new key (and value)$family_name{"betty"} .= $family_name{"barney"}; # creates the element if needed

7KDW¦V� DOVR� MXVW� OLNH� ZKDW� KDSSHQV� ZLWK� DUUD\V� DQG� VFDODUV�� LI� \RX� GLGQ¦W� KDYH$pebbles[17]�RU�$dino�EHIRUH��\RX�ZLOO�KDYH�LW�DIWHU�\RX�DVVLJQ�WR�LW��,I�\RX�GLGQ¦W�KDYH$family_name{"betty"}�EHIRUH��\RX�GR�QRZ�

$QG�DFFHVVLQJ�RXWVLGH�WKH�KDVK�JLYHV�undef�

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

2QFH�DJDLQ��WKLV�LV�MXVW�OLNH�ZKDW�KDSSHQV�ZLWK�DUUD\V�DQG�VFDODUV��LI�WKHUH¦V�QRWKLQJ�\HWVWRUHG�LQ�$pebbles[17]�RU�$dino��DFFHVVLQJ�WKHP�ZLOO�\LHOG�undef��,I�WKHUH¦V�QRWKLQJ�\HWVWRUHG�LQ�$family_name{"larry"}��DFFHVVLQJ�LW�ZLOO�\LHOG�undef�

The Hash As a Whole7R�UHIHU�WR�WKH�HQWLUH�KDVK��XVH�WKH�SHUFHQW�VLJQ��%��DV�D�SUHIL[��6R��WKH�KDVK�ZH¦YH�EHHQXVLQJ�IRU�WKH�ODVW�IHZ�SDJHV�LV�DFWXDOO\�FDOOHG�%family_name�

)RU�FRQYHQLHQFH��D�KDVK�PD\�EH�FRQYHUWHG�LQWR�D�OLVW��DQG�EDFN�DJDLQ��$VVLJQLQJ�WR�DKDVK��LQ�WKLV�FDVH��WKH�RQH�IURP�)LJXUH������LV�D�OLVW�FRQWH[W�DVVLJQPHQW��ZKHUH�WKH�OLVWLV�PDGH�RI�NH\�YDOXH�SDLUV�

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

7KH�YDOXH�RI�WKH�KDVK��LQ�D�OLVW�FRQWH[W��LV�D�VLPSOH�OLVW�RI�NH\�YDOXH�SDLUV�

@any_array = %some_hash;

:H�FDOO�WKLV�XQZLQGLQJ�WKH�KDVK¢WXUQLQJ�LW�EDFN�LQWR�D�OLVW�RI�NH\�YDOXH�SDLUV��2I�FRXUVH�WKH�SDLUV�ZRQ¦W�QHFHVVDULO\�EH�LQ�WKH�VDPH�RUGHU�DV�WKH�RULJLQDO�OLVW�

print "@any_array\n"; # might give something like this: # betty bye (and a newline) wilma 1.72e+30 foo 35 2.5 hello bar 12.4

7KH�RUGHU�LV�MXPEOHG�EHFDXVH�3HUO�NHHSV�WKH�NH\�YDOXH�SDLUV�LQ�DQ�RUGHU�WKDW¦V�FRQYHQ�LHQW�IRU�3HUO�VR�WKDW�LW�FDQ�ORRN�XS�DQ\�LWHP�TXLFNO\��<RX�XVH�D�KDVK�HLWKHU�ZKHQ�\RXGRQ¦W�FDUH�ZKDW�RUGHU�WKH�LWHPV�DUH�LQ��RU�ZKHQ�\RX�KDYH�DQ�HDV\�ZD\�WR�SXW�WKHP�LQWRWKH�RUGHU�\RX�ZDQW�

$OWKRXJK�DQ\�OLVW�H[SUHVVLRQ�PD\�EH�XVHG��LW�PXVW�KDYH�DQ�HYHQ�QXPEHU�RI�HOHPHQWV�EHFDXVH�WKH�KDVK�LV�PDGHRI�NH\�YDOXH�SDLUV��$Q�RGG�HOHPHQW�ZLOO�OLNHO\�GR�VRPHWKLQJ�XQUHOLDEOH��DOWKRXJK�LW¦V�D�ZDUQDEOH�RIIHQVH�

98 | Chapter 6:ಗHashes

2I�FRXUVH��HYHQ�WKRXJK�WKH�RUGHU�RI�WKH�NH\�YDOXH�SDLUV�LV�MXPEOHG��HDFK�NH\�£VWLFNV¤ZLWK�LWV�FRUUHVSRQGLQJ�YDOXH�LQ�WKH�UHVXOWLQJ�OLVW��6R��HYHQ�WKRXJK�ZH�GRQ¦W�NQRZ�ZKHUHWKH�NH\�foo�ZLOO�DSSHDU�LQ�WKH�OLVW��ZH�NQRZ�WKDW�LWV�YDOXH��35��ZLOO�EH�ULJKW�DIWHU�LW�

Hash Assignment,W¦V�UDUH�WR�GR�VR��EXW�D�KDVK�PD\�EH�FRSLHG�XVLQJ�WKH�REYLRXV�V\QWD[�

%new_hash = %old_hash;

7KLV�LV�DFWXDOO\�PRUH�ZRUN�IRU�3HUO�WKDQ�PHHWV�WKH�H\H��8QOLNH�ZKDW�KDSSHQV�LQ�ODQ�JXDJHV�OLNH�3DVFDO�RU�&��ZKHUH�VXFK�DQ�RSHUDWLRQ�ZRXOG�EH�D�VLPSOH�PDWWHU�RI�FRS\LQJD�EORFN�RI�PHPRU\��3HUO¦V�GDWD�VWUXFWXUHV�DUH�PRUH�FRPSOH[��6R��WKDW�OLQH�RI�FRGH�WHOOV3HUO� WR� XQZLQG� WKH� %old_hash� LQWR� D� OLVW� RI� NH\�YDOXH� SDLUV�� WKHQ� DVVLJQ� WKRVH� WR%new_hash��EXLOGLQJ�LW�XS�RQH�NH\�YDOXH�SDLU�DW�D�WLPH�

,W¦V�PRUH�FRPPRQ�WR�WUDQVIRUP�WKH�KDVK�LQ�VRPH�ZD\��WKRXJK��)RU�H[DPSOH��ZH�FRXOGPDNH�DQ�LQYHUVH�KDVK�

%inverse_hash = reverse %any_hash;

7KLV�WDNHV�%any_hash�DQG�XQZLQGV�LW�LQWR�D�OLVW�RI�NH\�YDOXH�SDLUV��PDNLQJ�D�OLVW�OLNH(NH\��YDOXH��NH\��YDOXH��NH\��YDOXH�����)��7KHQ�reverse�WXUQV�WKDW�OLVW�HQG�IRU�HQG��PDNLQJD�OLVW�OLNH�(YDOXH��NH\��YDOXH��NH\��YDOXH��NH\�����)��1RZ�WKH�NH\V�DUH�ZKHUH�WKH�YDOXHVXVHG� WR�EH�� DQG� WKH�YDOXHV�DUH�ZKHUH� WKH�NH\V�XVHG� WR�EH��:KHQ� WKDW¦V� VWRUHG� LQWR%inverse_hash��ZH¦OO�EH�DEOH�WR�ORRN�XS�D�VWULQJ�WKDW�ZDV�D�YDOXH�LQ�%any_hash¢LW¦V�QRZD�NH\�RI�%inverse_hash��$QG�WKH�YDOXH�ZH¦OO�ILQG�LV�RQH�WKDW�ZDV�RQH�RI�WKH�NH\V�IURP%any_hash��6R��ZH�KDYH�D�ZD\�WR�ORRN�XS�D�£YDOXH¤��QRZ�D�NH\���DQG�ILQG�D�£NH\¤��QRZD�YDOXH��

2I�FRXUVH��\RX�PLJKW�JXHVV��RU�GHWHUPLQH�IURP�VFLHQWLILF�SULQFLSOHV�LI�\RX¦UH�FOHYHU��WKDWWKLV�ZLOO�ZRUN�SURSHUO\�RQO\�LI�WKH�YDOXHV�LQ�WKH�RULJLQDO�KDVK�ZHUH�XQLTXH¢RWKHUZLVH�ZH¦G�KDYH�GXSOLFDWH�NH\V�LQ�WKH�QHZ�KDVK��DQG�NH\V�DUH�DOZD\V�XQLTXH��+HUH¦V�WKH�UXOHWKDW�3HUO�XVHV��WKH�ODVW�RQH�LQ�ZLQV��7KDW�LV��WKH�ODWHU�LWHPV�LQ�WKH�OLVW�RYHUZULWH�DQ\�HDUOLHURQHV��2I�FRXUVH��ZH�GRQ¦W�NQRZ�ZKDW�RUGHU�WKH�NH\�YDOXH�SDLUV�ZLOO�KDYH�LQ�WKLV�OLVW��VRWKHUH¦V�QR�WHOOLQJ�ZKLFK�RQHV�ZRXOG�ZLQ��<RX¦G�XVH�WKLV�WHFKQLTXH�RQO\�LI�\RX�NQRZWKHUH�DUH�QR�GXSOLFDWHV�DPRQJ�WKH�RULJLQDO�YDOXHV� �%XW�WKDW¦V�WKH�FDVH�IRU�WKH�,3�DGGUHVVDQG�KRVWQDPH�H[DPSOHV�JLYHQ�HDUOLHU�

%ip_address = reverse %host_name;

1RZ�ZH�FDQ�ORRN�XS�D�KRVWQDPH�RU�,3�DGGUHVV�ZLWK�HTXDO�HDVH�WR�ILQG�WKH�FRUUHVSRQGLQJ,3�DGGUHVV�RU�KRVWQDPH�

2U�LI�\RX�GRQ¦W�FDUH�WKDW�WKHUH�DUH�GXSOLFDWHV��)RU�H[DPSOH��ZH�FRXOG�LQYHUW�WKH�%family_name�KDVK��LQ�ZKLFKWKH�NH\V�DUH�SHRSOH¦V�JLYHQ�QDPHV�DQG�YDOXHV�DUH�WKHLU�IDPLO\�QDPHV��WR�PDNH�LW�HDV\�WR�GHWHUPLQH�ZKHWKHUWKHUH�LV�RU�LV�QRW�DQ\RQH�ZLWK�D�JLYHQ�IDPLO\�QDPH�LQ�WKH�JURXS��7KXV��LQ�WKH�LQYHUWHG�KDVK��LI�WKHUH¦V�QR�NH\RI�slate��ZH¦G�NQRZ�WKDW�WKHUH¦V�QR�RQH�ZLWK�WKDW�QDPH�LQ�WKH�RULJLQDO�KDVK�

Hash Element Access | 99

The Big Arrow:KHQ�DVVLJQLQJ�D�OLVW�WR�D�KDVK��VRPHWLPHV�LW¦V�QRW�REYLRXV�ZKLFK�HOHPHQWV�DUH�NH\VDQG�ZKLFK�DUH�YDOXHV��)RU�H[DPSOH��LQ�WKLV�DVVLJQPHQW��ZKLFK�ZH�VDZ�HDUOLHU���ZH�KX�PDQV�KDYH� WR�FRXQW� WKURXJK� WKH� OLVW�� VD\LQJ��£NH\��YDOXH��NH\��YDOXH�¤�� LQ�RUGHU� WRGHWHUPLQH�ZKHWKHU�2.5�LV�D�NH\�RU�D�YDOXH�

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

:RXOGQ¦W�LW�EH�QLFH�LI�3HUO�JDYH�XV�D�ZD\�WR�SDLU�XS�NH\V�DQG�YDOXHV�LQ�WKDW�NLQG�RI�DOLVW��VR�WKDW�LW�ZRXOG�EH�HDV\�WR�VHH�ZKLFK�RQHV�ZHUH�ZKLFK"�/DUU\�WKRXJKW�VR��WRR��ZKLFKLV�ZK\�KH�LQYHQWHG�WKH�ELJ�DUURZ��=>�� �7R�3HUO��LW¦V�MXVW�D�GLIIHUHQW�ZD\�WR�£VSHOO¤�D�FRPPD��VR�LW¦V�DOVR�VRPHWLPHV�FDOOHG�WKH�£IDW�FRPPD�¤�7KDW�LV��LQ�WKH�3HUO�JUDPPDU�DQ\�WLPH�WKDW�\RX�QHHG�D�FRPPD���,����\RX�FDQ�XVH�WKH�ELJ�DUURZ�LQVWHDG��LW¦V�DOO�WKHVDPH�WR�3HUO���6R�KHUH¦V�DQRWKHU�ZD\�WR�VHW�XS�WKH�KDVK�RI�ODVW�QDPHV�

my %last_name = ( # a hash may be a lexical variable "fred" => "flintstone", "dino" => undef, "barney" => "rubble", "betty" => "rubble",);

+HUH��LW¦V�HDV\��RU�SHUKDSV�DW�OHDVW�HDVLHU��WR�VHH�ZKRVH�QDPH�SDLUV�ZLWK�ZKLFK�YDOXH�HYHQ� LI�ZH�HQG�XS�SXWWLQJ�PDQ\�SDLUV�RQ�RQH� OLQH��$QG�QRWLFH�WKDW�WKHUH¦V�DQ�H[WUDFRPPD�DW�WKH�HQG�RI�WKH�OLVW��$V�ZH�VDZ�HDUOLHU��WKLV�LV�KDUPOHVV��EXW�FRQYHQLHQW��LI�ZHQHHG�WR�DGG�DGGLWLRQDO�SHRSOH�WR�WKLV�KDVK��ZH¦OO�VLPSO\�PDNH�VXUH�WKDW�HDFK�OLQH�KDV�DNH\�YDOXH�SDLU�DQG�D�WUDLOLQJ�FRPPD��3HUO�ZLOO�VHH�WKDW�WKHUH�LV�D�FRPPD�EHWZHHQ�HDFKLWHP�DQG�WKH�QH[W��DQG�RQH�H[WUD��KDUPOHVV��FRPPD�DW�WKH�HQG�RI�WKH�OLVW�

Hash Functions1DWXUDOO\��WKHUH�DUH�VRPH�XVHIXO�IXQFWLRQV�WKDW�FDQ�ZRUN�RQ�DQ�HQWLUH�KDVK�DW�RQFH�

The keys and values Functions7KH�keys�IXQFWLRQ�\LHOGV�D�OLVW�RI�DOO�WKH�NH\V�LQ�D�KDVK��ZKLOH�WKH�values�IXQFWLRQ�JLYHVWKH�FRUUHVSRQGLQJ�YDOXHV��,I�WKHUH�DUH�QR�HOHPHQWV�WR�WKH�KDVK��WKHQ�HLWKHU�IXQFWLRQUHWXUQV�DQ�HPSW\�OLVW�

<HV��WKHUH¦V�DOVR�D�OLWWOH�DUURZ��->���,W¦V�XVHG�ZLWK�UHIHUHQFHV��ZKLFK�LV�DQ�DGYDQFHG�WRSLF��VHH�WKH�SHUOUHIWXWDQG�SHUOUHI�PDQSDJHV�ZKHQ�\RX¦UH�UHDG\�IRU�WKDW�

� :HOO��WKHUH¦V�RQH�WHFKQLFDO�GLIIHUHQFH��DQ\�EDUHZRUG��D�VHTXHQFH�RI�QRWKLQJ�EXW�OHWWHUV��GLJLWV��DQG�XQGHUVFRUHVQRW�VWDUWLQJ�ZLWK�D�GLJLW��EXW�RSWLRQDOO\�SUHIL[HG�ZLWK�SOXV�RU�PLQXV��WR�WKH�OHIW�RI�WKH�ELJ�DUURZ�LV�LPSOLFLWO\TXRWHG��6R�\RX�FDQ�OHDYH�RII�WKH�TXRWH�PDUNV�RQ�D�EDUHZRUG�WR�WKH�OHIW�RI�WKH�ELJ�DUURZ��<RX�PD\�DOVR�RPLWWKH�TXRWH�PDUNV�LI�WKHUH¦V�QRWKLQJ�EXW�D�EDUHZRUG�DV�D�NH\�LQVLGH�WKH�FXUO\�EUDFHV�RI�D�KDVK�

100 | Chapter 6:ಗHashes

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

6R��@k�ZLOO�FRQWDLQ�"a"��"b"��DQG�"c"��DQG�@v�ZLOO�FRQWDLQ�1��2��DQG�3¢LQ�VRPH�RUGHU�5HPHPEHU��3HUO�GRHVQ¦W�PDLQWDLQ�WKH�RUGHU�RI�HOHPHQWV�LQ�D�KDVK��%XW��ZKDWHYHU�RUGHUWKH�NH\V�DUH�LQ��WKH�YDOXHV�ZLOO�EH�LQ�WKH�FRUUHVSRQGLQJ�RUGHU��LI�"b"�LV�ODVW�LQ�WKH�NH\V�2�ZLOO�EH�ODVW�LQ�WKH�YDOXHV��LI�"c"�LV�WKH�ILUVW�NH\��3�ZLOO�EH�WKH�ILUVW�YDOXH��7KDW¦V�WUXH�DVORQJ�DV�\RX�GRQ¦W�PRGLI\�WKH�KDVK�EHWZHHQ�WKH�UHTXHVW�IRU�WKH�NH\V�DQG�WKH�RQH�IRU�WKHYDOXHV��,I�\RX�DGG�HOHPHQWV�WR�WKH�KDVK��3HUO�UHVHUYHV�WKH�ULJKW�WR�UHDUUDQJH�LW�DV�QHHGHG�WR�NHHS�WKH�DFFHVV�TXLFN� �,Q�D�VFDODU�FRQWH[W��WKHVH�IXQFWLRQV�JLYH�WKH�QXPEHU�RI�HOH�PHQWV��NH\�YDOXH�SDLUV��LQ�WKH�KDVK��7KH\�GR�WKLV�TXLWH�HIILFLHQWO\��ZLWKRXW�KDYLQJ�WRYLVLW�HDFK�HOHPHQW�RI�WKH�KDVK�

my $count = keys %hash; # gets 3, meaning three key-value pairs

2QFH�LQ�D�ORQJ�ZKLOH��\RX¦OO�VHH�WKDW�VRPHRQH�KDV�XVHG�D�KDVK�DV�D�%RROHDQ��WUXH�IDOVH�H[SUHVVLRQ��VRPHWKLQJ�OLNH�WKLV�

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

7KDW�ZLOO�EH�WUXH�LI��DQG�RQO\�LI��WKH�KDVK�KDV�DW�OHDVW�RQH�NH\�YDOXH�SDLU���6R��LW¦V�MXVWVD\LQJ��£,I�WKH�KDVK�LV�QRW�HPSW\�¤�%XW�WKLV�LV�D�SUHWW\�UDUH�FRQVWUXFW��DV�VXFK�WKLQJV�JR�

The each Function,I�\RX�ZLVK�WR�LWHUDWH�RYHU��WKDW�LV��H[DPLQH�HYHU\�HOHPHQW�RI��DQ�HQWLUH�KDVK��RQH�RI�WKHXVXDO�ZD\V�LV�WR�XVH�WKH�each�IXQFWLRQ��ZKLFK�UHWXUQV�D�NH\�YDOXH�SDLU�DV�D�WZR�HOHPHQWOLVW�®�2Q�HDFK�HYDOXDWLRQ�RI�WKLV�IXQFWLRQ�IRU�WKH�VDPH�KDVK��WKH�QH[W�VXFFHVVLYH�NH\�YDOXH�SDLU�LV�UHWXUQHG��XQWLO�DOO�WKH�HOHPHQWV�KDYH�EHHQ�DFFHVVHG��:KHQ�WKHUH�DUH�QRPRUH�SDLUV��each�UHWXUQV�DQ�HPSW\�OLVW�

,Q�SUDFWLFH��WKH�RQO\�ZD\�WR�XVH�each�LV�LQ�D�while�ORRS��VRPHWKLQJ�OLNH�WKLV�

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

2I�FRXUVH��LI�\RX�VWDUWHG�DGGLQJ�HOHPHQWV�WR�WKH�KDVK�EHWZHHQ�keys�DQG�values��\RXU�OLVW�RI�YDOXHV��RU�NH\V�ZKLFKHYHU�\RX�GLG�VHFRQG��ZRXOG�KDYH�DGGLWLRQDO�LWHPV��ZKLFK�ZRXOG�EH�WRXJK�WR�PDWFK�XS�ZLWK�WKH�ILUVWOLVW��6R�QR�QRUPDO�SURJUDPPHU�ZRXOG�GR�WKDW�

� 7KH�DFWXDO�UHVXOW�LV�DQ�LQWHUQDO�GHEXJJLQJ�VWULQJ�XVHIXO�WR�WKH�SHRSOH�ZKR�PDLQWDLQ�3HUO��,W�ORRNV�VRPHWKLQJOLNH�£�����¤�EXW�WKH�YDOXH�LV�JXDUDQWHHG�WR�EH�WUXH�ZKHQ�WKH�KDVK�LV�QRQHPSW\��DQG�IDOVH�ZKHQ�LW¦V�HPSW\��VRWKH�UHVW�RI�XV�FDQ�VWLOO�XVH�LW�IRU�WKDW�

® 7KH�RWKHU�XVXDO�ZD\�WR�LWHUDWH�RYHU�DQ�HQWLUH�KDVK�LV�WR�XVH�foreach�RQ�D�OLVW�RI�NH\V�IURP�WKH�KDVK��ZH¦OO�VHHWKDW�E\�WKH�HQG�RI�WKLV�VHFWLRQ�

Hash Functions | 101

7KHUH¦V�D�ORW�JRLQJ�RQ�KHUH��)LUVW��each %hash�UHWXUQV�D�NH\�YDOXH�SDLU�IURP�WKH�KDVK��DVD�WZR�HOHPHQW�OLVW��OHW¦V�VD\�WKDW�WKH�NH\�LV�"c"�DQG�WKH�YDOXH�LV�3��VR�WKH�OLVW�LV�("c",3)��7KDW�OLVW�LV�DVVLJQHG�WR�WKH�OLVW�($key, $value)��VR�$key�EHFRPHV�"c"��DQG�$valueEHFRPHV�3�

%XW�WKDW�OLVW�DVVLJQPHQW�LV�KDSSHQLQJ�LQ�WKH�FRQGLWLRQDO�H[SUHVVLRQ�RI�WKH�while�ORRS�ZKLFK�LV�D�VFDODU�FRQWH[W���6SHFLILFDOO\��LW¦V�D�%RROHDQ�FRQWH[W��ORRNLQJ�IRU�D�WUXH�IDOVHYDOXH��DQG�D�%RROHDQ�FRQWH[W�LV�D�SDUWLFXODU�NLQG�RI�VFDODU�FRQWH[W���7KH�YDOXH�RI�D�OLVWDVVLJQPHQW�LQ�D�VFDODU�FRQWH[W�LV�WKH�QXPEHU�RI�HOHPHQWV�LQ�WKH�VRXUFH�OLVW¢2��LQ�WKLVFDVH��6LQFH�2�LV�D�WUXH�YDOXH��ZH�HQWHU�WKH�ERG\�RI�WKH�ORRS�DQG�SULQW�WKH�PHVVDJH�c => 3�

7KH�QH[W�WLPH�WKURXJK�WKH�ORRS��each %hash�JLYHV�D�QHZ�NH\�YDOXH�SDLU��OHW¦V�VD\�LW¦V("a", 1)�WKLV�WLPH���,W�NQRZV�WR�UHWXUQ�D�GLIIHUHQW�SDLU�WKDQ�SUHYLRXVO\�EHFDXVH�LW�NHHSVWUDFN�RI�ZKHUH�LW�LV��LQ�WHFKQLFDO�MDUJRQ��WKHUH¦V�DQ�LWHUDWRU�VWRUHG�LQ�ZLWK�HDFK�KDVK� �7KRVH�WZR�LWHPV�DUH�VWRUHG�LQWR�($key, $value)��6LQFH�WKH�QXPEHU�RI�HOHPHQWV�LQ�WKHVRXUFH�OLVW�ZDV�DJDLQ�2¢D�WUXH�YDOXH¢WKH�while�FRQGLWLRQ�LV�WUXH��DQG�WKH�ORRS�ERG\UXQV�DJDLQ��WHOOLQJ�XV�a => 1�

:H�JR�RQH�PRUH�WLPH�WKURXJK�WKH�ORRS��DQG�E\�QRZ�ZH�NQRZ�ZKDW�WR�H[SHFW��VR�LW¦VQR�VXUSULVH�WR�VHH�b => 2�DSSHDU�LQ�WKH�RXWSXW�

%XW�ZH�NQHZ�LW�FRXOGQ¦W�JR�RQ�IRUHYHU��1RZ��ZKHQ�3HUO�HYDOXDWHV�each %hash��WKHUH�DUHQR�PRUH�NH\�YDOXH�SDLUV�DYDLODEOH��VR�each�KDV�WR�UHWXUQ�DQ�HPSW\�OLVW���7KH�HPSW\�OLVWLV�DVVLJQHG�WR�($key, $value)��VR�$key�JHWV�undef��DQG�$value�DOVR�JHWV�undef�

%XW�WKDW�KDUGO\�PDWWHUV�EHFDXVH�WKH�ZKROH�WKLQJ�LV�EHLQJ�HYDOXDWHG�LQ�WKH�FRQGLWLRQDOH[SUHVVLRQ�RI�WKH�while�ORRS��7KH�YDOXH�RI�D�OLVW�DVVLJQPHQW�LQ�D�VFDODU�FRQWH[W�LV�WKHQXPEHU�RI�HOHPHQWV�LQ�WKH�VRXUFH�OLVW¢LQ�WKLV�FDVH��WKDW¦V�0��6LQFH�0�LV�D�IDOVH�YDOXH��WKHwhile�ORRS�LV�GRQH��DQG�H[HFXWLRQ�FRQWLQXHV�ZLWK�WKH�UHVW�RI�WKH�SURJUDP�

2I�FRXUVH��each�UHWXUQV�WKH�NH\�YDOXH�SDLUV�LQ�D�MXPEOHG�RUGHU���,W¦V�WKH�VDPH�RUGHU�DVkeys�DQG�values�ZRXOG�JLYH��LQFLGHQWDOO\��WKH�£QDWXUDO¤�RUGHU�RI�WKH�KDVK���,I�\RX�QHHGWR�JR�WKURXJK�WKH�KDVK�LQ�RUGHU��VLPSO\�VRUW�WKH�NH\V��SHUKDSV�VRPHWKLQJ�OLNH�WKLV�

foreach $key (sort keys %hash) { $value = $hash{$key}; print "$key => $value\n"; # Or, we could have avoided the extra $value variable: # print "$key => $hash{$key}\n";}

6LQFH�HDFK�KDVK�KDV�LWV�RZQ�SULYDWH�LWHUDWRU��ORRSV�XVLQJ�each�PD\�EH�QHVWHG��DV�ORQJ�DV�WKH\�DUH�LWHUDWLQJ�RYHUGLIIHUHQW�KDVKHV��$QG��DV�ORQJ�DV�ZH¦UH�DOUHDG\�LQ�D�IRRWQRWH��ZH�PD\�DV�ZHOO�WHOO�\RX��LW¦V�XQOLNHO\�\RX¦OO�HYHUQHHG�WR�GR�VR��EXW�\RX�PD\�UHVHW�WKH�LWHUDWRU�RI�D�KDVK�E\�XVLQJ�WKH�keys�RU�values�IXQFWLRQ�RQ�WKH�KDVK��7KHLWHUDWRU�LV�DOVR�DXWRPDWLFDOO\�UHVHW�LI�D�QHZ�OLVW�LV�VWRUHG�LQWR�WKH�HQWLUH�KDVK��RU�LI�each�KDV�LWHUDWHG�WKURXJKDOO�RI�WKH�LWHPV�WR�WKH�£HQG¤�RI�WKH�KDVK��2Q�WKH�RWKHU�KDQG��DGGLQJ�QHZ�NH\�YDOXH�SDLUV�WR�WKH�KDVK�ZKLOHLWHUDWLQJ�RYHU�LW�LV�JHQHUDOO\�D�EDG�LGHD��VLQFH�WKDW�ZRQ¦W�QHFHVVDULO\�UHVHW�WKH�LWHUDWRU��7KDW¦V�OLNHO\�WR�FRQIXVH\RX��\RXU�PDLQWHQDQFH�SURJUDPPHU��DQG�each�DV�ZHOO�

� ,W¦V�EHLQJ�XVHG�LQ�OLVW�FRQWH[W��VR�LW�FDQ¦W�UHWXUQ�undef�WR�VLJQDO�IDLOXUH��WKDW�ZRXOG�EH�WKH�RQH�HOHPHQW�OLVW(undef)�LQVWHDG�RI�WKH�HPSW\��]HUR�HOHPHQW��OLVW�( )�

102 | Chapter 6:ಗHashes

:H¦OO�VHH�PRUH�DERXW�VRUWLQJ�KDVKHV�LQ�&KDSWHU����

Typical Use of a Hash$W�WKLV�SRLQW��\RX�PD\�ILQG�LW�KHOSIXO�WR�VHH�D�PRUH�FRQFUHWH�H[DPSOH�

7KH�%HGURFN�OLEUDU\�XVHV�D�3HUO�SURJUDP�LQ�ZKLFK�D�KDVK�NHHSV�WUDFN�RI�KRZ�PDQ\ERRNV�HDFK�SHUVRQ�KDV�FKHFNHG�RXW��DPRQJ�RWKHU�LQIRUPDWLRQ�

$books{"fred"} = 3;$books{"wilma"} = 1;

,W¦V�HDV\�WR�VHH�ZKHWKHU�DQ�HOHPHQW�RI�WKH�KDVK�LV�WUXH�RU�IDOVH��GR�WKLV�

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

%XW�WKHUH�DUH�VRPH�HOHPHQWV�RI�WKH�KDVK�WKDW�DUHQ¦W�WUXH�

$books{"barney"} = 0; # no books currently checked out$books{"pebbles"} = undef; # no books EVER checked out - a new library card

6LQFH�3HEEOHV�KDV�QHYHU�FKHFNHG�RXW�DQ\�ERRNV��KHU�HQWU\�KDV�WKH�YDOXH�RI�undef��UDWKHUWKDQ�0�

7KHUH¦V�D�NH\�LQ�WKH�KDVK�IRU�HYHU\RQH�ZKR�KDV�D�OLEUDU\�FDUG��)RU�HDFK�NH\��WKDW�LV��IRUHDFK�OLEUDU\�SDWURQ���WKHUH¦V�D�YDOXH�WKDW�LV�HLWKHU�D�QXPEHU�RI�ERRNV�FKHFNHG�RXW��RUundef�LI�WKDW�SHUVRQ¦V�OLEUDU\�FDUG�KDV�QHYHU�EHHQ�XVHG�

The exists Function7R�VHH�ZKHWKHU�D�NH\�H[LVWV�LQ�WKH�KDVK���WKDW�LV��ZKHWKHU�VRPHRQH�KDV�D�OLEUDU\�FDUG�RUQRW���XVH�WKH�exists�IXQFWLRQ��ZKLFK�UHWXUQV�D�WUXH�YDOXH�LI�WKH�JLYHQ�NH\�H[LVWV�LQ�WKHKDVK��ZKHWKHU�WKH�FRUUHVSRQGLQJ�YDOXH�LV�WUXH�RU�QRW�

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

7KDW�LV�WR�VD\��exists $books{"dino"}�ZLOO�UHWXUQ�D�WUXH�YDOXH�LI��DQG�RQO\�LI��dino�LVIRXQG�LQ�WKH�OLVW�RI�NH\V�IURP�keys %books�

The delete Function7KH�delete�IXQFWLRQ�UHPRYHV�WKH�JLYHQ�NH\��DQG�LWV�FRUUHVSRQGLQJ�YDOXH��IURP�WKH�KDVK��,I�WKHUH¦V�QR�VXFK�NH\��LWV�ZRUN�LV�GRQH��WKHUH¦V�QR�ZDUQLQJ�RU�HUURU�LQ�WKDW�FDVH��

my $person = "betty";delete $books{$person}; # Revoke the library card for $person

Typical Use of a Hash | 103

1RWH� WKDW� WKLV� LV�QRW� WKH�VDPH�DV�VWRULQJ�undef� LQWR� WKDW�KDVK�HOHPHQW¢LQ�IDFW�� LW¦VSUHFLVHO\�WKH�RSSRVLWH��&KHFNLQJ�exists($books{"betty"})�ZLOO�JLYH�RSSRVLWH�UHVXOWV�LQWKHVH�WZR�FDVHV��DIWHU�D�delete��WKH�NH\�FDQ¦W�H[LVW�LQ�WKH�KDVK��EXW�DIWHU�VWRULQJ�undef�WKH�NH\�PXVW�H[LVW�

,Q�WKH�H[DPSOH��delete�YHUVXV�VWRULQJ�undef�LV�WKH�GLIIHUHQFH�EHWZHHQ�WDNLQJ�DZD\�%HWW\¦VOLEUDU\�FDUG�YHUVXV�JLYLQJ�KHU�D�FDUG�WKDW�KDV�QHYHU�EHHQ�XVHG�

Hash Element Interpolation<RX�FDQ�LQWHUSRODWH�D�VLQJOH�KDVK�HOHPHQW�LQWR�D�GRXEOH�TXRWHG�VWULQJ�MXVW�DV�\RX¦GH[SHFW�

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

%XW�WKHUH¦V�QR�VXSSRUW�IRU�HQWLUH�KDVK�LQWHUSRODWLRQ��"%books"�LV�MXVW�WKH�VL[�FKDUDFWHUVRI��OLWHUDOO\��%books� �6R�\RX¦YH�VHHQ�DOO�RI�WKH�PDJLFDO�FKDUDFWHUV�WKDW�QHHG�EDFNVODVKLQJLQ�GRXEOH�TXRWHV��$�DQG�@��EHFDXVH�WKH\�LQWURGXFH�D�YDULDEOH�WKDW�3HUO�ZLOO�WU\�WR�LQWHU�SRODWH�� "�� VLQFH� WKDW¦V� WKH� TXRWLQJ� FKDUDFWHU� WKDW�ZRXOG� RWKHUZLVH� HQG� WKH� GRXEOH�TXRWHG�VWULQJ��DQG�\��WKH�EDFNVODVK�LWVHOI��$Q\�RWKHU�FKDUDFWHUV�LQ�D�GRXEOH�TXRWHG�VWULQJDUH�QRQPDJLFDO�DQG�VKRXOG�VLPSO\�VWDQG�IRU�WKHPVHOYHV��

The %ENV hash<RXU�3HUO�SURJUDP��OLNH�DQ\�RWKHU�SURJUDP��UXQV�LQ�D�FHUWDLQ�HQYLURQPHQW��DQG�\RXUSURJUDP�FDQ�ORRN�DW�WKH�HQYLURQPHQW�WR�JHW�LQIRUPDWLRQ�DERXW�LWV�VXUURXQGLQJV��3HUOVWRUHV�WKLV�LQIRUPDWLRQ�LQ�WKH�%ENV�KDVK��)RU�LQVWDQFH��\RX¦OO�SUREDEO\�VHH�D�PATH�NH\�LQ%ENV�

print "PATH is $ENV{PATH}\n";

'HSHQGLQJ�RQ�\RXU�SDUWLFXODU�VHWXS�DQG�RSHUDWLQJ�V\VWHP��\RX¦OO�VHH�VRPHWKLQJ�OLNHWKLV�

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

0RVW�RI�WKHVH�DUH�VHW�IRU�\RX�DXWRPDWLFDOO\��EXW�\RX�FDQ�DGG�WR�WKH�HQYLURQPHQW�\RXU�VHOI��+RZ�\RX�GR�WKLV�GHSHQGV�RQ�\RXU�RSHUDWLQJ�V\VWHP�DQG�VKHOO�

:HOO��LW�FRXOGQ¦W�UHDOO\�EH�DQ\WKLQJ�HOVH��LI�ZH�WULHG�WR�SULQW�RXW�WKH�HQWLUH�KDVK��DV�D�VHULHV�RI�NH\�YDOXH�SDLUV�WKDW�ZRXOG�EH�QHDUO\�XVHOHVV��$QG��DV�\RX�VDZ� LQ� WKH� ODVW�FKDSWHU�� WKH�SHUFHQW�VLJQ� LV� IUHTXHQWO\�XVHG� LQprintf�IRUPDW�VWULQJV��JLYLQJ�LW�DQRWKHU�PHDQLQJ�KHUH�ZRXOG�EH�WHUULEO\�LQFRQYHQLHQW�

� %XW�GR�EHZDUH�RI�WKH�DSRVWURSKH��'���OHIW�VTXDUH�EUDFNHW��[���OHIW�FXUO\�EUDFH��{���WKH�VPDOO�DUURZ��->���RU�GRXEOHFRORQ��::��IROORZLQJ�D�YDULDEOH�QDPH�LQ�D�GRXEOH�TXRWHG�VWULQJ��DV�WKH\�FRXOG�SHUKDSV�PHDQ�VRPHWKLQJ�\RXGLGQ¦W�LQWHQG�

104 | Chapter 6:ಗHashes

Bourne shell

$ CHARACTER=Fred; export CHARACTER $ export CHARACTER=Fred

csh

% setenv CHARACTER=Fred

DOS or Windows command

C:> set CHARACTER=Fred

2QFH�\RX�VHW�WKHVH�HQYLURQPHQW�YDULDEOHV�RXWVLGH�RI�\RXU�3HUO�SURJUDP��\RX�FDQ�DFFHVVWKHP�LQVLGH�\RXU�3HUO�SURJUDP�

print "CHARACTER is $ENV{CHARACTER}\n";

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >�@�:ULWH�D�SURJUDP�WKDW�ZLOO�DVN�WKH�XVHU�IRU�D�JLYHQ�QDPH�DQG�UHSRUW�WKH�FRUUH�VSRQGLQJ�IDPLO\�QDPH��8VH�WKH�QDPHV�RI�SHRSOH�\RX�NQRZ��RU��LI�\RX�VSHQG�VRPXFK�WLPH�RQ�WKH�FRPSXWHU�WKDW�\RX�GRQ¦W�NQRZ�DQ\�DFWXDO�SHRSOH��XVH�WKH�IRO�ORZLQJ�WDEOH�

Input Output

fred flintstone

barney rubble

wilma flintstone

�� >��@�:ULWH�D�SURJUDP�WKDW�UHDGV�D�VHULHV�RI�ZRUGV��ZLWK�RQH�ZRUG�SHU�OLQH ��XQWLOHQG�RI�LQSXW��WKHQ�SULQWV�D�VXPPDU\�RI�KRZ�PDQ\�WLPHV�HDFK�ZRUG�ZDV�VHHQ���+LQW�UHPHPEHU�WKDW�ZKHQ�DQ�XQGHILQHG�YDOXH�LV�XVHG�DV�LI�LW�ZHUH�D�QXPEHU��3HUO�DXWR�PDWLFDOO\�FRQYHUWV�LW�WR�0��,W�PD\�KHOS�WR�ORRN�EDFN�DW�WKH�HDUOLHU�H[HUFLVH�WKDW�NHSWD�UXQQLQJ�WRWDO���6R��LI�WKH�LQSXW�ZRUGV�ZHUH�fred��barney��fred��dino��wilma��fred�DOO�RQ�VHSDUDWH�OLQHV���WKH�RXWSXW�VKRXOG�WHOO�XV�WKDW�fred�ZDV�VHHQ�3�WLPHV��)RUH[WUD�FUHGLW��VRUW�WKH�VXPPDU\�ZRUGV�LQ�$6&,,�RUGHU�LQ�WKH�RXWSXW�

�� >��@�:ULWH�D�SURJUDP�WR�OLVW�DOO�RI�WKH�NH\V�DQG�YDOXHV�LQ�%ENV��3ULQW�WKH�UHVXOWV�LQWZR�FROXPQV�LQ�$6&,,EHWLFDO�RUGHU��)RU�H[WUD�FUHGLW��DUUDQJH�WKH�RXWSXW�WR�YHUWLFDOO\DOLJQ�ERWK�FROXPQV��7KH�length�IXQFWLRQ�FDQ�KHOS�\RX�ILJXUH�RXW�KRZ�ZLGH�WR�PDNHWKH�ILUVW�FROXPQ��2QFH�\RX�JHW�WKH�SURJUDP�UXQQLQJ��WU\�VHWWLQJ�VRPH�QHZ�HQYL�URQPHQW�YDULDEOHV�DQG�HQVXULQJ�WKDW�WKH\�VKRZ�XS�LQ�\RXU�RXWSXW�

,W�KDV�WR�EH�RQH�ZRUG�SHU�OLQH�EHFDXVH�ZH�VWLOO�KDYHQ¦W�VKRZQ�\RX�KRZ�WR�H[WUDFW�LQGLYLGXDO�ZRUGV�IURP�D�OLQHRI�LQSXW�

Exercises | 105

CHAPTER 7

In the World of Regular Expressions

3HUO�KDV�PDQ\�IHDWXUHV�WKDW�VHW�LW�DSDUW�IURP�RWKHU�ODQJXDJHV��2I�DOO�WKRVH�IHDWXUHV��RQHRI�WKH�PRVW�LPSRUWDQW�LV�LWV�VWURQJ�VXSSRUW�IRU�UHJXODU�H[SUHVVLRQV��7KHVH�DOORZ�IDVW�IOH[LEOH��DQG�UHOLDEOH�VWULQJ�KDQGOLQJ�

%XW�WKDW�SRZHU�FRPHV�DW�D�SULFH��5HJXODU�H[SUHVVLRQV�DUH�DFWXDOO\�WLQ\�SURJUDPV�LQ�WKHLURZQ�VSHFLDO�ODQJXDJH��EXLOW�LQVLGH�3HUO���<HV��\RX¦UH�DERXW�WR�OHDUQ�DQRWKHU�SURJUDP�PLQJ�ODQJXDJH� �)RUWXQDWHO\�LW¦V�D�VLPSOH�RQH���6R�LQ�WKLV�FKDSWHU��\RX¦OO�YLVLW�WKH�ZRUOGRI�UHJXODU�H[SUHVVLRQV��ZKHUH��PRVWO\��\RX�FDQ�IRUJHW�DERXW�WKH�ZRUOG�RI�3HUO��7KHQ��LQWKH�QH[W�FKDSWHU��ZH¦OO�VKRZ�\RX�ZKHUH�WKLV�ZRUOG�ILWV�LQWR�3HUO¦V�ZRUOG�

5HJXODU� H[SUHVVLRQV� DUHQ¦W�PHUHO\� SDUW� RI� 3HUO�� WKH\¦UH� DOVR� IRXQG� LQ� VHG� DQG�DZN�SURFPDLO��JUHS��PRVW�SURJUDPPHUV¦�WH[W�HGLWRUV�VXFK�DV�YL�DQG�HPDFV��DQG�HYHQ�LQ�PRUHHVRWHULF�SODFHV��,I�\RX¦YH�VHHQ�VRPH�RI�WKHVH�DOUHDG\��\RX¦UH�DKHDG�RI�WKH�JDPH��.HHSZDWFKLQJ��DQG�\RX¦OO�VHH�PDQ\�PRUH�WRROV�WKDW�XVH�RU�VXSSRUW�UHJXODU�H[SUHVVLRQV��VXFKDV�VHDUFK�HQJLQHV�RQ�WKH�:HE��RIWHQ�ZULWWHQ�LQ�3HUO���HPDLO�FOLHQWV��DQG�RWKHUV��7KH�EDGQHZV�LV�WKDW�HYHU\ERG\¦V�UHJXODU�H[SUHVVLRQV�KDYH�VOLJKWO\�GLIIHUHQW�V\QWD[��VR�\RX�PD\QHHG�WR�OHDUQ�WR�LQFOXGH�RU�RPLW�DQ�RFFDVLRQDO�EDFNVODVK�

What Are Regular Expressions?$�UHJXODU�H[SUHVVLRQ��RIWHQ�FDOOHG�D�SDWWHUQ�LQ�3HUO��LV�D�WHPSODWH�WKDW�HLWKHU�PDWFKHV�RUGRHVQ¦W�PDWFK�D�JLYHQ�VWULQJ���7KDW�LV��WKHUH�DUH�DQ�LQILQLWH�QXPEHU�RI�SRVVLEOH�WH[WVWULQJV��D�JLYHQ�SDWWHUQ�GLYLGHV�WKDW�LQILQLWH�VHW�LQWR�WZR�JURXSV��WKH�RQHV�WKDW�PDWFK�DQG�WKH�RQHV�WKDW�GRQ¦W��7KHUH¦V�QHYHU�DQ\�NLQGD�VRUWD�DOPRVW�XS�WR�KHUH�ZLVK\�ZDVK\PDWFKLQJ��HLWKHU�LW�PDWFKHV�RU�LW�GRHVQ¦W�

$�SDWWHUQ�PD\�PDWFK�MXVW�RQH�SRVVLEOH�VWULQJ��RU�MXVW�WZR�RU�WKUHH��RU�D�GR]HQ��RU�DKXQGUHG��RU�DQ�LQILQLWH�QXPEHU��2U�LW�PD\�PDWFK�DOO�VWULQJV�H[FHSW�IRU�RQH��RU�H[FHSW

6RPH�PLJKW�DUJXH�WKDW�UHJXODU�H[SUHVVLRQV�DUH�QRW�D�FRPSOHWH�SURJUDPPLQJ�ODQJXDJH��:H�ZRQ¦W�DUJXH�

� 3XULVWV�ZRXOG�DVN�IRU�D�PRUH�ULJRURXV�GHILQLWLRQ��%XW�WKHQ�DJDLQ��SXULVWV�VD\�WKDW�3HUO¦V�SDWWHUQV�DUHQ¦W�UHDOO\UHJXODU�H[SUHVVLRQV��,I�\RX¦UH�VHULRXV�DERXW�UHJXODU�H[SUHVVLRQV��ZH�KLJKO\�UHFRPPHQG�WKH�ERRN�0DVWHULQJ5HJXODU�([SUHVVLRQV�E\�-HIIUH\�)ULHGO��2¦5HLOO\��

107

IRU�VRPH��RU�H[FHSW�IRU�DQ�LQILQLWH�QXPEHU� �:H�DOUHDG\�UHIHUUHG�WR�UHJXODU�H[SUHVVLRQVDV�EHLQJ�OLWWOH�SURJUDPV�LQ�WKHLU�RZQ�VLPSOH�SURJUDPPLQJ�ODQJXDJH��,W¦V�D�VLPSOH�ODQ�JXDJH�EHFDXVH�WKH�SURJUDPV�KDYH�MXVW�RQH�WDVN��WR�ORRN�DW�D�VWULQJ�DQG�VD\�£LW�PDWFKHV¤RU�£LW�GRHVQ¦W�PDWFK�¤��7KDW¦V�DOO�WKH\�GR�

2QH�RI�WKH�SODFHV�\RX¦UH�OLNHO\�WR�KDYH�VHHQ�UHJXODU�H[SUHVVLRQV�LV�LQ�WKH�8QL[�JUHS�FRPPDQG��ZKLFK�SULQWV�RXW�WH[W�OLQHV�PDWFKLQJ�D�JLYHQ�SDWWHUQ��)RU�H[DPSOH��LI�\RXZDQWHG�WR�VHH�ZKLFK�OLQHV�LQ�D�JLYHQ�ILOH�PHQWLRQ�flint�DQG��VRPHZKHUH�ODWHU�RQ�WKHVDPH�OLQH��stone��\RX�PLJKW�GR�VRPHWKLQJ�OLNH�WKLV��ZLWK�WKH�8QL[�JUHS�FRPPDQG�

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

'RQ¦W� FRQIXVH� UHJXODU� H[SUHVVLRQV� ZLWK� VKHOO� ILOHQDPH�PDWFKLQJ� SDWWHUQV�� FDOOHGJOREV��$�W\SLFDO�JORE�LV�ZKDW�\RX�XVH�ZKHQ�\RX�W\SH�*.pm�WR�WKH�8QL[�VKHOO�WR�PDWFK�DOOILOHQDPHV�WKDW�HQG�LQ�.pm��7KH�SUHYLRXV�H[DPSOH�XVHV�D�JORE�RI�chapter*.txt���<RX�PD\KDYH�QRWLFHG�WKDW�\RX�KDG�WR�TXRWH�WKH�SDWWHUQ�WR�SUHYHQW�WKH�VKHOO�IURP�WUHDWLQJ�LW�OLNHD�JORE���$OWKRXJK�JOREV�XVH�D�ORW�RI�WKH�VDPH�FKDUDFWHUV�WKDW�\RX�XVH�LQ�UHJXODU�H[SUHV�VLRQV�� WKRVH�FKDUDFWHUV�DUH�XVHG� LQ�WRWDOO\�GLIIHUHQW�ZD\V�®�:H¦OO�YLVLW�JOREV� ODWHU�� LQ&KDSWHU�����EXW�IRU�QRZ�WU\�WR�SXW�WKHP�WRWDOO\�RXW�RI�\RXU�PLQG�

Using Simple Patterns7R�PDWFK�D�SDWWHUQ��UHJXODU�H[SUHVVLRQ��DJDLQVW�WKH�FRQWHQWV�RI�$_��VLPSO\�SXW�WKH�SDW�WHUQ�EHWZHHQ�D�SDLU�RI�IRUZDUG�VODVKHV��/���OLNH�ZH�GR�KHUH�

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

7KH�H[SUHVVLRQ�/abba/�ORRNV�IRU�WKDW�IRXU�OHWWHU�VWULQJ�LQ�$_��LI�LW�ILQGV�LW��LW�UHWXUQV�DWUXH�YDOXH��,Q�WKLV�FDVH��LW¦V�IRXQG�PRUH�WKDQ�RQFH��EXW�WKDW�GRHVQ¦W�PDNH�DQ\�GLIIHUHQFH�,I�LW¦V�IRXQG�DW�DOO��LW¦V�D�PDWFK��LI�LW¦V�QRW�LQ�WKHUH�DW�DOO��LW�IDLOV�

%HFDXVH�WKH�SDWWHUQ�PDWFK�LV�JHQHUDOO\�EHLQJ�XVHG�WR�UHWXUQ�D�WUXH�RU�IDOVH�YDOXH��LW�LVDOPRVW�DOZD\V�IRXQG�LQ�WKH�FRQGLWLRQDO�H[SUHVVLRQ�RI�if�RU�while�

$QG�DV�\RX¦OO�VHH��\RX�FRXOG�KDYH�D�SDWWHUQ�WKDW�DOZD\V�PDWFKHV�RU�WKDW�QHYHU�GRHV��,Q�UDUH�FDVHV��HYHQ�WKHVHPD\�EH�XVHIXO��*HQHUDOO\��WKRXJK��WKH\¦UH�PLVWDNHV�

� 7KH�SURJUDPV�DOVR�SDVV�EDFN�VRPH�LQIRUPDWLRQ�WKDW�3HUO�FDQ�XVH�ODWHU��2QH�VXFK�SLHFH�RI�LQIRUPDWLRQ�LV�WKH£UHJXODU�H[SUHVVLRQV�PHPRULHV¤�WKDW�\RX¦OO�OHDUQ�DERXW�D�OLWWOH�ODWHU�

® *OREV�DUH�DOVR��DODV��VRPHWLPHV�FDOOHG�SDWWHUQV��:KDW¦V�ZRUVH��WKRXJK�� LV�WKDW�VRPH�EDG�8QL[�ERRNV�IRUEHJLQQHUV��DQG�SRVVLEO\�ZULWWHQ�E\�EHJLQQHUV��KDYH�WDNHQ�WR�FDOOLQJ�JOREV�£UHJXODU�H[SUHVVLRQV�¤�ZKLFK�WKH\FHUWDLQO\�DUH�QRW��7KLV�FRQIXVHV�PDQ\�IRONV�DW�WKH�VWDUW�RI�WKHLU�ZRUN�ZLWK�8QL[�

108 | Chapter 7:ಗIn the World of Regular Expressions

$OO�RI� WKH�XVXDO�EDFNVODVK� HVFDSHV� WKDW� \RX�FDQ�SXW� LQWR�GRXEOH�TXRWHG� VWULQJV� DUHDYDLODEOH� LQ�SDWWHUQV�� VR�\RX�FRXOG�XVH� WKH�SDWWHUQ�/coke\tsprite/� WR�PDWFK� WKH���FKDUDFWHUV�RI�coke��D�WDE��DQG�sprite�

About Metacharacters2I�FRXUVH��LI�SDWWHUQV�PDWFKHG�RQO\�VLPSOH�OLWHUDO�VWULQJV��WKH\�ZRXOGQ¦W�EH�YHU\�XVHIXO�7KDW¦V�ZK\�WKHUH�DUH�D�QXPEHU�RI�VSHFLDO�FKDUDFWHUV��FDOOHG�PHWDFKDUDFWHUV��WKDW�KDYHVSHFLDO�PHDQLQJV�LQ�UHJXODU�H[SUHVVLRQV�

)RU�H[DPSOH��WKH�GRW��.��LV�D�ZLOGFDUG�FKDUDFWHU¢LW�PDWFKHV�DQ\�VLQJOH�FKDUDFWHU�H[FHSWD�QHZOLQH��ZKLFK�LV�UHSUHVHQWHG�E\�"\n"���6R��WKH�SDWWHUQ�/bet.y/�ZRXOG�PDWFK�betty�2U�LW�ZRXOG�PDWFK�betsy��RU�bet=y��RU�bet.y��RU�DQ\�RWKHU�VWULQJ�WKDW�KDV�bet��IROORZHGE\�DQ\�RQH�FKDUDFWHU� �H[FHSW�D�QHZOLQH��� IROORZHG�E\�y�� ,W�ZRXOGQ¦W�PDWFK�bety�RUbetsey��WKRXJK��VLQFH�WKRVH�GRQ¦W�KDYH�H[DFWO\�RQH�FKDUDFWHU�EHWZHHQ�WKH�t�DQG�WKH�y�7KH�GRW�DOZD\V�PDWFKHV�H[DFWO\�RQH�FKDUDFWHU�

6R��LI�\RX�ZDQWHG�WR�PDWFK�D�SHULRG�LQ�WKH�VWULQJ��\RX�FRXOG�XVH�WKH�GRW��%XW�WKDW�ZRXOGPDWFK�DQ\�SRVVLEOH�FKDUDFWHU��H[FHSW�D�QHZOLQH���ZKLFK�PLJKW�EH�PRUH�WKDQ�\RX�ZDQ�WHG��,I�\RX�ZDQWHG�WKH�GRW�WR�PDWFK�MXVW�D�SHULRG��\RX�FDQ�VLPSO\�EDFNVODVK�LW��,Q�IDFW�WKDW�UXOH�JRHV�IRU�DOO�RI�3HUO¦V�UHJXODU�H[SUHVVLRQ�PHWDFKDUDFWHUV��D�EDFNVODVK�LQ�IURQWRI�DQ\�PHWDFKDUDFWHU�PDNHV�LW�QRQVSHFLDO��6R��WKH�SDWWHUQ�/3\.14159/�GRHVQ¦W�KDYH�DZLOGFDUG�FKDUDFWHU�

6R�WKH�EDFNVODVK�LV�RXU�VHFRQG�PHWDFKDUDFWHU��,I�\RX�PHDQ�D�UHDO�EDFNVODVK��MXVW�XVH�DSDLU�RI�WKHP¢D�UXOH�WKDW�DSSOLHV�MXVW�DV�ZHOO�HYHU\ZKHUH�HOVH�LQ�3HUO�

Simple Quantifiers,W�RIWHQ�KDSSHQV�WKDW�\RX¦OO�QHHG�WR�UHSHDW�VRPHWKLQJ�LQ�D�SDWWHUQ��7KH�VWDU��*��PHDQVWR�PDWFK� WKH�SUHFHGLQJ� LWHP�]HUR�RU�PRUH� WLPHV�� 6R��/fred\t*barney/�PDWFKHV� DQ\QXPEHU� RI� WDE� FKDUDFWHUV� EHWZHHQ� fred� DQG� barney�� 7KDW� LV�� LW� PDWFKHV"fred\tbarney"�ZLWK�RQH�WDE��RU�"fred\t\tbarney"�ZLWK�WZR�WDEV��RU�"fred\t\t\tbarney"�ZLWK�WKUHH�WDEV��RU�HYHQ�"fredbarney"�ZLWK�QRWKLQJ�LQ�EHWZHHQ�DW�DOO��7KDW¦V�EH�FDXVH�WKH�VWDU�PHDQV�£]HUR�RU�PRUH¤¢VR�\RX�FRXOG�HYHQ�KDYH�KXQGUHGV�RI�WDE�FKDU�DFWHUV�LQ�EHWZHHQ��EXW�QRWKLQJ�RWKHU�WKDQ�WDEV��<RX�PD\�ILQG�LW�KHOSIXO�WR�WKLQN�RI�WKHVWDU�DV�VD\LQJ��£7KDW�SUHYLRXV�WKLQJ��DQ\�QXPEHU�RI�WLPHV��HYHQ�]HUR�WLPHV¤��EHFDXVH� LV�WKH�£WLPHV¤�RSHUDWRU�LQ�PXOWLSOLFDWLRQ��

:KDW�LI�\RX�ZDQWHG�WR�DOORZ�VRPHWKLQJ�EHVLGHV�WDE�FKDUDFWHUV"�7KH�GRW�PDWFKHV�DQ\FKDUDFWHU� �VR�.*�ZLOO�PDWFK�DQ\�FKDUDFWHU��DQ\�QXPEHU�RI�WLPHV��7KDW�PHDQV�WKDW�WKH

([FHSW�QHZOLQH��%XW�ZH¦UH�JRLQJ�WR�VWRS�UHPLQGLQJ�\RX�RI�WKDW�VR�RIWHQ�EHFDXVH�\RX�NQRZ�LW�E\�QRZ��0RVWRI�WKH�WLPH�LW�GRHVQ¦W�PDWWHU��DQ\ZD\��EHFDXVH�\RXU�VWULQJV�ZLOO�PRVW�RIWHQ�QRW�KDYH�QHZOLQHV��%XW�GRQ¦W�IRUJHWWKLV�GHWDLO�EHFDXVH�VRPHGD\�D�QHZOLQH�ZLOO�VQHDN�LQWR�\RXU�VWULQJ�DQG�\RX¦OO�QHHG�WR�UHPHPEHU�WKDW�WKH�GRWGRHVQ¦W�PDWFK�D�QHZOLQH�

Using Simple Patterns | 109

SDWWHUQ�/fred.*barney/�PDWFKHV�£DQ\�ROG�MXQN¤�EHWZHHQ�fred�DQG�barney��$Q\�OLQH�WKDWPHQWLRQV� fred� DQG� �VRPHZKHUH� ODWHU�� barney� ZLOO� PDWFK� WKDW� SDWWHUQ�� :H� RIWHQFDOO�.*�WKH�£DQ\�ROG�MXQN¤�SDWWHUQ�EHFDXVH�LW�FDQ�PDWFK�DQ\�ROG�MXQN�LQ�\RXU�VWULQJV�

7KH�VWDU�LV�IRUPDOO\�FDOOHG�D�TXDQWLILHU��PHDQLQJ�WKDW�LW�VSHFLILHV�D�TXDQWLW\�RI�WKH�SUH�FHGLQJ�LWHP��%XW�LW¦V�QRW�WKH�RQO\�TXDQWLILHU��WKH�SOXV��+��LV�DQRWKHU��7KH�SOXV�PHDQV�WRPDWFK� WKH� SUHFHGLQJ� LWHP� RQH� RU�PRUH� WLPHV�� /fred +barney/�PDWFKHV� LI� fred� DQGbarney�DUH�VHSDUDWHG�E\�VSDFHV�DQG�RQO\�VSDFHV���7KH�VSDFH�LV�QRW�D�PHWDFKDUDFWHU��7KLV�ZRQ¦W�PDWFK�fredbarney��VLQFH�WKH�SOXV�PHDQV�WKDW�WKHUH�PXVW�EH�RQH�RU�PRUHVSDFHV�EHWZHHQ�WKH�WZR�QDPHV��VR�DW�OHDVW�RQH�VSDFH�LV�UHTXLUHG��,W�PD\�EH�KHOSIXO�WRWKLQN�RI�WKH�SOXV�DV�VD\LQJ��£WKDW�ODVW�WKLQJ��SOXV��RSWLRQDOO\��PRUH�RI�WKH�VDPH�WKLQJ�¤

7KHUH¦V�D�WKLUG�TXDQWLILHU�OLNH�WKH�VWDU�DQG�SOXV��EXW�PRUH�OLPLWHG��,W¦V�WKH�TXHVWLRQ�PDUN�?���ZKLFK�PHDQV�WKDW�WKH�SUHFHGLQJ�LWHP�LV�RSWLRQDO��7KDW�LV��WKH�SUHFHGLQJ�LWHP�PD\RFFXU�RQFH�RU�QRW�DW�DOO��/LNH�WKH�RWKHU�WZR�TXDQWLILHUV��WKH�TXHVWLRQ�PDUN�PHDQV�WKDWWKH�SUHFHGLQJ�LWHP�DSSHDUV�D�FHUWDLQ�QXPEHU�RI�WLPHV��,W¦V�MXVW�WKDW�LQ�WKLV�FDVH�WKH�LWHPPD\�PDWFK�RQH�WLPH��LI� LW¦V� WKHUH��RU�]HUR�WLPHV��LI� LW¦V�QRW���7KHUH�DUHQ¦W�DQ\�RWKHUSRVVLELOLWLHV��6R��/bamm-?bamm/�PDWFKHV�HLWKHU�VSHOOLQJ��bamm-bamm�RU�bammbamm��7KLV�LVHDV\�WR�UHPHPEHU��VLQFH�LW¦V�VD\LQJ��£7KDW�ODVW�WKLQJ��PD\EH"�2U�PD\EH�QRW"¤

$OO�WKUHH�RI�WKHVH�TXDQWLILHUV�PXVW�IROORZ�VRPHWKLQJ��VLQFH�WKH\�WHOO�KRZ�PDQ\�WLPHVWKH�SUHYLRXV�LWHP�PD\�UHSHDW�

Grouping in Patterns$V�LQ�PDWKHPDWLFV��SDUHQWKHVHV��( )��PD\�EH�XVHG�IRU�JURXSLQJ��6R��SDUHQWKHVHV�DUH�DOVRPHWDFKDUDFWHUV�� $V� DQ� H[DPSOH�� WKH� SDWWHUQ� /fred+/� PDWFKHV� VWULQJV� OLNHfreddddddddd�� EXW� VWULQJV� OLNH� WKDW� GRQ¦W� VKRZ� XS� RIWHQ� LQ� UHDO� OLIH�� %XW� WKH� SDW�WHUQ�/(fred)+/�PDWFKHV�VWULQJV�OLNH�fredfredfred��ZKLFK�LV�PRUH�OLNHO\�WR�EH�ZKDW�\RXZDQWHG�� $QG� ZKDW� DERXW� WKH� SDWWHUQ� /(fred)*/"� 7KDW� PDWFKHV� VWULQJV� OLNH� hello,world�

7KH�SDUHQWKHVHV�DOVR�JLYH�XV�D�ZD\�WR�UHXVH�SDUW�RI�WKH�VWULQJ�GLUHFWO\�LQ�WKH�PDWFK��:HFDQ�XVH�EDFN�UHIHUHQFHV�WR�UHIHU�WR�WH[W�WKDW�ZH�PDWFKHG�LQ�WKH�SDUHQWKHVHV��:H�GHQRWHD�EDFN�UHIHUHQFH�DV�D�EDFNVODVK�IROORZHG�E\�D�QXPEHU��OLNH�\1��\2��DQG�VR�RQ��7KH�QXPEHUGHQRWHV�WKH�SDUHQWKHVHV�JURXS�

:KHQ�ZH�XVH�WKH�SDUHQWKHVHV�DURXQG�WKH�GRW��ZH�PDWFK�DQ\�QRQQHZOLQH�FKDUDFWHU�:H�FDQ�PDWFK�DJDLQ�ZKLFKHYHU�FKDUDFWHU�ZH�PDWFKHG�LQ�WKRVH�SDUHQWKHVHV�E\�XVLQJWKH�EDFN�UHIHUHQFH�\1�

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

7KH�VWDU�PHDQV�WR�PDWFK�]HUR�RU�PRUH�UHSHWLWLRQV�RI�fred��:KHQ�\RX¦UH�ZLOOLQJ�WR�VHWWOH�IRU�]HUR��LW¦V�KDUG�WREH�GLVDSSRLQWHG��7KDW�SDWWHUQ�ZLOO�PDWFK�DQ\�VWULQJ��HYHQ�WKH�HPSW\�VWULQJ�

110 | Chapter 7:ಗIn the World of Regular Expressions

7KH�(.)\1�VD\V�WKDW�ZH�KDYH�WR�PDWFK�D�FKDUDFWHU�ULJKW�QH[W�WR�LWVHOI��$W�ILUVW�WU\��WKH(.)�PDWFKHV�DQ�a��EXW�ZKHQ�LW�ORRNV�DW�WKH�EDFN�UHIHUHQFH¢ZKLFK�VD\V�WKH�QH[W�WKLQJLW�PXVW�PDWFK�LV�a¢WKDW�WULDO�IDLOV��3HUO�VWDUWV�RYHU��XVLQJ�WKH�(.)�WR�PDWFK�WKH�QH[WFKDUDFWHU��D�b��7KH�EDFN�UHIHUHQFH�\1�QRZ�VD\V�WKDW�WKH�QH[W�FKDUDFWHU�LQ�WKH�SDWWHUQ�LVb��ZKLFK�3HUO�FDQ�PDWFK�

7KH�EDFN�UHIHUHQFH�GRHVQ¦W�KDYH�WR�EH�ULJKW�QH[W�WR�WKH�SDUHQWKHVHV�JURXS��7KH�QH[WSDWWHUQ�PDWFKHV�DQ\�IRXU�QRQQHZOLQH�FKDUDFWHUV�DIWHU�D�OLWHUDO�y��DQG�ZH�XVH�WKH�\1�EDFNUHIHUHQFH�WR�GHQRWH�WKDW�ZH�ZDQW�WR�PDWFK�WKH�VDPH�IRXU�FKDUDFWHUV�DIWHU�WKH�d�

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

:H�FDQ�XVH�PXOWLSOH�JURXSV�RI�SDUHQWKHVHV��DQG�HDFK�JURXS�JHWV�LWV�RZQ�EDFN�UHIHUHQFH�:H�ZDQW�WR�PDWFK�D�QRQQHZOLQH�FKDUDFWHU�LQ�D�SDUHQWKHVHV�JURXS��IROORZHG�E\�DQRWKHUQRQQHZOLQH�FKDUDFWHU�LQ�D�SDUHQWKHVHV�JURXS��$IWHU�WKRVH�WZR�JURXSV��ZH�XVH�WKH�EDFNUHIHUHQFH�\2�IROORZHG�E\�WKH�EDFN�UHIHUHQFH�\1��,Q�HIIHFW��ZH¦UH�PDWFKLQJ�D�SDOLQGURPHVXFK�DV�abba�

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

1RZ��WKLV�EULQJV�XS�WKH�TXHVWLRQ�£+RZ�GR�,�NQRZ�ZKLFK�JURXS�JHWV�ZKLFK�QXPEHU"¤)RUWXQDWHO\��/DUU\�GLG�WKH�HDVLHVW�WKLQJ�IRU�KXPDQV�WR�XQGHUVWDQG��MXVW�FRXQW�WKH�RUGHURI�WKH�RSHQLQJ�SDUHQWKHVLV�DQG�LJQRUH�QHVWLQJ�

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

<RX�PLJKW�EH�DEOH�WR�VHH�WKLV�LI�\RX�ZULWH�RXW�WKH�UHJXODU�H[SUHVVLRQ�WR�VHH�WKH�GLIIHUHQWSDUWV��DOWKRXJK�WKLV�LVQ¦W�D�YDOLG�UHJXODU�H[SUHVVLRQ ��

( # first open parenthesis (.) # second open parenthesis (.) # third open parenthesis \3 \2)

3HUO������KDV�D�QHZ�ZD\�WR�GHQRWH�EDFN�UHIHUHQFHV��,QVWHDG�RI�XVLQJ�WKH�EDFNVODVK�DQGD�QXPEHU��LW�XVHV�\g{N}��ZKHUH�N�LV�WKH�QXPEHU�RI�WKH�EDFN�UHIHUHQFH�WKDW�\RX�ZDQW�WRXVH��7KLV�QRWDWLRQ�FDQ�PDNH�LW�HDVLHU�IRU�XV�WR�VKRZ�ZKDW�ZH�LQWHQG�LQ�WKH�SDWWHUQ�

<RX�FDQ�H[SDQG�UHJXODU�H[SUHVVLRQV�OLNH�WKLV�E\�XVLQJ�WKH�/x�IODJ��EXW�ZH¦UH�QRW�VKRZLQJ�WKDW�WR�\RX�XQWLO�WKHQH[W�FKDSWHU�

Using Simple Patterns | 111

&RQVLGHU�WKH�SUREOHP�ZKHUH�\RX�ZDQW�WR�XVH�D�EDFN�UHIHUHQFH�QH[W�WR�D�SDUW�RI�WKHSDWWHUQ�WKDW�LV�D�QXPEHU��,Q�WKLV�UHJXODU�H[SUHVVLRQ��ZH�ZDQW�WR�XVH�\1�WR�UHSHDW�WKHFKDUDFWHU�ZH�PDWFKHG�LQ�WKH�SDUHQWKHVHV�DQG�IROORZ�WKDW�ZLWK�WKH�OLWHUDO�VWULQJ�11�

$_ = "aa11bb";if (/(.)\111/) { print "It matched!\n";}

3HUO�KDV�WR�JXHVV�ZKDW�ZH�PHDQ�WKHUH��,V�WKDW�\1��\11��RU�\111"�3HUO�ZLOO�FUHDWH�DV�PDQ\EDFN�UHIHUHQFHV�DV�ZH�QHHG��VR�LW�DVVXPHV�WKDW�ZH�PHDQ�\111��6LQFH�ZH�GRQ¦W�KDYH�����RU�����SDUHQWKHVHV�JURXSV��3HUO�FRPSODLQV�ZKHQ�LW�WULHV�WR�FRPSLOH�WKH�SURJUDP�

%\�XVLQJ�\g{1}��ZH�GLVDPELJXDWH�WKH�EDFN�UHIHUHQFH�DQG�WKH�OLWHUDO�SDUWV�RI�WKH�SDWWHUQ�

use 5.010;

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

:LWK�WKH�\g{N}�QRWDWLRQ��ZH�FDQ�DOVR�XVH�QHJDWLYH�QXPEHUV��,QVWHDG�RI�VSHFLI\LQJ�WKHDEVROXWH�QXPEHU�RI�WKH�SDUHQWKHVHV�JURXS��ZH�FDQ�VSHFLI\�D�UHODWLYH�EDFN�UHIHUHQFH��:HFDQ�UHZULWH�WKH�ODVW�H[DPSOH�WR�XVH�!1�DV�WKH�QXPEHU�WR�GR�WKH�VDPH�WKLQJ�

use 5.010;

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

,I�,�GHFLGH�WR�DGG�PRUH�WR�WKDW�SDWWHUQ�ODWHU��,�GRQ¦W�KDYH�WR�UHPHPEHU�WR�FKDQJH�WKHEDFN�UHIHUHQFH��,I�,�DGG�DQRWKHU�SDUHQWKHVHV�JURXS��,�FKDQJH�WKH�DEVROXWH�QXPEHULQJRI�DOO�WKH�EDFN�UHIHUHQFHV��7KH�UHODWLYH�EDFN�UHIHUHQFH��KRZHYHU��MXVW�FRXQWV�IURP�LWVRZQ�SRVLWLRQ�DQG�UHIHUV�WR�WKH�JURXS�ULJKW�EHIRUH�LW�QR�PDWWHU�LWV�DEVROXWH�QXPEHU��VRLW�VWD\V�WKH�VDPH�

use 5.010;

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

Alternatives7KH�YHUWLFDO�EDU��|���RIWHQ�SURQRXQFHG�£RU¤�LQ�WKLV�XVDJH��PHDQV�WKDW�HLWKHU�WKH�OHIW�VLGHPD\�PDWFK��RU�WKH�ULJKW�VLGH��7KDW�LV��LI�WKH�SDUW�RI�WKH�SDWWHUQ�RQ�WKH�OHIW�RI�WKH�EDU�IDLOV�

,Q�JHQHUDO��ZH�FRXOG�OHDYH�WKH�FXUO\�EUDFHV�RII�WKH�\g{1}�DQG�MXVW�XVH�\g1��EXW�LQ�WKLV�FDVH�ZH�QHHG�WKH�EUDFHV�,QVWHDG�RI�WKLQNLQJ�DERXW�LW��ZH�MXVW�XVH�WKHP�DOO�WKH�WLPH�

112 | Chapter 7:ಗIn the World of Regular Expressions

WKH�SDUW�RQ�WKH�ULJKW�JHWV�D�FKDQFH�WR�PDWFK��6R��/fred|barney|betty/�ZLOO�PDWFK�DQ\VWULQJ�WKDW�PHQWLRQV�fred��RU�barney��RU�betty�

1RZ� \RX� FDQ�PDNH� SDWWHUQV� OLNH� /fred( |\t)+barney/��ZKLFK�PDWFKHV� LI� fred� DQGbarney�DUH�VHSDUDWHG�E\�VSDFHV��WDEV��RU�D�PL[WXUH�RI�WKH�WZR��7KH�SOXV�PHDQV�WR�UHSHDWRQH�RU�PRUH�WLPHV��HDFK�WLPH�LW�UHSHDWV��WKH�( |\t)�KDV�WKH�FKDQFH�WR�PDWFK�HLWKHU�DVSDFH�RU�D�WDE� �7KHUH�PXVW�EH�DW�OHDVW�RQH�RI�WKRVH�FKDUDFWHUV�EHWZHHQ�WKH�WZR�QDPHV�

,I�\RX�ZDQWHG�WKH�FKDUDFWHUV�EHWZHHQ�fred�DQG�barney�WR�DOO�EH�WKH�VDPH��\RX�FRXOGUHZULWH�WKDW�SDWWHUQ�DV�/fred( +|\t+)barney/��,Q�WKLV�FDVH��WKH�VHSDUDWRUV�PXVW�EH�DOOVSDFHV�RU�DOO�WDEV�

7KH�SDWWHUQ�/fred (and|or) barney/�PDWFKHV�DQ\�VWULQJ�FRQWDLQLQJ�HLWKHU�RI�WKH�WZRSRVVLEOH�VWULQJV��fred and barney��RU�fred or barney���<RX�FRXOG�PDWFK�WKH�VDPH�WZRVWULQJV�ZLWK�WKH�SDWWHUQ�/fred and barney|fred or barney/��EXW�WKDW�ZRXOG�EH�WRR�PXFKW\SLQJ��,W�ZRXOG�SUREDEO\�DOVR�EH�OHVV�HIILFLHQW��GHSHQGLQJ�XSRQ�ZKDW�RSWLPL]DWLRQVDUH�EXLOW�LQWR�WKH�UHJXODU�H[SUHVVLRQ�HQJLQH�

Character Classes$�FKDUDFWHU�FODVV��D�OLVW�RI�SRVVLEOH�FKDUDFWHUV�LQVLGH�VTXDUH�EUDFNHWV��[]���PDWFKHV�DQ\VLQJOH�FKDUDFWHU�IURP�ZLWKLQ�WKH�FODVV��,W�PDWFKHV�MXVW�RQH�VLQJOH�FKDUDFWHU��EXW�WKDW�RQHFKDUDFWHU�PD\�EH�DQ\�RI�WKH�RQHV�OLVWHG�

)RU�H[DPSOH��WKH�FKDUDFWHU�FODVV�[abcwxyz]�PD\�PDWFK�DQ\�RQH�RI�WKRVH�VHYHQ�FKDUDF�WHUV��)RU�FRQYHQLHQFH��\RX�PD\�VSHFLI\�D�UDQJH�RI�FKDUDFWHUV�ZLWK�D�K\SKHQ��-��VR�WKDWFODVV�PD\�DOVR�EH�ZULWWHQ�DV�[a-cw-z]��7KDW�GLGQ¦W�VDYH�PXFK�W\SLQJ��EXW�LW¦V�PRUH�XVXDOWR�PDNH�D�FKDUDFWHU�FODVV�OLNH�[a-zA-Z]�WR�PDWFK�DQ\�RQH�OHWWHU�RXW�RI�WKDW�VHW�RI����®

<RX�PD\�XVH�WKH�VDPH�FKDUDFWHU�VKRUWFXWV�DV�LQ�DQ\�GRXEOH�TXRWHG�VWULQJ�WR�GHILQH�DFKDUDFWHU��VR�WKH�FODVV�[\000-\177]�PDWFKHV�DQ\�VHYHQ�ELW�$6&,,�FKDUDFWHU��2I�FRXUVH�D�FKDUDFWHU�FODVV�ZLOO�EH�MXVW�SDUW�RI�D�IXOO�SDWWHUQ��LW�ZLOO�QHYHU�VWDQG�RQ�LWV�RZQ�LQ�3HUO�)RU�H[DPSOH��\RX�PLJKW�VHH�FRGH�WKDW�VD\V�VRPHWKLQJ�OLNH�WKLV�

$_ = "The HAL-9000 requires authorization to continue.";if (/HAL-[0-9]+/) { print "The string mentions some model of HAL computer.\n";}

7KLV�SDUWLFXODU�PDWFK�ZRXOG�QRUPDOO\�EH�GRQH�PRUH�HIILFLHQWO\�ZLWK�D�FKDUDFWHU�FODVV��DV�\RX¦OO�VHH�ODWHU�LQWKLV�FKDSWHU�

� 1RWH�WKDW�WKH�ZRUGV�and�DQG�or�DUH�QRW�RSHUDWRUV�LQ�UHJXODU�H[SUHVVLRQV��7KH\�DUH�VKRZQ�KHUH�LQ�D�IL[HG�ZLGWKW\SHIDFH�EHFDXVH�WKH\¦UH�SDUW�RI�WKH�VWULQJV�

® 1RWLFH�WKDW�WKRVH����GRQ¦W�LQFOXGH�OHWWHUV�OLNH�c��e��¹�����DQG�h��%XW�ZKHQ�8QLFRGH�SURFHVVLQJ�LV�DYDLODEOH�WKDW�SDUWLFXODU�FKDUDFWHU�UDQJH�LV�QRWLFHG�DQG�HQKDQFHG�WR�DXWRPDWLFDOO\�GR�WKH�ULJKW�WKLQJ�

$W�OHDVW��LI�\RX�XVH�$6&,,�DQG�QRW�(%&',&�

Character Classes | 113

6RPHWLPHV��LW¦V�HDVLHU�WR�VSHFLI\�WKH�FKDUDFWHUV�OHIW�RXW��UDWKHU�WKDQ�WKH�RQHV�ZLWKLQ�WKHFKDUDFWHU�FODVV��$�FDUHW��^��DW�WKH�VWDUW�RI�WKH�FKDUDFWHU�FODVV�QHJDWHV�LW��7KDW�LV��[^def]ZLOO�PDWFK�DQ\�VLQJOH�FKDUDFWHU�H[FHSW�RQH�RI�WKRVH�WKUHH��$QG�[^n\-z]�PDWFKHV�DQ\FKDUDFWHU�H[FHSW�IRU�n��K\SKHQ��RU�z���1RWH�WKDW�WKH�K\SKHQ�LV�EDFNVODVKHG�EHFDXVH�LW¦VVSHFLDO� LQVLGH�D�FKDUDFWHU�FODVV��%XW�WKH�ILUVW�K\SKHQ�LQ�/HAL-[0-9]+/�GRHVQ¦W�QHHG�DEDFNVODVK�EHFDXVH�K\SKHQV�DUHQ¦W�VSHFLDO�RXWVLGH�D�FKDUDFWHU�FODVV��

Character Class Shortcuts6RPH�FKDUDFWHU�FODVVHV�DSSHDU�VR�IUHTXHQWO\�WKDW�WKH\�KDYH�VKRUWFXWV��)RU�H[DPSOH��WKHFKDUDFWHU�FODVV�IRU�DQ\�GLJLW��[0-9]��PD\�EH�DEEUHYLDWHG�DV�\d��7KXV��WKH�SDWWHUQ�IURPWKH�H[DPSOH�DERXW�+$/�FRXOG�EH�ZULWWHQ�/HAL-\d+/�LQVWHDG�

7KH�VKRUWFXW�\w�LV�D�VR�FDOOHG�ZRUG�FKDUDFWHU��[A-Za-z0-9_]��,I�\RXU�£ZRUGV¤�DUH�PDGHXS�RI�RUGLQDU\�OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV��\RX¦OO�EH�KDSS\�ZLWK�WKLV��0RVW�RI�WKHUHVW�RI�XV�KDYH�ZRUGV�PDGH�XS�RI�RUGLQDU\�OHWWHUV��K\SKHQV��DQG�DSRVWURSKHV� �DQG�VRZH¦G�OLNH�WR�FKDQJH�WKLV�GHILQLWLRQ�RI�£ZRUG�¤�$V�RI�WKLV�ZULWLQJ��WKH�3HUO�GHYHORSHUV�DUHZRUNLQJ�RQ�LW��EXW�LW¦V�QRW�DYDLODEOH�\HW���6R�XVH�WKLV�RQH�RQO\�ZKHQ�\RX�ZDQW�RUGLQDU\OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV�

2I�FRXUVH��\w�GRHVQ¦W�PDWFK�D�£ZRUG¤��LW�PHUHO\�PDWFKHV�D�VLQJOH�£ZRUG¤�FKDUDFWHU��7RPDWFK�DQ�HQWLUH�ZRUG��WKRXJK��WKH�SOXV�PRGLILHU�LV�KDQG\��$�SDWWHUQ�OLNH�/fred \w+barney/�ZLOO�PDWFK�fred�DQG�D�VSDFH��WKHQ�D�£ZRUG�¤�WKHQ�D�VSDFH�DQG�barney��7KDW�LV�LW¦OO�PDWFK�LI�WKHUH¦V�RQH�ZRUG®�EHWZHHQ�fred�DQG�barney��VHW�RII�E\�VLQJOH�VSDFHV�

$V�\RX�PD\�KDYH�QRWLFHG�LQ�WKDW�SUHYLRXV�H[DPSOH��LW�PLJKW�EH�KDQG\�WR�EH�DEOH�WRPDWFK�VSDFHV�PRUH�IOH[LEO\��7KH�\s�VKRUWFXW�LV�JRRG�IRU�ZKLWHVSDFH��LW¦V�WKH�VDPH�DV[\f\t\n\r ]��7KDW�LV��LW¦V�WKH�VDPH�DV�D�FODVV�FRQWDLQLQJ�WKH�ILYH�ZKLWHVSDFH�FKDUDFWHUV�IRUP�IHHG��WDE��QHZOLQH��FDUULDJH�UHWXUQ��DQG�WKH�VSDFH�FKDUDFWHU�LWVHOI��7KHVH�DUH�WKHFKDUDFWHUV�WKDW�PHUHO\�PRYH�WKH�SULQWLQJ�SRVLWLRQ�DURXQG��WKH\�GRQ¦W�XVH�DQ\�LQN��6WLOO�OLNH�WKH�RWKHU�VKRUWFXWV�\RX¦YH�MXVW�VHHQ��\s�PDWFKHV�MXVW�D�VLQJOH�FKDUDFWHU�IURP�WKHFODVV��VR�LW¦V�XVXDO�WR�XVH�HLWKHU�\s*�IRU�DQ\�DPRXQW�RI�ZKLWHVSDFH��LQFOXGLQJ�QRQH�DWDOO���RU�\s+�IRU�RQH�RU�PRUH�ZKLWHVSDFH�FKDUDFWHUV���,Q�IDFW��LW¦V�UDUH�WR�VHH�\s�ZLWKRXWRQH�RI�WKRVH�TXDQWLILHUV���6LQFH�DOO�RI�WKRVH�ZKLWHVSDFH�FKDUDFWHUV�ORRN�DERXW�WKH�VDPHWR�XV�KXPDQV��\RX�FDQ�WUHDW�WKHP�DOO�LQ�WKH�VDPH�ZD\�ZLWK�WKLV�VKRUWFXW�

$W�OHDVW��LQ�XVXDO�(QJOLVK�\RX�GR��,Q�RWKHU�ODQJXDJHV��\RX�PD\�KDYH�GLIIHUHQW�FRPSRQHQWV�RI�ZRUGV��$QGZKHQ�ORRNLQJ�DW�$6&,,�HQFRGHG�(QJOLVK�WH[W��\RX�KDYH�WKH�SUREOHP�WKDW�WKH�VLQJOH�TXRWH�DQG�WKH�DSRVWURSKHDUH�WKH�VDPH�FKDUDFWHU��VR�LW¦V�QRW�SRVVLEOH�LQ�LVRODWLRQ�WR�WHOO�ZKHWKHU�cats'�LV�D�ZRUG�ZLWK�DQ�DSRVWURSKH�RUD�ZRUG�DW�WKH�HQG�RI�D�TXRWDWLRQ��7KLV�LV�SUREDEO\�RQH�UHDVRQ�WKDW�FRPSXWHUV�KDYHQ¦W�EHHQ�DEOH�WR�WDNH�RYHUWKH�ZRUOG�\HW�

� ([FHSW�WR�D�OLPLWHG��EXW�QHYHUWKHOHVV�XVHIXO��H[WHQW�LQ�FRQQHFWLRQ�ZLWK�ORFDOHV��VHH�WKH�SHUOORFDOH�PDQSDJH�

® :H¦UH�JRLQJ�WR�VWRS�VD\LQJ�£ZRUG¤�LQ�TXRWHV�VR�PXFK��\RX�NQRZ�E\�QRZ�WKDW�WKHVH�OHWWHU�GLJLW�XQGHUVFRUHZRUGV�DUH�WKH�RQHV�ZH�PHDQ�

114 | Chapter 7:ಗIn the World of Regular Expressions

3HUO������DGGV�PRUH�FKDUDFWHU�FODVVHV�IRU�ZKLWHVSDFH��7KH�\h�VKRUWFXW�RQO\�PDWFKHV�KRUL]RQWDO�ZKLWHVSDFH��ZKLFK�\RX�FDQ�ZULWH�DV�WKH�FKDUDFWHU�FODVV�[\t ]�WR�PDWFK�D�WDEDQG�D�VSDFH��7KH�\v�VKRUWFXW�RQO\�PDWFKHV�YHUWLFDO�ZKLWHVSDFH��RU�[\f\n\r]��7KH�\RVKRUWFXW�PDWFKHV�DQ\�VRUW�RI�OLQHEUHDN��PHDQLQJ�WKDW�\RX�GRQ¦W�KDYH�WR�WKLQN�DERXWZKLFK�RSHUDWLQJ�V\VWHP�\RX¦UH�XVLQJ�DQG�ZKDW�LW�WKLQNV�D�OLQHEUHDN�LV�VLQFH�\R�ZLOO�ILJXUHLW�RXW�

Negating the Shortcuts6RPHWLPHV�\RX�PD\�ZDQW�WKH�RSSRVLWH�RI�RQH�RI�WKHVH�WKUHH�VKRUWFXWV��7KDW�LV��\RX�PD\ZDQW�[^\d]��[^\w]��RU�[^\s]��PHDQLQJ�D�QRQGLJLW�FKDUDFWHU��D�QRQZRUG�FKDUDFWHU��RU�DQRQZKLWHVSDFH�FKDUDFWHU��7KDW¦V�HDV\�HQRXJK�WR�DFFRPSOLVK�E\�XVLQJ�WKHLU�XSSHUFDVHFRXQWHUSDUWV��\D��\W��RU�\S��7KHVH�PDWFK�DQ\�FKDUDFWHU�WKDW�WKHLU�FRXQWHUSDUW�ZRXOGQRW�PDWFK�

$Q\�RI�WKHVH�VKRUWFXWV�ZLOO�ZRUN�HLWKHU�LQ�SODFH�RI�D�FKDUDFWHU�FODVV��VWDQGLQJ�RQ�WKHLURZQ�LQ�D�SDWWHUQ���RU�LQVLGH�WKH�VTXDUH�EUDFNHWV�RI�D�ODUJHU�FKDUDFWHU�FODVV��7KDW�PHDQVWKDW�\RX�FRXOG�QRZ�XVH�/[\dA-Fa-f]+/�WR�PDWFK�KH[DGHFLPDO��EDVH�����QXPEHUV��ZKLFKXVH�OHWWHUV�ABCDEF��RU�WKH�VDPH�OHWWHUV�LQ�ORZHUFDVH��DV�DGGLWLRQDO�GLJLWV�

$QRWKHU�FRPSRXQG�FKDUDFWHU�FODVV�LV�[\d\D]��ZKLFK�PHDQV�DQ\�GLJLW��RU�DQ\�QRQGLJLW�7KDW�LV�WR�VD\��DQ\�FKDUDFWHU�DW�DOO��7KLV�LV�D�FRPPRQ�ZD\�WR�PDWFK�DQ\�FKDUDFWHU��HYHQD�QHZOLQH���$V�RSSRVHG�WR�.��ZKLFK�PDWFKHV�DQ\�FKDUDFWHU�H[FHSW�D�QHZOLQH���$QG�WKHQWKHUH¦V�WKH�WRWDOO\�XVHOHVV�[^\d\D]��ZKLFK�PDWFKHV�DQ\WKLQJ�WKDW¦V�QRW�HLWKHU�D�GLJLW�RUD�QRQGLJLW��5LJKW¢QRWKLQJ�

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV��UHPHPEHU��LW¦V�QRUPDO�WR�EHVXUSULVHG�E\�VRPH�RI�WKH�WKLQJV�WKDW�UHJXODU�H[SUHVVLRQV�GR��WKDW¦V�RQH�UHDVRQ�WKDW�WKHH[HUFLVHV�LQ�WKLV�FKDSWHU�DUH�HYHQ�PRUH�LPSRUWDQW�WKDQ�WKH�RWKHUV��([SHFW�WKH�XQH[�SHFWHG��

�� >��@�0DNH� D� SURJUDP� WKDW� SULQWV� HDFK� OLQH� RI� LWV� LQSXW� WKDW�PHQWLRQV� fred�� �,WVKRXOGQ¦W�GR�DQ\WKLQJ�IRU�RWKHU�OLQHV�RI�LQSXW���'RHV�LW�PDWFK�LI�\RXU�LQSXW�VWULQJLV�Fred��frederick��RU�Alfred"�0DNH�D�VPDOO�WH[W�ILOH�ZLWK�D�IHZ�OLQHV�PHQWLRQLQJ£IUHG�IOLQWVWRQH¤�DQG�KLV�IULHQGV��WKHQ�XVH�WKDW�ILOH�DV�LQSXW�WR�WKLV�SURJUDP�DQG�WKHRQHV�ODWHU�LQ�WKLV�VHFWLRQ�

�� >�@�0RGLI\�WKH�SUHYLRXV�SURJUDP�WR�DOORZ�Fred�WR�PDWFK�DV�ZHOO��'RHV�LW�PDWFKQRZ�LI�\RXU�LQSXW�VWULQJ�LV�Fred��frederick��RU�Alfred"��$GG�OLQHV�ZLWK�WKHVH�QDPHVWR�WKH�WH[W�ILOH��

�� >�@�0DNH�D�SURJUDP�WKDW�SULQWV�HDFK�OLQH�RI�LWV�LQSXW�WKDW�FRQWDLQV�D�SHULRG��.��LJQRULQJ�RWKHU�OLQHV�RI�LQSXW��7U\�LW�RQ�WKH�VPDOO�WH[W�ILOH�IURP�WKH�SUHYLRXV�H[HUFLVH�GRHV�LW�QRWLFH�Mr. Slate"

Exercises | 115

�� >�@�0DNH�D�SURJUDP�WKDW�SULQWV�HDFK�OLQH�WKDW�KDV�D�ZRUG�WKDW�LV�FDSLWDOL]HG�EXW�QRW$//�FDSLWDOL]HG��'RHV�LW�PDWFK�Fred�EXW�QHLWKHU�fred�QRU�FRED"

�� >�@�0DNH�D�SURJUDP�WKDW�SULQWV�HDFK�OLQH�WKDW�KDV�D�WZR�RI�WKH�VDPH�QRQZKLWHVSDFHFKDUDFWHUV�QH[W�WR�HDFK�RWKHU��,W�VKRXOG�PDWFK�OLQHV�WKDW�FRQWDLQ�ZRUGV�VXFK�DVMississippi��Bamm-Bamm��RU�llama�

�� >�@�([WUD�FUHGLW�H[HUFLVH��ZULWH�D�SURJUDP�WKDW�SULQWV�RXW�DQ\�LQSXW�OLQH�WKDW�PHQ�WLRQV�ERWK�wilma�DQG�fred�

116 | Chapter 7:ಗIn the World of Regular Expressions

CHAPTER 8

Matching with Regular Expressions

,Q�WKH�SUHYLRXV�FKDSWHU��\RX�YLVLWHG�WKH�ZRUOG�RI�UHJXODU�H[SUHVVLRQV��1RZ�\RX¦OO�VHHKRZ�WKDW�ZRUOG�ILWV�LQWR�WKH�ZRUOG�RI�3HUO�

Matches with m//:H¦YH�EHHQ�ZULWLQJ�SDWWHUQV�LQ�SDLUV�RI�IRUZDUG�VODVKHV��OLNH�/fred/��%XW�WKLV�LV�DFWXDOO\D�VKRUWFXW�IRU�WKH�m//��SDWWHUQ�PDWFK��RSHUDWRU��$V�\RX�VDZ�ZLWK�WKH�qw//�RSHUDWRU��\RXPD\�FKRRVH�DQ\�SDLU�RI�GHOLPLWHUV�WR�TXRWH�WKH�FRQWHQWV��6R�\RX�FRXOG�ZULWH�WKDW�VDPHH[SUHVVLRQ�DV�m(fred)��m<fred>��m{fred}��RU�m[fred]�XVLQJ�WKRVH�SDLUHG�GHOLPLWHUV��RU�DVm,fred,��m!fred!��m^fred^��RU�PDQ\�RWKHU�ZD\V�XVLQJ�QRQSDLUHG�GHOLPLWHUV�

7KH�VKRUWFXW�LV�WKDW�LI�\RX�FKRRVH�WKH�IRUZDUG�VODVK�DV�WKH�GHOLPLWHU��\RX�PD\�RPLW�WKHLQLWLDO�m��6LQFH�3HUO�IRONV�ORYH�WR�DYRLG�W\SLQJ�H[WUD�FKDUDFWHUV��\RX¦OO�VHH�PRVW�SDWWHUQPDWFKHV�ZULWWHQ�XVLQJ�VODVKHV��DV�LQ�/fred/�

2I�FRXUVH��\RX�VKRXOG�ZLVHO\�FKRRVH�D�GHOLPLWHU�WKDW�GRHVQ¦W�DSSHDU�LQ�\RXU�SDWWHUQ��

,I�\RX�ZDQWHG�WR�PDNH�D�SDWWHUQ�WR�PDWFK�WKH�EHJLQQLQJ�RI�DQ�RUGLQDU\�ZHE�85/��\RXPLJKW�VWDUW�WR�ZULWH�/http:\/\//�WR�PDWFK�WKH�LQLWLDO�"http://"��%XW�WKDW¦V�HDVLHU�WR�UHDG�ZULWH��PDLQWDLQ��DQG�GHEXJ�LI�\RX�XVH�D�EHWWHU�FKRLFH�RI�GHOLPLWHU��m%http://%�®� ,W¦VFRPPRQ�WR�XVH�FXUO\�EUDFHV�DV�WKH�GHOLPLWHU��,I�\RX�XVH�D�SURJUDPPHU¦V�WH[W�HGLWRU��LW

1RQSDLUHG�GHOLPLWHUV�DUH�WKH�RQHV�WKDW�GRQ¦W�KDYH�D�GLIIHUHQW�£OHIW¤�DQG�£ULJKW¤�YDULHW\��WKH�VDPH�SXQFWXDWLRQPDUN�LV�XVHG�IRU�ERWK�HQGV�

� ,I�\RX¦UH�XVLQJ�SDLUHG�GHOLPLWHUV��\RX�VKRXOGQ¦W�JHQHUDOO\�KDYH�WR�ZRUU\�DERXW�XVLQJ�WKH�GHOLPLWHU�LQVLGH�WKHSDWWHUQ�� VLQFH� WKDW�GHOLPLWHU�ZLOO�JHQHUDOO\�EH�SDLUHG� LQVLGH�\RXU�SDWWHUQ��7KDW� LV��m(fred(.*)barney)� DQGm{\w{2,}}�DQG�m[wilma[\n\t]+betty]�DUH�DOO�ILQH��HYHQ�WKRXJK�WKH�SDWWHUQ�FRQWDLQV�WKH�TXRWLQJ�FKDUDFWHU�VLQFH�HDFK�£OHIW¤�KDV�D�FRUUHVSRQGLQJ�£ULJKW�¤�%XW� WKH�DQJOH�EUDFNHWV� �<� DQG�>��DUHQ¦W� UHJXODU�H[SUHVVLRQPHWDFKDUDFWHUV��VR�WKH\�PD\�QRW�EH�SDLUHG��LI�WKH�SDWWHUQ�ZHUH�m{(\d+)\s*>=?\s*(\d+)}��TXRWLQJ�LW�ZLWK�DQJOHEUDFNHWV�ZRXOG�PHDQ�KDYLQJ� WR�EDFNVODVK� WKH�JUHDWHU�WKDQ� VLJQ� VR� WKDW� LW�ZRXOGQ¦W�SUHPDWXUHO\�HQG� WKHSDWWHUQ�

® 5HPHPEHU��WKH�IRUZDUG�VODVK�LV�QRW�D�PHWDFKDUDFWHU��VR�\RX�GRQ¦W�QHHG�WR�HVFDSH�LW�ZKHQ�LW¦V�QRW�WKH�GHOLPLWHU�

117

SUREDEO\�KDV�WKH�DELOLW\�WR� MXPS�IURP�DQ�RSHQLQJ�FXUO\�EUDFH�WR�WKH�FRUUHVSRQGLQJFORVLQJ�RQH��ZKLFK�FDQ�EH�KDQG\�LQ�PDLQWDLQLQJ�FRGH�

Option Modifiers7KHUH�DUH�VHYHUDO�RSWLRQ�PRGLILHU�OHWWHUV��VRPHWLPHV�FDOOHG�IODJV��ZKLFK�PD\�EH�DSSHQ�GHG�DV�D�JURXS�ULJKW�DIWHU�WKH�HQGLQJ�GHOLPLWHU�RI�D�UHJXODU�H[SUHVVLRQ�WR�FKDQJH�LWVEHKDYLRU�IURP�WKH�GHIDXOW�

Case-Insensitive Matching with /i7R�PDNH�D�FDVH�LQVHQVLWLYH�SDWWHUQ�PDWFK��VR�\RX�FDQ�PDWFK�FRED�DV�HDVLO\�DV�fred�RUFred��XVH�WKH�/i�PRGLILHU�

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

Matching Any Character with /s%\�GHIDXOW��WKH�GRW��.��GRHVQ¦W�PDWFK�QHZOLQH��DQG�WKLV�PDNHV�VHQVH�IRU�PRVW�£ORRNZLWKLQ�D�VLQJOH�OLQH¤�SDWWHUQV��,I�\RX�PLJKW�KDYH�QHZOLQHV�LQ�\RXU�VWULQJV��DQG�\RX�ZDQWWKH�GRW� WR�EH�DEOH� WR�PDWFK�WKHP��WKH�/s�PRGLILHU�ZLOO�GR�WKH� MRE�� ,W�FKDQJHV�HYHU\GRW �LQ�WKH�SDWWHUQ�WR�DFW�OLNH�WKH�FKDUDFWHU�FODVV�[\d\D]�GRHV��ZKLFK�LV�WR�PDWFK�DQ\FKDUDFWHU��HYHQ�LI�LW�LV�D�QHZOLQH��2I�FRXUVH��\RX�KDYH�WR�KDYH�D�VWULQJ�ZLWK�QHZOLQHV�IRUWKLV�WR�PDNH�D�GLIIHUHQFH�

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

:LWKRXW�WKH�/s�PRGLILHU��WKDW�PDWFK�ZRXOG�IDLO��VLQFH�WKH�WZR�QDPHV�DUHQ¦W�RQ�WKH�VDPHOLQH�

Adding Whitespace with /x7KH�WKLUG�PRGLILHU�\RX¦OO�VHH�DOORZV�\RX�WR�DGG�DUELWUDU\�ZKLWHVSDFH�WR�D�SDWWHUQ�WRPDNH�LW�HDVLHU�WR�UHDG�

/-?\d+\.?\d*/ # what is this doing?/ -? \d+ \.? \d* /x # a little better

,I�\RX�ZLVK�WR�FKDQJH�MXVW�VRPH�RI�WKHP��DQG�QRW�DOO��\RX¦OO�SUREDEO\�ZDQW�WR�UHSODFH�MXVW�WKRVH�IHZ�ZLWK[\d\D]�

118 | Chapter 8:ಗMatching with Regular Expressions

6LQFH�WKH�/x�DOORZV�ZKLWHVSDFH�LQVLGH�WKH�SDWWHUQ��D�OLWHUDO�VSDFH�RU�WDE�FKDUDFWHU�ZLWKLQWKH�SDWWHUQ�LV�LJQRUHG��<RX�FRXOG�XVH�D�EDFNVODVKHG�VSDFH�RU�\t��DPRQJ�PDQ\�RWKHUZD\V��WR�PDWFK�WKHVH��EXW�LW¦V�PRUH�FRPPRQ�WR�XVH�\s��RU�\s*�RU�\s+��ZKHQ�\RX�ZDQWWR�PDWFK�ZKLWHVSDFH�DQ\ZD\�

5HPHPEHU�WKDW�LQ�3HUO��FRPPHQWV�PD\�EH�LQFOXGHG�DV�SDUW�RI�WKH�ZKLWHVSDFH��1RZ�ZHFDQ�SXW�FRPPHQWV�LQWR�WKDW�SDWWHUQ�WR�WHOO�ZKDW�LW¦V�UHDOO\�GRLQJ�

/ -? # an optional minus sign \d+ # one or more digits before the decimal point \.? # an optional decimal point \d* # some optional digits after the decimal point/x # end of string

6LQFH�WKH�SRXQG�VLJQ�LQGLFDWHV�WKH�VWDUW�RI�D�FRPPHQW��XVH�\#�RU�[#]�LQ�WKH�UDUH�FDVHWKDW�\RX�QHHG�WR�PDWFK�D�SRXQG�VLJQ��$QG�EH�FDUHIXO�QRW�WR�LQFOXGH�WKH�FORVLQJ�GHOLPLWHULQVLGH�WKH�FRPPHQWV��RU�LW�ZLOO�SUHPDWXUHO\�WHUPLQDWH�WKH�SDWWHUQ�

Combining Option Modifiers,I�\RX�KDYH�PRUH�WKDQ�RQH�RSWLRQ�PRGLILHU�WR�XVH�RQ�WKH�VDPH�SDWWHUQ��WKH\�PD\�EHXVHG�RQH�DIWHU�WKH�RWKHU��WKHLU�RUGHU�LVQ¦W�VLJQLILFDQW��

if (/barney.*fred/is) { # both /i and /s print "That string mentions Fred after Barney!\n";}

2U�DV�D�PRUH�H[SDQGHG�YHUVLRQ�ZLWK�FRPPHQWV�

if (m{ barney # the little guy .* # anything in between fred # the loud guy}six) { # all three of /s and /i and /x print "That string mentions Fred after Barney!\n";}

1RWH�WKH�VKLIW�WR�FXUO\�EUDFHV�KHUH�IRU�WKH�GHOLPLWHUV�DV�ZHOO��DOORZLQJ�SURJUDPPHU�VW\OHHGLWRUV�WR�HDVLO\�ERXQFH�IURP�WKH�EHJLQQLQJ�WR�WKH�HQG�RI�WKH�UHJXODU�H[SUHVVLRQ�

Other Options7KHUH�DUH�PDQ\�RWKHU�RSWLRQ�PRGLILHUV�DYDLODEOH��:H¦OO�FRYHU�WKRVH�DV�ZH�JHW�WR�WKHP�RU�\RX�FDQ�UHDG�DERXW�WKHP�LQ�WKH�SHUORS�PDQSDJH�DQG�LQ�WKH�GHVFULSWLRQV�RI�m//�DQGWKH�RWKHU�UHJXODU�H[SUHVVLRQ�RSHUDWRUV�WKDW�\RX¦OO�VHH�ODWHU�LQ�WKLV�FKDSWHU�

Option Modifiers | 119

Anchors%\�GHIDXOW��LI�D�SDWWHUQ�GRHVQ¦W�PDWFK�DW�WKH�VWDUW�RI�WKH�VWULQJ��LW�FDQ�£IORDW¤�RQ�GRZQWKH�VWULQJ��WU\LQJ�WR�PDWFK�VRPHZKHUH�HOVH��%XW�WKHUH�DUH�D�QXPEHU�RI�DQFKRUV�WKDW�PD\EH�XVHG�WR�KROG�WKH�SDWWHUQ�DW�D�SDUWLFXODU�SRLQW�LQ�D�VWULQJ�

7KH�FDUHW �DQFKRU��^��PDUNV�WKH�EHJLQQLQJ�RI�WKH�VWULQJ��ZKLOH�WKH�GROODU�VLJQ��$��PDUNVWKH� HQG��� 6R� WKH� SDWWHUQ� /^fred/�ZLOO�PDWFK� fred� RQO\� DW� WKH� VWDUW� RI� WKH� VWULQJ�� LWZRXOGQ¦W�PDWFK�manfred mann��$QG�/rock$/�ZLOO�PDWFK�rock�RQO\�DW�WKH�HQG�RI�WKH�VWULQJ�LW�ZRXOGQ¦W�PDWFK�knute rockne�

6RPHWLPHV�\RX¦OO�ZDQW�WR�XVH�ERWK�RI�WKHVH�DQFKRUV�WR�HQVXUH�WKDW�WKH�SDWWHUQ�PDWFKHVDQ�HQWLUH�VWULQJ��$�FRPPRQ�H[DPSOH�LV�/^\s*$/��ZKLFK�PDWFKHV�D�EODQN�OLQH��%XW�WKLV£EODQN¤�OLQH�PD\�LQFOXGH�VRPH�ZKLWHVSDFH�FKDUDFWHUV��OLNH�WDEV�DQG�VSDFHV��ZKLFK�DUHLQYLVLEOH�WR�\RX�DQG�PH��$Q\�OLQH�WKDW�PDWFKHV�WKDW�SDWWHUQ�ORRNV�MXVW�OLNH�DQ\�RWKHURQH�RQ�SDSHU��VR�WKLV�SDWWHUQ�WUHDWV�DOO�EODQN�OLQHV�DV�HTXLYDOHQW��:LWKRXW�WKH�DQFKRUV�LW�ZRXOG�PDWFK�QRQEODQN�OLQHV�DV�ZHOO�

Word Anchors$QFKRUV�DUHQ¦W�MXVW�DW�WKH�HQGV�RI�WKH�VWULQJ��7KH�ZRUG�ERXQGDU\�DQFKRU��\b��PDWFKHVDW�HLWKHU�HQG�RI�D�ZRUG�®�6R�\RX�FDQ�XVH�/\bfred\b/�WR�PDWFK�WKH�ZRUG�fred�EXW�QRWfrederick�RU�alfred�RU�manfred mann��7KLV�LV�VLPLODU�WR�WKH�IHDWXUH�RIWHQ�FDOOHG�VRPHWKLQJOLNH�£PDWFK�ZKROH�ZRUGV�RQO\¤�LQ�D�ZRUG�SURFHVVRU¦V�VHDUFK�FRPPDQG�

$ODV��WKHVH�DUHQ¦W�ZRUGV�DV�\RX�DQG�,�DUH�OLNHO\�WR�WKLQN�RI�WKHP��WKH\¦UH�WKRVH�\w�W\SHZRUGV�PDGH�XS�RI�RUGLQDU\�OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV��7KH�\b�DQFKRU�PDWFKHV�DWWKH�VWDUW�RU�HQG�RI�D�JURXS�RI�\w�FKDUDFWHUV�

,Q�)LJXUH������WKHUH¦V�D�JUD\�XQGHUOLQH�XQGHU�HDFK�£ZRUG�¤�DQG�WKH�DUURZV�VKRZ�WKHFRUUHVSRQGLQJ�SODFHV�ZKHUH�\b�FRXOG�PDWFK��7KHUH�DUH�DOZD\V�DQ�HYHQ�QXPEHU�RI�ZRUGERXQGDULHV�LQ�D�JLYHQ�VWULQJ��VLQFH�WKHUH¦V�DQ�HQG�RI�ZRUG�IRU�HYHU\�VWDUW�RI�ZRUG�

<HV��\RX¦YH�VHHQ�WKH�FDUHW�XVHG�LQ�DQRWKHU�ZD\�LQ�SDWWHUQV��$V�WKH�ILUVW�FKDUDFWHU�RI�D�FKDUDFWHU�FODVV��LW�QHJDWHVWKH�FODVV��%XW�RXWVLGH�RI�D�FKDUDFWHU�FODVV��LW¦V�D�PHWDFKDUDFWHU�LQ�D�GLIIHUHQW�ZD\��EHLQJ�WKH�VWDUW�RI�VWULQJDQFKRU��7KHUH�DUH�RQO\�VR�PDQ\�FKDUDFWHUV��VR�\RX�KDYH�WR�XVH�VRPH�RI�WKHP�WZLFH�

� $FWXDOO\��LW�PDWFKHV�HLWKHU�WKH�HQG�RI�WKH�VWULQJ�RU�DW�D�QHZOLQH�DW�WKH�HQG�RI�WKH�VWULQJ��7KDW¦V�VR�\RX�FDQPDWFK� WKH� HQG�RI� WKH� VWULQJ�ZKHWKHU� LW�KDV� D� WUDLOLQJ�QHZOLQH�RU�QRW��0RVW� IRONV�GRQ¦W�ZRUU\� DERXW� WKLVGLVWLQFWLRQ�PXFK��EXW�RQFH�LQ�D�ORQJ�ZKLOH�LW¦V�LPSRUWDQW�WR�UHPHPEHU�WKDW�/^fred$/�ZLOO�PDWFK�HLWKHU�"fred"�RU"fred\n"�ZLWK�HTXDO�HDVH�

® 6RPH�UHJXODU�H[SUHVVLRQ�LPSOHPHQWDWLRQV�KDYH�RQH�DQFKRU�IRU�VWDUW�RI�ZRUG�DQG�DQRWKHU�IRU�HQG�RI�ZRUG�EXW�3HUO�XVHV�\b�IRU�ERWK�

120 | Chapter 8:ಗMatching with Regular Expressions

7KH�£ZRUGV¤�DUH�VHTXHQFHV�RI�OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV��WKDW�LV��D�ZRUG�LQ�WKLVVHQVH�LV�ZKDW¦V�PDWFKHG�E\�/\w+/��7KHUH�DUH�ILYH�ZRUGV�LQ�WKDW�VHQWHQFH��That��s��a�word��DQG�boundary� �1RWLFH�WKDW�WKH�TXRWH�PDUNV�DURXQG�word�GRQ¦W�FKDQJH�WKH�ZRUGERXQGDULHV��WKHVH�ZRUGV�DUH�PDGH�RI�\w�FKDUDFWHUV�

(DFK�DUURZ�SRLQWV�WR�WKH�EHJLQQLQJ�RU�WKH�HQG�RI�RQH�RI�WKH�JUD\�XQGHUOLQHV��VLQFH�WKHZRUG�ERXQGDU\�DQFKRU�\b�PDWFKHV�RQO\�DW�WKH�EHJLQQLQJ�RU�WKH�HQG�RI�D�JURXS�RI�ZRUGFKDUDFWHUV�

7KH�ZRUG�ERXQGDU\�DQFKRU�LV�XVHIXO�WR�HQVXUH�WKDW�ZH�GRQ¦W�DFFLGHQWDOO\�ILQG�cat�LQdelicatessen��dog�LQ�boondoggle��RU�fish�LQ�selfishness��6RPHWLPHV�\RX¦OO�ZDQW�MXVWRQH�ZRUG�ERXQGDU\�DQFKRU��DV�ZKHQ�XVLQJ�/\bhunt/�WR�PDWFK�ZRUGV�OLNH�hunt�RU�hunting�RU�hunter��EXW�QRW�shunt��RU�ZKHQ�XVLQJ�/stone\b/�WR�PDWFK�ZRUGV�OLNH�sandstoneRU�flintstone�EXW�QRW�capstones�

7KH�QRQZRUG�ERXQGDU\� DQFKRU� LV�\B�� LW�PDWFKHV� DW� DQ\�SRLQW�ZKHUH�\b�ZRXOG�QRWPDWFK��6R�WKH�SDWWHUQ�/\bsearch\B/�ZLOO�PDWFK�searches��searching��DQG�searched��EXWQRW�search�RU�researching�

The Binding Operator, =~0DWFKLQJ�DJDLQVW�$_�LV�PHUHO\�WKH�GHIDXOW��WKH�ELQGLQJ�RSHUDWRU��=~��WHOOV�3HUO�WR�PDWFKWKH�SDWWHUQ�RQ�WKH�ULJKW�DJDLQVW�WKH�VWULQJ�RQ�WKH�OHIW��LQVWHDG�RI�PDWFKLQJ�DJDLQVW�$_��

)RU�H[DPSOH�

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

7KH� ILUVW� WLPH�\RX� VHH� LW�� WKH�ELQGLQJ�RSHUDWRU� ORRNV� OLNH� VRPH�NLQG�RI� DVVLJQPHQWRSHUDWRU��%XW�LW¦V�QR�VXFK�WKLQJ��,W�LV�VLPSO\�VD\LQJ��£7KLV�SDWWHUQ�PDWFK��ZKLFK�ZRXOGDWWDFK�WR�$_�E\�GHIDXOW¢PDNH�LW�ZRUN�ZLWK�WKLV�VWULQJ�RQ�WKH�OHIW�LQVWHDG�¤�,I�WKHUH¦V�QRELQGLQJ�RSHUDWRU��WKH�H[SUHVVLRQ�LV�XVLQJ�$_�E\�GHIDXOW�

<RX�FDQ�VHH�ZK\�ZH�ZLVK�WKDW�ZH�FRXOG�FKDQJH�WKH�GHILQLWLRQ�RI�£ZRUG¤��That's�VKRXOG�EH�RQH�ZRUG��QRWWZR�ZRUGV�ZLWK�DQ�DSRVWURSKH�LQ�EHWZHHQ��$QG�HYHQ�LQ�WH[W�WKDW�PD\�EH�PRVWO\�RUGLQDU\�(QJOLVK��LW¦V�QRUPDOWR�ILQG�D�VRXSoRQ�RI�RWKHU�FKDUDFWHUV�VSLFLQJ�WKLQJV�XS�

� 7KH�ELQGLQJ�RSHUDWRU�LV�DOVR�XVHG�ZLWK�VRPH�RWKHU�RSHUDWLRQV�EHVLGHV�WKH�SDWWHUQ�PDWFK��DV�\RX¦OO�VHH�ODWHU�

)LJXUH������:RUG�ERXQGDU\�PDWFKHV�ZLWK�?E

The Binding Operator, =~ | 121

,Q�WKH��VRPHZKDW�XQXVXDO��H[DPSOH�WKDW�IROORZV��$likes_perl�LV�VHW�WR�D�%RROHDQ�YDOXHDFFRUGLQJ�WR�ZKDW�WKH�XVHU�W\SHG�DW�WKH�SURPSW��7KLV�LV�D�OLWWOH�RQ�WKH�TXLFN�DQG�GLUW\VLGH�EHFDXVH�WKH�OLQH�RI�LQSXW�LWVHOI�LV�GLVFDUGHG��7KLV�FRGH�UHDGV�WKH�OLQH�RI�LQSXW��WHVWVWKDW�VWULQJ�DJDLQVW�WKH�SDWWHUQ��WKHQ�GLVFDUGV�WKH�OLQH�RI�LQSXW� �,W�GRHVQ¦W�XVH�RU�FKDQJH$_�DW�DOO�

print "Do you like Perl? ";my $likes_perl = (<STDIN> =~ /\byes\b/i);... # Time passes...if ($likes_perl) { print "You said earlier that you like Perl, so...\n"; ...}

%HFDXVH�WKH�ELQGLQJ�RSHUDWRU�KDV�IDLUO\�KLJK�SUHFHGHQFH��WKH�SDUHQWKHVHV�DURXQG�WKHSDWWHUQ�WHVW�H[SUHVVLRQ�DUHQ¦W�UHTXLUHG��VR�WKH�IROORZLQJ�OLQH�GRHV�WKH�VDPH�WKLQJ�DV�WKHRQH�DERYH¢LW�VWRUHV�WKH�UHVXOW�RI�WKH�WHVW��DQG�QRW�WKH�OLQH�RI�LQSXW��LQWR�WKH�YDULDEOH�

my $likes_perl = <STDIN> =~ /\byes\b/i;

Interpolating into Patterns7KH�UHJXODU�H[SUHVVLRQ�LV�GRXEOH�TXRWH�LQWHUSRODWHG��MXVW�DV�LI�LW�ZHUH�D�GRXEOH�TXRWHGVWULQJ��7KLV�DOORZV�XV�WR�ZULWH�D�TXLFN�JUHS�OLNH�SURJUDP�OLNH�WKLV�

#!/usr/bin/perl -wmy $what = "larry";

while (<>) { if (/^($what)/) { # pattern is anchored at beginning of string print "We saw $what in beginning of $_"; }}

7KH�SDWWHUQ�ZLOO�EH�EXLOW�XS�RXW�RI�ZKDWHYHU¦V�LQ�$what�ZKHQ�ZH�UXQ�WKH�SDWWHUQ�PDWFK�,Q�WKLV�FDVH��LW¦V�WKH�VDPH�DV�LI�ZH�KDG�ZULWWHQ�/^(larry)/��ORRNLQJ�IRU�larry�DW�WKH�VWDUWRI�HDFK�OLQH�

%XW�ZH�GLGQ¦W�KDYH�WR�JHW�WKH�YDOXH�RI�$what�IURP�D�OLWHUDO�VWULQJ��ZH�FRXOG�KDYH�JRWWHQLW�LQVWHDG�IURP�WKH�FRPPDQG�OLQH�DUJXPHQWV�LQ�@ARGV�

my $what = shift @ARGV;

1RZ�� LI� WKH� ILUVW� FRPPDQG�OLQH� DUJXPHQW� ZHUH� fred|barney�� WKH� SDWWHUQ� EH�FRPHV� /^(fred|barney)/�� ORRNLQJ� IRU� fred� RU� barney� DW� WKH� VWDUW� RI� HDFK� OLQH���7KH

5HPHPEHU��WKH�OLQH�RI�LQSXW�LV�QRW�DXWRPDWLFDOO\�VWRUHG�LQWR�$_�XQOHVV�WKH�OLQH�LQSXW�RSHUDWRU��<STDIN>��LV�DOODORQH�LQ�WKH�FRQGLWLRQDO�H[SUHVVLRQ�RI�D�while�ORRS�

� 7KH�DVWXWH�UHDGHU�ZLOO�NQRZ�WKDW�\RX�FDQ¦W�JHQHUDOO\�W\SH�fred|barney�DV�DQ�DUJXPHQW�DW�WKH�FRPPDQG�OLQHEHFDXVH�WKH�YHUWLFDO�EDU�LV�D�VKHOO�PHWDFKDUDFWHU��6HH�WKH�GRFXPHQWDWLRQ�WR�\RXU�VKHOO�WR�OHDUQ�DERXW�KRZ�WRTXRWH�FRPPDQG�OLQH�DUJXPHQWV�

122 | Chapter 8:ಗMatching with Regular Expressions

SDUHQWKHVHV��ZKLFK�ZHUHQ¦W�UHDOO\�QHFHVVDU\�ZKHQ�VHDUFKLQJ�IRU�larry��DUH�LPSRUWDQWQRZ�EHFDXVH�ZLWKRXW�WKHP�ZH¦G�EH�PDWFKLQJ�fred�DW�WKH�VWDUW�RU�barney�DQ\ZKHUH�LQWKH�VWULQJ�

:LWK�WKDW�OLQH�FKDQJHG�WR�JHW�WKH�SDWWHUQ�IURP�@ARGV��WKLV�SURJUDP�UHVHPEOHV�WKH�8QL[JUHS�FRPPDQG��%XW�ZH�KDYH�WR�ZDWFK�RXW�IRU�PHWDFKDUDFWHUV� LQ�WKH�VWULQJ��,I�$whatFRQWDLQV�'fred(barney'��WKH�SDWWHUQ�ZRXOG�ORRN�OLNH�/^(fred(barney)/��DQG�\RX�NQRZWKDW�FDQ¦W�ZRUN�ULJKW¢LW¦OO�FUDVK�\RXU�SURJUDP�ZLWK�DQ�LQYDOLG�UHJXODU�H[SUHVVLRQ�HUURU�:LWK�VRPH�DGYDQFHG�WHFKQLTXHV� �\RX�FDQ�WUDS�WKLV�NLQG�RI�HUURU��RU�SUHYHQW�WKH�PDJLFRI�WKH�PHWDFKDUDFWHUV�LQ�WKH�ILUVW�SODFH��VR�WKDW�LW�ZRQ¦W�FUDVK�\RXU�SURJUDP��%XW�IRUQRZ��MXVW�NQRZ�WKDW�LI�\RX�JLYH�\RXU�XVHUV�WKH�SRZHU�RI�UHJXODU�H[SUHVVLRQV��WKH\¦OO�DOVRQHHG�WKH�UHVSRQVLELOLW\�WR�XVH�WKHP�FRUUHFWO\�

The Match Variables6R�IDU��ZKHQ�ZH¦YH�SXW�SDUHQWKHVHV�LQWR�SDWWHUQV��WKH\¦YH�EHHQ�XVHG�RQO\�IRU�WKHLU�DELOLW\WR�JURXS�SDUWV�RI�D�SDWWHUQ�WRJHWKHU��%XW�SDUHQWKHVHV�DOVR�WULJJHU�WKH�UHJXODU�H[SUHVVLRQHQJLQH¦V�PHPRU\��7KH�PHPRU\�KROGV�WKH�SDUW�RI�WKH�VWULQJ�PDWFKHG�E\�WKH�SDUW�RI�WKHSDWWHUQ�LQVLGH�SDUHQWKHVHV��,I�WKHUH�LV�PRUH�WKDQ�RQH�SDLU�RI�SDUHQWKHVHV��WKHUH�ZLOO�EHPRUH�WKDQ�RQH�PHPRU\��(DFK�UHJXODU�H[SUHVVLRQ�PHPRU\�KROGV�SDUW�RI�WKH�RULJLQDOVWULQJ��QRW�SDUW�RI�WKH�SDWWHUQ�

6LQFH�WKHVH�YDULDEOHV�KROG�VWULQJV��WKH\�DUH�VFDODU�YDULDEOHV��LQ�3HUO��WKH\�KDYH�QDPHVOLNH� $1� DQG� $2�� 7KHUH� DUH� DV�PDQ\� RI� WKHVH� YDULDEOHV� DV� WKHUH� DUH� SDLUV� RI�PHPRU\SDUHQWKHVHV�LQ�WKH�SDWWHUQ��$V�\RX¦G�H[SHFW��$4�PHDQV�WKH�VWULQJ�PDWFKHG�E\�WKH�IRXUWKVHW�RI�SDUHQWKHVHV��

7KHVH�PDWFK�YDULDEOHV�DUH�D�ELJ�SDUW�RI�WKH�SRZHU�RI�UHJXODU�H[SUHVVLRQV�EHFDXVH�WKH\OHW�XV�SXOO�RXW�WKH�SDUWV�RI�D�VWULQJ�

$_ = "Hello there, neighbor";if (/\s(\w+),/) { # memorize the word between space and comma print "the word was $1\n"; # the word was there}

2U�\RX�FRXOG�XVH�PRUH�WKDQ�RQH�PHPRU\�DW�RQFH�

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

,Q�WKLV�FDVH��\RX�ZRXOG�XVH�DQ�eval�EORFN�WR�WUDS�WKH�HUURU��RU�\RX�ZRXOG�TXRWH�WKH�LQWHUSRODWHG�WH[W�XVLQJquotemeta��RU�LWV�\Q�HTXLYDOHQW�IRUP��VR�WKDW�LW¦V�QR�ORQJHU�WUHDWHG�DV�D�UHJXODU�H[SUHVVLRQ�

� 7KLV�LV�WKH�VDPH�VWULQJ�WKDW�WKH�EDFN�UHIHUHQFH�\4�ZRXOG�UHIHU�WR�GXULQJ�WKH�SDWWHUQ�PDWFK��%XW�WKHVH�DUHQ¦WWZR�GLIIHUHQW�QDPHV�IRU�WKH�VDPH�WKLQJ��\4�UHIHUV�EDFN�WR�WKH�PHPRU\�GXULQJ�WKH�SDWWHUQ�ZKLOH�LW�LV�WU\LQJ�WRPDWFK��ZKLOH�$4�UHIHUV�WR�WKH�PHPRU\�RI�DQ�DOUHDG\�FRPSOHWHG�SDWWHUQ�PDWFK��)RU�PRUH�LQIRUPDWLRQ�RQ�EDFNUHIHUHQFHV��VHH�WKH�SHUOUH�PDQSDJH�

The Match Variables | 123

7KDW�WHOOV�XV�WKDW�WKH�ZRUGV�ZHUH�Hello there neighbor��1RWLFH�WKDW�WKHUH¦V�QR�FRPPDLQ�WKH�RXWSXW��%HFDXVH�WKH�FRPPD�LV�RXWVLGH�RI�WKH�PHPRU\�SDUHQWKHVHV�LQ�WKH�SDWWHUQ�WKHUH�LV�QR�FRPPD�LQ�PHPRU\�WZR��8VLQJ�WKLV�WHFKQLTXH��ZH�FDQ�FKRRVH�H[DFWO\�ZKDWZH�ZDQW�LQ�WKH�PHPRULHV��DV�ZHOO�DV�ZKDW�ZH�ZDQW�WR�OHDYH�RXW�

<RX�FRXOG�HYHQ�KDYH�DQ�HPSW\�PDWFK�YDULDEOH �LI�WKDW�SDUW�RI�WKH�SDWWHUQ�PLJKW�EH�HPSW\�7KDW�LV��D�PDWFK�YDULDEOH�PD\�FRQWDLQ�WKH�HPSW\�VWULQJ�

my $dino = "I fear that I'll be extinct after 1000 years.";if ($dino =~ /(\d*) years/) { print "That said '$1' years.\n"; # 1000}

$dino = "I fear that I'll be extinct after a few million years.";if ($dino =~ /(\d*) years/) { print "That said '$1' years.\n"; # empty string}

The Persistence of Memory7KHVH�PDWFK�YDULDEOHV�JHQHUDOO\�VWD\�DURXQG�XQWLO�WKH�QH[W�VXFFHVVIXO�SDWWHUQ�PDWFK��

7KDW�LV��DQ�XQVXFFHVVIXO�PDWFK�OHDYHV�WKH�SUHYLRXV�PHPRULHV�LQWDFW��EXW�D�VXFFHVVIXORQH�UHVHWV�WKHP�DOO��7KLV�FRUUHFWO\�LPSOLHV�WKDW�\RX�VKRXOGQ¦W�XVH�WKHVH�PDWFK�YDULDEOHVXQOHVV�WKH�PDWFK�VXFFHHGHG��RWKHUZLVH��\RX�FRXOG�EH�VHHLQJ�D�PHPRU\�IURP�VRPH�SUH�YLRXV�SDWWHUQ��7KH�IROORZLQJ��EDG��H[DPSOH�LV�VXSSRVHG�WR�SULQW�D�ZRUG�PDWFKHG�IURP$wilma��%XW�LI�WKH�PDWFK�IDLOV��LW�ZLOO�XVH�ZKDWHYHU�OHIWRYHU�VWULQJ�KDSSHQV�WR�EH�IRXQGLQ�$1�

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

7KLV�LV�DQRWKHU�UHDVRQ�WKDW�D�SDWWHUQ�PDWFK�LV�DOPRVW�DOZD\V�IRXQG�LQ�WKH�FRQGLWLRQDOH[SUHVVLRQ�RI�DQ�if�RU�while�

if ($wilma =~ /(\w+)/) { print "Wilma's word was $1.\n";} else { print "Wilma doesn't have a word.\n";}

6LQFH�WKHVH�PHPRULHV�GRQ¦W�VWD\�DURXQG�IRUHYHU��\RX�VKRXOGQ¦W�XVH�D�PDWFK�YDULDEOHOLNH�$1�PRUH�WKDQ�D�IHZ�OLQHV�DIWHU�LWV�SDWWHUQ�PDWFK��,I�\RXU�PDLQWHQDQFH�SURJUDPPHUDGGV�D�QHZ�UHJXODU�H[SUHVVLRQ�EHWZHHQ�\RXU�UHJXODU�H[SUHVVLRQ�DQG�\RXU�XVH�RI�$1�\RX¦OO�EH�JHWWLQJ�WKH�YDOXH�RI�$1�IRU�WKH�VHFRQG�PDWFK��UDWKHU�WKDQ�WKH�ILUVW��)RU�WKLVUHDVRQ��LI�\RX�QHHG�D�PHPRU\�IRU�PRUH�WKDQ�D�IHZ�OLQHV��LW¦V�JHQHUDOO\�EHVW�WR�FRS\�LW

$V�RSSRVHG�WR�DQ�XQGHILQHG�RQH��,I�\RX�KDYH�WKUHH�RU�IHZHU�VHWV�RI�SDUHQWKHVHV�LQ�WKH�SDWWHUQ��$4�ZLOO�EH�undef�

� 7KH�DFWXDO�VFRSLQJ�UXOH�LV�PXFK�PRUH�FRPSOH[��VHH�WKH�GRFXPHQWDWLRQ�LI�\RX�QHHG�LW���EXW�DV�ORQJ�DV�\RXGRQ¦W�H[SHFW� WKH�PDWFK�YDULDEOHV� WR�EH�XQWRXFKHG�PDQ\� OLQHV�DIWHU�D�SDWWHUQ�PDWFK��\RX�VKRXOGQ¦W�KDYHSUREOHPV�

124 | Chapter 8:ಗMatching with Regular Expressions

LQWR�DQ�RUGLQDU\�YDULDEOH��'RLQJ�WKLV�KHOSV�PDNH�WKH�FRGH�PRUH�UHDGDEOH�DW�WKH�VDPHWLPH�

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

/DWHU��LQ�&KDSWHU����\RX¦OO�VHH�KRZ�WR�JHW�WKH�PHPRU\�YDOXH�GLUHFWO\�LQWR�WKH�YDULDEOH�DWWKH�VDPH�WLPH�WKH�SDWWHUQ�PDWFK�KDSSHQV��ZLWKRXW�KDYLQJ�WR�XVH�$1�H[SOLFLWO\�

Noncapturing Parentheses6R�IDU�\RX¦YH�VHHQ�SDUHQWKHVHV�WKDW�FDSWXUH�SDUWV�RI�D�PDWFKHG�VWULQJ�DQG�VWRUH�WKHPLQ�WKH�PHPRU\�YDULDEOHV��EXW�ZKDW�LI�\RX�MXVW�ZDQW�WR�XVH�WKH�SDUHQWKHVHV�WR�JURXSWKLQJV"�&RQVLGHU�D�UHJXODU�H[SUHVVLRQ�ZKHUH�ZH�ZDQW�WR�PDNH�SDUW�RI�LW�RSWLRQDO��EXWFDSWXUH�RQO\�DQRWKHU�SDUW�RI�LW��,Q�WKLV�H[DPSOH��ZH�ZDQW�£EURQWR¤�WR�EH�RSWLRQDO��EXWWR�PDNH�LW�RSWLRQDO��ZH�KDYH�WR�JURXS�WKDW�VHTXHQFH�RI�FKDUDFWHUV�ZLWK�SDUHQWKHVHV�/DWHU�LQ�WKH�SDWWHUQ��ZH�XVH�DQ�DOWHUQDWLRQ�WR�JHW�HLWKHU�£VWHDN¤�RU�£EXUJHU¤��DQG�ZHZDQW�WR�NQRZ�ZKLFK�RQH�ZH�IRXQG�

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

(YHQ�LI�EURQWR�LV�QRW�WKHUH��LWV�SDUW�RI�WKH�SDWWHUQ�JRHV�LQWR�$1��3HUO�MXVW�FRXQWV�WKH�RUGHURI�WKH�RSHQLQJ�SDUHQWKHVHV�WR�GHFLGH�ZKDW�WKH�PHPRU\�YDULDEOHV�ZLOO�EH��7KH�SDUW�WKDWZH�ZDQW�WR�UHPHPEHU�HQGV�XS�LQ�$2��,Q�PRUH�FRPSOLFDWHG�SDWWHUQV��WKLV�VLWXDWLRQ�FDQJHW�TXLWH�FRQIXVLQJ�

)RUWXQDWHO\��3HUO¦V�UHJXODU�H[SUHVVLRQV�KDYH�D�ZD\�WR�XVH�SDUHQWKHVHV�WR�JURXS�WKLQJVEXW�QRW�WULJJHU�WKH�PHPRU\�YDULDEOHV��:H�FDOO�WKHVH�QRQFDSWXULQJ�SDUHQWKHVHV��DQG�ZHZULWH�WKHP�ZLWK�D�VSHFLDO�VHTXHQFH��:H�DGG�D�TXHVWLRQ�PDUN�DQG�D�FRORQ�DIWHU�WKHRSHQLQJ� SDUHQWKHVLV�� (?:)� � DQG� WKDW� WHOOV� 3HUO� ZH� XVH� WKHVH� SDUHQWKHVHV� RQO\� IRUJURXSLQJ�

:H�FKDQJH�RXU�UHJXODU�H[SUHVVLRQ�WR�XVH�QRQFDSWXULQJ�SDUHQWKHVHV�DURXQG�£EURQWR¤�DQG�WKH�SDUW�WKDW�ZH�ZDQW�WR�UHPHPEHU�QRZ�VKRZV�XS�LQ�$1�

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

/DWHU��ZKHQ�ZH�FKDQJH�RXU�UHJXODU�H[SUHVVLRQ��SHUKDSV�WR�LQFOXGH�D�SRVVLEOH�EDU�EH�TXH�YHUVLRQ�RI�WKH�EURQWRVDXUXV�EXUJHU��ZH�FDQ�PDNH�WKH�DGGHG�£%%4�¤��ZLWK�D�VSDFH��RSWLRQDO�DQG�QRQFDSWXULQJ�� VR� WKH�SDUW�ZH�ZDQW� WR� UHPHPEHU� VWLOO� VKRZV�XS� LQ�$1�

7KLV�LV�WKH�IRXUWK�W\SH�RI�"�\RX¦OO�VHH�LQ�UHJXODU�H[SUHVVLRQV��D�OLWHUDO�TXHVWLRQ�PDUN��HVFDSHG���WKH���RU��TXDQWLILHU��WKH�QRQJUHHG\�PRGLILHU��QH[W�FKDSWHU���DQG�QRZ�WKH�VWDUW�RI�DQ�H[WHQGHG�SDWWHUQ�

The Match Variables | 125

2WKHUZLVH��ZH¦G�SRWHQWLDOO\�KDYH�WR�VKLIW�DOO�RI�RXU�PHPRU\�YDULDEOH�QDPHV�HYHU\�WLPHZH�DGG�JURXSLQJ�SDUHQWKHVHV�WR�RXU�UHJXODU�H[SUHVVLRQ�

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

3HUO¦V� UHJXODU� H[SUHVVLRQV�KDYH� VHYHUDO� RWKHU� VSHFLDO� SDUHQWKHVHV� VHTXHQFHV� WKDW� GRIDQF\�DQG�FRPSOLFDWHG�WKLQJV�OLNH�ORRN�DKHDG��ORRN�EHKLQG��HPEHGGHG�FRPPHQWV��RUHYHQ� UXQ�FRGH� ULJKW� LQ� WKH�PLGGOH�RI�D�SDWWHUQ��<RX¦OO�KDYH� WR�FKHFN�RXW� WKH�SHUOUHPDQSDJH�IRU�WKH�GHWDLOV�WKRXJK�

Named Captures<RX�FDQ�FDSWXUH�SDUWV�RI� WKH� VWULQJ�ZLWK�SDUHQWKHVHV�DQG� WKHQ� ORRN� LQ� WKH�QXPEHUYDULDEOHV�$1��$2��DQG�VR�RQ�WR�JHW�WKH�SDUWV�RI�WKH�VWULQJ�WKDW�PDWFKHG��.HHSLQJ�WUDFN�RIWKRVH�QXPEHU�YDULDEOHV�DQG�ZKDW�VKRXOG�EH�LQ�WKHP�FDQ�EH�FRQIXVLQJ�HYHQ�IRU�VLPSOHSDWWHUQV��&RQVLGHU�WKLV�UHJXODU�H[SUHVVLRQ�WKDW�WULHV�WR�PDWFK�WKH�WZR�QDPHV�LQ�$names�

use 5.010;

my $names = 'Fred or Barney';if( $names =~ m/(\w+) and (\w+)/ ) { # won't match say "I saw $1 and $2"; }

:H�GRQ¦W�VHH�WKH�PHVVDJH�IURP�say�EHFDXVH�WKH�VWULQJ�KDV�DQ�or�ZKHUH�\RX�ZHUH�H[�SHFWLQJ�DQ�and��0D\EH�ZH�ZHUH�VXSSRVHG�WR�KDYH�LW�ERWK�ZD\V��VR�ZH�FKDQJH�WKH�UHJXODUH[SUHVVLRQ�WR�KDYH�DQ�DOWHUQDWLRQ�WR�KDQGOH�ERWK�and�DQG�or��DGGLQJ�DQRWKHU�VHW�RISDUHQWKHVHV�WR�JURXS�WKH�DOWHUQDWLRQ�

use 5.010;

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

2RSV��:H�VHH�D�PHVVDJH�WKLV�WLPH��EXW�LW�GRHVQ¦W�KDYH�WKH�VHFRQG�QDPH�LQ�LW�EHFDXVHZH�DGGHG�DQRWKHU�VHW�RI�PHPRU\�SDUHQWKHVHV��7KH�YDOXH�LQ�$2�LV�IURP�WKH�DOWHUQDWLRQDQG�WKH�VHFRQG�QDPH�ZDV�QRZ�LQ�$3��ZKLFK�ZH�GRQ¦W�RXWSXW��

I saw Fred and or

:H�FRXOG�KDYH�XVHG� WKH�QRQFDSWXULQJ�SDUHQWKHVHV� WR�JHW� DURXQG� WKLV��EXW� WKH� UHDOSUREOHP�LV�WKDW�ZH�KDYH�WR�UHPHPEHU�ZKLFK�QXPEHUHG�SDUHQWKHVHV�EHORQJ�WR�ZKLFKGDWD�ZH�DUH�WU\LQJ�WR�FDSWXUH��,PDJLQH�KRZ�PXFK�WRXJKHU�WKLV�JHWV�ZLWK�PDQ\�FDSWXUHV�

126 | Chapter 8:ಗMatching with Regular Expressions

,QVWHDG�RI�UHPHPEHULQJ�QXPEHUV�VXFK�DV�$1��3HUO������OHWV�XV�QDPH�WKH�FDSWXUHV�GLUHFWO\LQ�WKH�UHJXODU�H[SUHVVLRQ��,W�VDYHV�WKH�WH[W�LW�PDWFKHV�LQ�WKH�KDVK�QDPHG�%+��WKH�NH\�LVWKH�ODEHO�ZH�XVHG�DQG�WKH�YDOXH�LV�WKH�SDUW�RI�WKH�VWULQJ�WKDW�LW�PDWFKHG��7R�ODEHO�D�PDWFKYDULDEOH��ZH�XVH�(?<LABEL>PATTERN)�ZKHUH�ZH�UHSODFH�LABEL�ZLWK�RXU�RZQ�QDPHV� �:HODEHO� WKH� ILUVW� FDSWXUH� name1� DQG� WKH� VHFRQG� RQH� name2�� DQG� ORRN� LQ� $+{name1}� DQG$+{name2}�WR�ILQG�WKHLU�YDOXHV�

use 5.010;

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

1RZ�ZH�VHH�WKH�ULJKW�PHVVDJH�

I saw Fred and Barney

2QFH�ZH�ODEHO�RXU�FDSWXUHV��ZH�FDQ�PRYH�WKHP�DURXQG�DQG�DGG�DGGLWLRQDO�FDSWXULQJSDUHQWKHVHV�ZLWKRXW�GLVWXUELQJ�WKH�RUGHU�RI�WKH�FDSWXUHV�

use 5.010;

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

1RZ�WKDW�ZH�KDYH�D�ZD\�WR�ODEHO�PDWFKHV��ZH�DOVR�QHHG�D�ZD\�WR�UHIHU�WR�WKHP�IRU�EDFNUHIHUHQFHV��3UHYLRXVO\��ZH�XVHG�HLWKHU�\1�RU�\g{1}�IRU�WKLV��:LWK�D�ODEHOHG�JURXS��ZH�FDQXVH�WKH�ODEHO�LQ�\g{label}�

use 5.010;

my $names = 'Fred Flinstone and Wilma Flinstone';

if( $names =~ m/(?<last_name>\w+) and \w+ \g{last_name}/ ) { say "I saw $+{last_name}"; }

:H�FDQ�GR�WKH�VDPH�WKLQJ�ZLWK�DQRWKHU�V\QWD[��,QVWHDG�RI�XVLQJ�\g{label}��ZH�XVH\k<label>��

use 5.010;

my $names = 'Fred Flinstone and Wilma Flinstone';

if( $names =~ m/(?<last_name>\w+) and \w+ \k<last_name>/ ) {

3HUO�DOVR�OHWV�XV�XVH�WKH�3\WKRQ�V\QWD[�(?P<LABEL>...)�WR�GR�WKH�VDPH�WKLQJ�

� \k<label>�LV�VOLJKWO\�GLIIHUHQW�WKDQ�\g{label}��,Q�SDWWHUQV�WKDW�KDYH�WZR�RU�PRUH�ODEHOHG�JURXSV�ZLWK�WKH�VDPHODEHO��\k<label>�DQG�\g{label}�DOZD\V�UHIHUV�WR�WKH�OHIWPRVW�JURXS��EXW�\g{N}�FDQ�EH�D�UHODWLYH�EDFN�UHIHUHQFH�,I�\RX¦UH�D�IDQ�RI�3\WKRQ��\RX�FDQ�DOVR�XVH�WKH�(?P=label)�V\QWD[�

The Match Variables | 127

say "I saw $+{last_name}"; }

The Automatic Match Variables7KHUH�DUH�WKUHH�PRUH�PDWFK�YDULDEOHV�WKDW�\RX�JHW�IRU�IUHH� �ZKHWKHU�WKH�SDWWHUQ�KDVPHPRU\�SDUHQWKHVHV�RU�QRW��7KDW¦V�WKH�JRRG�QHZV��WKH�EDG�QHZV�LV�WKDW�WKHVH�YDULDEOHVKDYH�ZHLUG�QDPHV�

1RZ��/DUU\�SUREDEO\�ZRXOG�KDYH�EHHQ�KDSS\�HQRXJK�WR�FDOO�WKHVH�E\�VOLJKWO\�OHVV�ZHLUGQDPHV��OLNH�SHUKDSV�$gazoo�RU�$ozmodiar��%XW�WKRVH�DUH�QDPHV�WKDW�\RX�MXVW�PLJKW�ZDQWWR�XVH�LQ�\RXU�RZQ�FRGH��7R�NHHS�RUGLQDU\�3HUO�SURJUDPPHUV�IURP�KDYLQJ�WR�PHPRUL]HWKH�QDPHV�RI�DOO�RI�3HUO¦V�VSHFLDO�YDULDEOHV�EHIRUH�FKRRVLQJ�WKHLU�ILUVW�YDULDEOH�QDPHV�LQWKHLU�ILUVW�SURJUDPV���/DUU\�KDV�JLYHQ�VWUDQJH�QDPHV�WR�PDQ\�RI�3HUO¦V�EXLOW�LQ�YDULDEOHV�QDPHV�WKDW�£EUHDN�WKH�UXOHV�¤�,Q�WKLV�FDVH��WKH�QDPHV�DUH�SXQFWXDWLRQ�PDUNV��$&��$`�DQG�$'��7KH\¦UH�VWUDQJH��XJO\��DQG�ZHLUG��EXW�WKRVH�DUH�WKHLU�QDPHV�®�7KH�SDUW�RI�WKHVWULQJ�WKDW�DFWXDOO\�PDWFKHG�WKH�SDWWHUQ�LV�DXWRPDWLFDOO\�VWRUHG�LQ�$&�

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

7KDW�WHOOV�XV�WKDW�WKH�SDUW�WKDW�PDWFKHG�ZDV�" there,"��ZLWK�D�VSDFH��D�ZRUG��DQG�DFRPPD���0HPRU\�RQH��LQ�$1��KDV�MXVW�WKH�ILYH�OHWWHU�ZRUG�there��EXW�$&�KDV�WKH�HQWLUHPDWFKHG�VHFWLRQ�

:KDWHYHU�FDPH�EHIRUH�WKH�PDWFKHG�VHFWLRQ�LV�LQ�$`��DQG�ZKDWHYHU�ZDV�DIWHU�LW�LV�LQ�$'�$QRWKHU�ZD\�WR�VD\�WKDW�LV�WKDW�$`�KROGV�ZKDWHYHU�WKH�UHJXODU�H[SUHVVLRQ�HQJLQH�KDG�WRVNLS�RYHU�EHIRUH�LW�IRXQG�WKH�PDWFK��DQG�$'�KDV�WKH�UHPDLQGHU�RI�WKH�VWULQJ�WKDW�WKHSDWWHUQ�QHYHU�JRW�WR��,I�\RX�JOXH�WKHVH�WKUHH�VWULQJV�WRJHWKHU�LQ�RUGHU��\RX¦OO�DOZD\V�JHWEDFN�WKH�RULJLQDO�VWULQJ�

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

7KH�PHVVDJH�VKRZV�WKH�VWULQJ�DV�(Hello)( there,)( neighbor)��VKRZLQJ�WKH�WKUHH�DX�WRPDWLF�PDWFK�YDULDEOHV�LQ�DFWLRQ��7KLV�PD\�VHHP�IDPLOLDU��DQG�IRU�JRRG�UHDVRQ��WKHVHDXWRPDWLF�PHPRU\�YDULDEOHV�DUH�ZKDW�WKH�SDWWHUQ�WHVW�SURJUDP��IURP�&KDSWHU����ZDVXVLQJ�LQ�LWV�OLQH�RI�£P\VWHU\¤�FRGH��WR�VKRZ�ZKDW�SDUW�RI�WKH�VWULQJ�ZDV�EHLQJ�PDWFKHGE\�WKH�SDWWHUQ�

<HDK��ULJKW��7KHUH¦V�QR�VXFK�WKLQJ�DV�D�IUHH�PDWFK��7KHVH�DUH�£IUHH¤�RQO\�LQ�WKH�VHQVH�WKDW�WKH\�GRQ¦W�UHTXLUHPDWFK�SDUHQWKHVHV��'RQ¦W�ZRUU\��ZH¦OO�PHQWLRQ�WKHLU�UHDO�FRVW�D�OLWWOH�ODWHU��WKRXJK�

� <RX�VKRXOG�VWLOO�DYRLG�D�IHZ�FODVVLFDO�YDULDEOH�QDPHV�OLNH�$ARGV��EXW�WKHVH�IHZ�DUH�DOO�LQ�DOO�FDSV��$OO�RI�3HUO¦VEXLOW�LQ�YDULDEOHV�DUH�GRFXPHQWHG�LQ�WKH�SHUOYDU�PDQSDJH�

® ,I�\RX�UHDOO\�FDQ¦W�VWDQG�WKHVH�QDPHV��FKHFN�RXW�WKH�English�PRGXOH��ZKLFK�DWWHPSWV�WR�JLYH�DOO�RI�3HUO¦VVWUDQJHVW�YDULDEOHV�QHDUO\�QRUPDO�QDPHV��%XW�WKH�XVH�RI�WKLV�PRGXOH�KDV�QHYHU�UHDOO\�FDXJKW�RQ��LQVWHDG��3HUOSURJUDPPHUV�KDYH�JURZQ�WR�ORYH�WKH�SXQFWXDWLRQ�PDUN�YDULDEOH�QDPHV��VWUDQJH�DV�WKH\�DUH�

128 | Chapter 8:ಗMatching with Regular Expressions

print "Matched: |$`<$&>$'|\n"; # The three automatic match variables

$Q\�RU�DOO�RI�WKHVH�WKUHH�DXWRPDWLF�PDWFK�YDULDEOHV�PD\�EH�HPSW\��RI�FRXUVH��MXVW�OLNHWKH�QXPEHUHG�PDWFK�YDULDEOHV��$QG�WKH\�KDYH�WKH�VDPH�VFRSH�DV�WKH�QXPEHUHG�PDWFKYDULDEOHV��*HQHUDOO\��WKDW�PHDQV�WKDW�WKH\¦OO�VWD\�DURXQG�XQWLO�WKH�QH[W�VXFFHVVIXO�SDW�WHUQ�PDWFK�

1RZ��ZH�VDLG�HDUOLHU�WKDW�WKHVH�WKUHH�DUH�£IUHH�¤�:HOO��IUHHGRP�KDV�LWV�SULFH��,Q�WKLV�FDVH�WKH�SULFH�LV�WKDW�RQFH�\RX�XVH�DQ\�RQH�RI�WKHVH�DXWRPDWLF�PDWFK�YDULDEOHV�DQ\ZKHUH�LQ\RXU�HQWLUH�SURJUDP��RWKHU�UHJXODU�H[SUHVVLRQV�ZLOO�UXQ�D�OLWWOH�PRUH�VORZO\� �1RZ��WKLVLVQ¦W�D�JLDQW�VORZGRZQ��EXW�LW¦V�HQRXJK�RI�D�ZRUU\�WKDW�PDQ\�3HUO�SURJUDPPHUV�ZLOOVLPSO\�QHYHU�XVH�WKHVH�DXWRPDWLF�PDWFK�YDULDEOHV���,QVWHDG��WKH\¦OO�XVH�D�ZRUNDURXQG�)RU�H[DPSOH��LI�WKH�RQO\�RQH�\RX�QHHG�LV�$&�� MXVW�SXW�SDUHQWKHVHV�DURXQG�WKH�ZKROHSDWWHUQ� DQG�XVH�$1� LQVWHDG� �\RX�PD\�QHHG� WR� UHQXPEHU� WKH�SDWWHUQ¦V�PHPRULHV�� RIFRXUVH��

0DWFK�YDULDEOHV��ERWK�WKH�DXWRPDWLF�RQHV�DQG�WKH�QXPEHUHG�RQHV��DUH�PRVW�RIWHQ�XVHGLQ�VXEVWLWXWLRQV��ZKLFK�\RX¦OO�VHH�LQ�WKH�QH[W�FKDSWHU�

General Quantifiers$�TXDQWLILHU�LQ�D�SDWWHUQ�PHDQV�WR�UHSHDW�WKH�SUHFHGLQJ�LWHP�D�FHUWDLQ�QXPEHU�RI�WLPHV�<RX¦YH�DOUHDG\�VHHQ�WKUHH�TXDQWLILHUV��*��+��DQG�?��%XW�LI�QRQH�RI�WKRVH�WKUHH�VXLWV�\RXUQHHGV��MXVW�XVH�D�FRPPD�VHSDUDWHG�SDLU�RI�QXPEHUV�LQVLGH�FXUO\�EUDFHV��{}��WR�VSHFLI\H[DFWO\�KRZ�IHZ�DQG�KRZ�PDQ\�UHSHWLWLRQV�DUH�DOORZHG�

6R�WKH�SDWWHUQ�/a{5,15}/�ZLOO�PDWFK�IURP���WR����UHSHWLWLRQV�RI�WKH�OHWWHU�a��,I�WKH�aDSSHDUV�WKUHH�WLPHV��WKDW¦V�WRR�IHZ��VR�LW�ZRQ¦W�PDWFK��,I�LW�DSSHDUV�ILYH�WLPHV��LW¦V�DPDWFK��,I�LW�DSSHDUV����WLPHV��WKDW¦V�VWLOO�D�PDWFK��,I�LW�DSSHDUV����WLPHV��MXVW�WKH�ILUVW���ZLOO�PDWFK��VLQFH�WKDW¦V�WKH�XSSHU�OLPLW�

,I�\RX�RPLW�WKH�VHFRQG�QXPEHU��EXW�LQFOXGH�WKH�FRPPD���WKHUH¦V�QR�XSSHU�OLPLW�WR�WKHQXPEHU�RI�WLPHV�WKH�LWHP�ZLOO�PDWFK��6R��/(fred){3,}/�ZLOO�PDWFK�LI�WKHUH�DUH�WKUHH�RUPRUH�LQVWDQFHV�RI�fred�LQ�D�URZ��ZLWK�QR�H[WUD�FKDUDFWHUV��OLNH�VSDFHV��DOORZHG�EHWZHHQHDFK�fred�DQG�WKH�QH[W���7KHUH¦V�QR�XSSHU�OLPLW�VR�WKDW�ZRXOG�PDWFK����LQVWDQFHV�RIfred�LI�\RX�KDG�D�VWULQJ�ZLWK�WKDW�PDQ\�

,I� \RX�RPLW� WKH� FRPPD� DV�ZHOO� DV� WKH�XSSHU� ERXQG�� WKH�QXPEHU� JLYHQ� LV� DQ� H[DFWFRXQW��/\w{8}/�ZLOO�PDWFK�H[DFWO\�HLJKW�ZRUG�FKDUDFWHUV��RFFXUULQJ�DV�SDUW�RI�D�ODUJHU

)RU�HYHU\�EORFN�HQWU\�DQG�H[LW��ZKLFK�LV�SUDFWLFDOO\�HYHU\ZKHUH�

� 0RVW�RI�WKHVH�IRONV�KDYHQ¦W�EHQFKPDUNHG�WKHLU�SURJUDPV�WR�VHH�ZKHWKHU�WKHLU�ZRUNDURXQGV�DFWXDOO\�VDYHWLPH��WKRXJK��LW¦V�DV�WKRXJK�WKHVH�YDULDEOHV�ZHUH�SRLVRQRXV�RU�VRPHWKLQJ��%XW�ZH�FDQ¦W�EODPH�WKHP�IRU�QRWEHQFKPDUNLQJ¢PDQ\�SURJUDPV�WKDW�FRXOG�EHQHILW�IURP�WKHVH�WKUHH�YDULDEOHV�WDNH�XS�RQO\�D�IHZ�PLQXWHV�RI&38�WLPH�LQ�D�ZHHN��VR�EHQFKPDUNLQJ�DQG�RSWLPL]LQJ�ZRXOG�EH�D�ZDVWH�RI�WLPH��%XW�LQ�WKDW�FDVH��ZK\�IHDUD�SRVVLEOH�H[WUD�PLOOLVHFRQG"�%\�WKH�ZD\��WKH�3HUO�GHYHORSHUV�DUH�ZRUNLQJ�RQ�WKLV�SUREOHP��EXW�WKHUH�ZLOOSUREDEO\�EH�QR�VROXWLRQ�EHIRUH�3HUO���

General Quantifiers | 129

VWULQJ��SHUKDSV���$QG�/,{5}chameleon/�PDWFKHV�£FRPPD�FRPPD�FRPPD�FRPPD�FRP�PD�FKDPHOHRQ¤��%\�*HRUJH��WKDW�LV�QLFH�

,Q�IDFW��WKH�WKUHH�TXDQWLILHU�FKDUDFWHUV�WKDW�\RX�VDZ�HDUOLHU�DUH�MXVW�FRPPRQ�VKRUWFXWV�7KH�VWDU�LV�WKH�VDPH�DV�WKH�TXDQWLILHU�{0,}��PHDQLQJ�]HUR�RU�PRUH��7KH�SOXV�LV�WKH�VDPHDV�{1,}��PHDQLQJ�RQH�RU�PRUH��$QG�WKH�TXHVWLRQ�PDUN�FRXOG�EH�ZULWWHQ�DV�{0,1}��,QSUDFWLFH��LW¦V�XQXVXDO�WR�QHHG�DQ\�FXUO\�EUDFH�TXDQWLILHUV��VLQFH�WKH�WKUHH�VKRUWFXW�FKDU�DFWHUV�DUH�QHDUO\�DOZD\V�WKH�RQO\�RQHV�QHHGHG�

Precedence:LWK�DOO�RI�WKHVH�PHWDFKDUDFWHUV�LQ�UHJXODU�H[SUHVVLRQV��\RX�PD\�IHHO�WKDW�\RX�FDQ¦WNHHS�WUDFN�RI�WKH�SOD\HUV�ZLWKRXW�D�VFRUHFDUG��7KDW¦V�WKH�SUHFHGHQFH�FKDUW��ZKLFK�VKRZVXV�ZKLFK�SDUWV�RI�WKH�SDWWHUQ�£VWLFN�WRJHWKHU¤�WKH�PRVW�WLJKWO\��8QOLNH�WKH�SUHFHGHQFHFKDUW�IRU�RSHUDWRUV��WKH�UHJXODU�H[SUHVVLRQ�SUHFHGHQFH�FKDUW�LV�VLPSOH��ZLWK�RQO\�IRXUOHYHOV��$V�D�ERQXV��WKLV�VHFWLRQ�ZLOO�UHYLHZ�DOO�RI�WKH�PHWDFKDUDFWHUV�WKDW�3HUO�XVHV�LQSDWWHUQV��7DEOH�����VKRZV�WKH�SUHFHGHQFH�

7DEOH������5HJXODU�H[SUHVVLRQ�SUHFHGHQFH

Regular expression feature Example

Parentheses (grouping or memory) (...), (?:...), (?<LABEL>...)

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

Anchors and sequence abc ^a a$

Alternation a|b|c

Atoms a [abc] \d \1

�� $W�WKH�WRS�RI�WKH�SUHFHGHQFH�FKDUW�DUH�WKH�SDUHQWKHVHV���( )���XVHG�IRU�JURXSLQJ�DQGPHPRU\��$Q\WKLQJ�LQ�SDUHQWKHVHV�ZLOO�£VWLFN�WRJHWKHU¤�PRUH�WLJKWO\�WKDQ�DQ\WKLQJHOVH�

�� 7KH�VHFRQG�OHYHO�LV�WKH�TXDQWLILHUV��7KHVH�DUH�WKH�UHSHDW�RSHUDWRUV¢VWDU��*���SOXV�+���DQG�TXHVWLRQ�PDUN��?�¢DV�ZHOO�DV�WKH�TXDQWLILHUV�PDGH�ZLWK�FXUO\�EUDFHV��OLNH{5,15}��{3,}��DQG�{5}��7KHVH�DOZD\V�VWLFN�WR�WKH�LWHP�WKH\¦UH�IROORZLQJ�

�� 7KH�WKLUG�OHYHO�RI�WKH�SUHFHGHQFH�FKDUW�KROGV�DQFKRUV�DQG�VHTXHQFH��7KH�DQFKRUVDUH�WKH�FDUHW��^��VWDUW�RI�VWULQJ�DQFKRU��WKH�GROODU�VLJQ��$��HQG�RI�VWULQJ�DQFKRU��WKH\b�ZRUG�ERXQGDU\�DQFKRU��DQG�WKH�\B�QRQZRUG�ERXQGDU\�DQFKRU��6HTXHQFH��SXW�WLQJ�RQH�LWHP�DIWHU�DQRWKHU��LV�DFWXDOO\�DQ�RSHUDWRU��HYHQ�WKRXJK�LW�GRHVQ¦W�XVH�DPHWDFKDUDFWHU��7KDW�PHDQV�WKDW�OHWWHUV�LQ�D�ZRUG�ZLOO�VWLFN�WRJHWKHU�MXVW�DV�WLJKWO\DV�WKH�DQFKRUV�VWLFN�WR�WKH�OHWWHUV�

�� 7KH�ORZHVW�OHYHO�RI�SUHFHGHQFH�LV�WKH�YHUWLFDO�EDU��|��RI�DOWHUQDWLRQ��6LQFH�WKLV�LV�DWWKH�ERWWRP�RI�WKH�FKDUW��LW�HIIHFWLYHO\�FXWV�WKH�SDWWHUQ�LQWR�SLHFHV��,W¦V�DW�WKH�ERWWRPRI�WKH�FKDUW�EHFDXVH�ZH�ZDQW�WKH� OHWWHUV� LQ�WKH�ZRUGV� LQ�/fred|barney/� WR�VWLFNWRJHWKHU�PRUH�WLJKWO\�WKDQ�WKH�DOWHUQDWLRQ��,I�DOWHUQDWLRQ�ZHUH�RI�KLJKHU�SULRULW\

130 | Chapter 8:ಗMatching with Regular Expressions

WKDQ�VHTXHQFH��WKDW�SDWWHUQ�ZRXOG�PHDQ�WR�PDWFK�fre��IROORZHG�E\�D�FKRLFH�RI�dRU�b��IROORZHG�E\�arney��6R��DOWHUQDWLRQ�LV�DW�WKH�ERWWRP�RI�WKH�FKDUW��DQG�WKH�OHWWHUVZLWKLQ�WKH�QDPHV�VWLFN�WRJHWKHU�

�� $W�WKH�ORZHVW�OHYHO��WKHUH�DUH�WKH�VR�FDOOHG�DWRPV�WKDW�PDNH�XS�WKH�PRVW�EDVLF�SLHFHVRI� WKH�SDWWHUQ��7KHVH�DUH� WKH� LQGLYLGXDO� FKDUDFWHUV�� FKDUDFWHU� FODVVHV�� DQG�EDFNUHIHUHQFHV�

Examples of Precedence:KHQ�\RX�QHHG�WR�GHFLSKHU�D�FRPSOH[�UHJXODU�H[SUHVVLRQ��\RX¦OO�QHHG�WR�GR�DV�3HUOGRHV�DQG�XVH�WKH�SUHFHGHQFH�FKDUW�WR�VHH�ZKDW¦V�UHDOO\�JRLQJ�RQ�

)RU�H[DPSOH��/^fred|barney$/�LV�SUREDEO\�QRW�ZKDW�WKH�SURJUDPPHU�LQWHQGHG��7KDW¦VEHFDXVH�WKH�YHUWLFDO�EDU�RI�DOWHUQDWLRQ�LV�YHU\�ORZ�SUHFHGHQFH��LW�FXWV�WKH�SDWWHUQ�LQ�WZR�7KDW�SDWWHUQ�PDWFKHV�HLWKHU�fred�DW�WKH�EHJLQQLQJ�RI�WKH�VWULQJ�RU�barney�DW�WKH�HQG��,W¦VPXFK�PRUH�OLNHO\�WKDW�WKH�SURJUDPPHU�ZDQWHG�/^(fred|barney)$/��ZKLFK�ZLOO�PDWFKLI�WKH�ZKROH�OLQH�KDV�QRWKLQJ�EXW�fred�RU�QRWKLQJ�EXW�barney� �$QG�ZKDW�ZLOO�/(wilma|pebbles?)/�PDWFK"�7KH�TXHVWLRQ�PDUN�DSSOLHV�WR�WKH�SUHYLRXV�FKDUDFWHU��VR�WKDW�ZLOOPDWFK�HLWKHU�wilma�RU�pebbles�RU�pebble��SHUKDSV�DV�SDUW�RI�D�ODUJHU�VWULQJ��VLQFH�WKHUHDUH�QR�DQFKRUV��

7KH�SDWWHUQ�/^(\w+)\s+(\w+)$/�PDWFKHV�OLQHV�WKDW�KDYH�D�£ZRUG�¤�VRPH�UHTXLUHG�ZKLWH�VSDFH��DQG�DQRWKHU�£ZRUG�¤�ZLWK�QRWKLQJ�HOVH�EHIRUH�RU�DIWHU��7KDW�PLJKW�EH�XVHG�WRPDWFK�OLQHV�OLNH�fred flintstone��IRU�H[DPSOH��7KH�SDUHQWKHVHV�DURXQG�WKH�ZRUGV�DUHQ¦WQHHGHG�IRU�JURXSLQJ��VR�WKH\�PD\�EH�LQWHQGHG�WR�VDYH�WKRVH�VXEVWULQJV�LQWR�WKH�UHJXODUH[SUHVVLRQ�PHPRULHV�

:KHQ�\RX¦UH�WU\LQJ�WR�XQGHUVWDQG�D�FRPSOH[�SDWWHUQ��LW�PD\�EH�KHOSIXO�WR�DGG�SDUHQ�WKHVHV�WR�FODULI\�WKH�SUHFHGHQFH��7KDW¦V�RND\��EXW�UHPHPEHU�WKDW�JURXSLQJ�SDUHQWKHVHVDUH�DOVR�DXWRPDWLFDOO\�PHPRU\�SDUHQWKHVHV��XVH�WKH�QRQFDSWXULQJ�SDUHQWKHVHV�LI�\RXMXVW�ZDQW�WR�JURXS�WKLQJV�

And There’s More$OWKRXJK�ZH¦YH�FRYHUHG�DOO�RI�WKH�UHJXODU�H[SUHVVLRQ�IHDWXUHV�WKDW�PRVW�SHRSOH�DUH�OLNHO\WR�QHHG�IRU�HYHU\GD\�SURJUDPPLQJ��WKHUH�DUH�VWLOO�HYHQ�PRUH�IHDWXUHV��$�IHZ�DUH�FRYHUHGLQ�WKH�$OSDFD�ERRN��EXW�DOVR�FKHFN�WKH�SHUOUH��SHUOUHTXLFN��DQG�SHUOUHWXW�PDQSDJHV�IRUPRUH�LQIRUPDWLRQ�DERXW�ZKDW�SDWWHUQV�LQ�3HUO�FDQ�GR�®

$QG��SHUKDSV��D�QHZOLQH�DW�WKH�HQG�RI�WKH�VWULQJ��DV�ZH�PHQWLRQHG�HDUOLHU�LQ�FRQQHFWLRQ�ZLWK�WKH�$�DQFKRU�

� %HFDXVH�D�TXDQWLILHU�VWLFNV�WR�WKH�OHWWHU�s�PRUH�WLJKWO\�WKDQ�WKH�s�VWLFNV�WR�WKH�RWKHU�OHWWHUV�LQ�pebbles�

® $QG�FKHFN�RXW�YAPE::Regexp::Explain�LQ�&3$1�DV�D�UHJXODU�H[SUHVVLRQ�WR�(QJOLVK�WUDQVODWRU�

Precedence | 131

A Pattern Test Program:KHQ�LQ�WKH�FRXUVH�RI�3HUO�HYHQWV�LW�EHFRPHV�QHFHVVDU\�IRU�D�SURJUDPPHU�WR�ZULWH�DUHJXODU�H[SUHVVLRQ��LW�PD\�EH�GLIILFXOW�WR�WHOO�MXVW�ZKDW�WKH�SDWWHUQ�ZLOO�GR��,W¦V�QRUPDOWR�ILQG�WKDW�D�SDWWHUQ�PDWFKHV�PRUH�WKDQ�\RX�H[SHFWHG��RU�OHVV��2U�LW�PD\�PDWFK�HDUOLHULQ�WKH�VWULQJ�WKDQ�\RX�H[SHFWHG��RU�ODWHU��RU�QRW�DW�DOO�

7KLV�SURJUDP�LV�XVHIXO�WR�WHVW�RXW�D�SDWWHUQ�RQ�VRPH�VWULQJV�DQG�VHH�MXVW�ZKDW�LW�PDWFKHV�DQG�ZKHUH�

#!/usr/bin/perlwhile (<>) { # take one input line at a time chomp; if (/YOUR_PATTERN_GOES_HERE/) { print "Matched: |$`<$&>$'|\n"; # the special match vars } else { print "No match: |$_|\n"; }}

7KLV�SDWWHUQ�WHVW�SURJUDP�LV�ZULWWHQ�IRU�SURJUDPPHUV�WR�XVH��QRW�HQG�XVHUV��\RX�FDQ�WHOOEHFDXVH�LW�GRHVQ¦W�KDYH�DQ\�SURPSWV�RU�XVDJH�LQIRUPDWLRQ��,W�ZLOO�WDNH�DQ\�QXPEHU�RILQSXW�OLQHV�DQG�FKHFN�HDFK�RQH�DJDLQVW�WKH�SDWWHUQ�WKDW�\RX¦OO�SXW�LQ�SODFH�RI�WKH�VWULQJVD\LQJ�YOUR_PATTERN_GOES_HERE��)RU�HDFK� OLQH�WKDW�PDWFKHV�� LW�XVHV�WKH�WKUHH�VSHFLDOPDWFK�YDULDEOHV��$`��$&��DQG�$'��WR�PDNH�D�SLFWXUH�RI�ZKHUH�WKH�PDWFK�KDSSHQHG��:KDW\RX¦OO�VHH�LV�WKLV��LI�WKH�SDWWHUQ�LV�/match/�DQG�WKH�LQSXW�LV�beforematchafter��WKH�RXWSXWZLOO�VD\�£|before<match>after|¤���XVLQJ�DQJOH�EUDFNHWV�WR�VKRZ�\RX�MXVW�ZKDW�SDUW�RIWKH�VWULQJ�ZDV�PDWFKHG�E\�\RXU�SDWWHUQ��,I�\RXU�SDWWHUQ�PDWFKHV�VRPHWKLQJ�\RX�GLGQ¦WH[SHFW��\RX¦OO�EH�DEOH�WR�VHH�WKDW�ULJKW�DZD\�

Exercises6HYHUDO� RI� WKHVH� H[HUFLVHV� DVN� \RX� WR� XVH� WKH� WHVW� SURJUDP� IURP� WKLV� FKDSWHU�� <RXFRXOG�PDQXDOO\�W\SH�XS�WKLV�SURJUDP��WDNLQJ�JUHDW�FDUH�WR�JHW�DOO�RI�WKH�RGG�SXQFWXDWLRQPDUNV�FRUUHFW� �%XW�\RX¦OO�SUREDEO\�ILQG�LW�IDVWHU�DQG�HDVLHU�WR�VLPSO\�GRZQORDG�WKHSURJUDP�DQG�VRPH�RWKHU�JRRGLHV�IURP�WKH�2¦5HLOO\�ZHE�VLWH��DV�ZH�PHQWLRQHG�LQ�WKH3UHIDFH��<RX¦OO�ILQG�WKLV�SURJUDP�XQGHU�WKH�QDPH�SDWWHUQBWHVW��

6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

,I�\RX�GR�W\SH�LW�XS�RQ�\RXU�RZQ��UHPHPEHU�WKDW�WKH�EDFNTXRWH�FKDUDFWHU��`��LV�QRW�WKH�VDPH�DV�WKH�DSRVWURSKH�'���2Q�PRVW�IXOO�VL]HG�FRPSXWHU�NH\ERDUGV�WKHVH�GD\V��LQ�WKH�8�6���DW�OHDVW���WKH�EDFNTXRWH�LV�IRXQG�RQ�D�NH\LPPHGLDWHO\�WR�WKH�OHIW�RI�WKH�1�NH\�

� 'RQ¦W�EH�VXUSULVHG�LI�WKH�SURJUDP�\RX�GRZQORDG�LV�D�VOLJKWO\�GLIIHUHQW�YHUVLRQ�WKDQ�ZKDW�ZH�KDYH�LQ�WKH�ERRN�

132 | Chapter 8:ಗMatching with Regular Expressions

�� >�@�8VLQJ�WKH�SDWWHUQ�WHVW�SURJUDP��PDNH�D�SDWWHUQ�WR�PDWFK�WKH�VWULQJ�match��7U\WKH�SURJUDP�ZLWK�WKH�LQSXW�VWULQJ�beforematchafter��'RHV�WKH�RXWSXW�VKRZ�WKHWKUHH�SDUWV�RI�WKH�PDWFK�LQ�WKH�ULJKW�RUGHU"

�� >�@�8VLQJ�WKH�SDWWHUQ�WHVW�SURJUDP��PDNH�D�SDWWHUQ�WKDW�PDWFKHV�LI�DQ\�ZRUG��LQWKH�\w�VHQVH�RI�ZRUG��HQGV�ZLWK�WKH�OHWWHU�a��'RHV�LW�PDWFK�wilma�EXW�QRW�barney"'RHV�LW�PDWFK�Mrs. Wilma Flintstone"�:KDW�DERXW�wilma&fred"�7U\�LW�RQ�WKH�VDPSOHWH[W�ILOH�IURP�WKH�SUHYLRXV�FKDSWHU¦V�H[HUFLVHV��DQG�DGG�WKHVH�WHVW�VWULQJV�LI�WKH\ZHUHQ¦W�DOUHDG\�LQ�WKHUH��

�� >�@�0RGLI\�WKH�SURJUDP�IURP�WKH�SUHYLRXV�H[HUFLVH�VR�WKDW�WKH�ZRUG�HQGLQJ�ZLWKWKH�OHWWHU�a�LV�FDSWXUHG�LQWR�PHPRU\�$1��8SGDWH�WKH�FRGH�WR�GLVSOD\�WKDW�YDULDEOH¦VFRQWHQWV�LQ�VLQJOH�TXRWHV��VRPHWKLQJ�OLNH�$1 contains 'Wilma'�

�� >�@�0RGLI\�WKH�SURJUDP�IURP�WKH�SUHYLRXV�H[HUFLVH�WR�XVH�QDPHG�FDSWXUHV�LQVWHDGRI�UHO\LQJ�RQ�$1��8SGDWH�WKH�FRGH�WR�GLVSOD\�WKDW�ODEHO�QDPH��VRPHWKLQJ�OLNH�'word'contains 'Wilma'�

�� >�@�([WUD�FUHGLW�H[HUFLVH��PRGLI\�WKH�SURJUDP�IURP�WKH�SUHYLRXV�H[HUFLVH�VR�WKDWLPPHGLDWHO\�IROORZLQJ�WKH�ZRUG�HQGLQJ�LQ�a�LW�ZLOO�DOVR�FDSWXUH�XS�WR�ILYH�FKDUDFWHUV�LI�WKHUH�DUH�WKDW�PDQ\�FKDUDFWHUV��RI�FRXUVH��LQ�D�VHSDUDWH�PHPRU\�YDULDEOH��8SGDWHWKH�FRGH�WR�GLVSOD\�ERWK�PHPRU\�YDULDEOHV��)RU�H[DPSOH��LI�WKH�LQSXW�VWULQJ�VD\V�Isaw Wilma yesterday��WKH�XS�WR�ILYH�FKDUDFWHUV�DUH�yest��,I�WKH�LQSXW�LV�I, Wilma!�WKH�H[WUD�PHPRU\�VKRXOG�KDYH�MXVW�RQH�FKDUDFWHU��'RHV�\RXU�SDWWHUQ�VWLOO�PDWFKMXVW�SODLQ�wilma"

�� >�@�:ULWH�D�QHZ�SURJUDP��QRW� WKH� WHVW�SURJUDP��� WKDW�SULQWV�RXW�DQ\� LQSXW� OLQHHQGLQJ�ZLWK�ZKLWHVSDFH��RWKHU�WKDQ�MXVW�D�QHZOLQH���3XW�D�PDUNHU�FKDUDFWHU�DW�WKHHQG�RI�WKH�RXWSXW�OLQH�VR�DV�WR�PDNH�WKH�ZKLWHVSDFH�YLVLEOH�

Exercises | 133

CHAPTER 9

Processing Text with RegularExpressions

<RX�FDQ�XVH�UHJXODU�H[SUHVVLRQV�WR�FKDQJH�WH[W�WRR��6R�IDU�ZH¦YH�RQO\�VKRZQ�\RX�KRZWR�PDWFK�D�SDWWHUQ��DQG�QRZ�ZH¦OO�VKRZ�\RX�KRZ�WR�XVH�SDWWHUQV�WR�ORFDWH�WKH�SDUWV�RIVWULQJV�WKDW�\RX�ZDQW�WR�FKDQJH�

Substitutions with s///,I�\RX� WKLQN�RI� WKH�m//�SDWWHUQ�PDWFK�DV�EHLQJ� OLNH�\RXU�ZRUG�SURFHVVRU¦V�£VHDUFK¤IHDWXUH��WKH�£VHDUFK�DQG�UHSODFH¤�IHDWXUH�ZRXOG�EH�3HUO¦V�s///�VXEVWLWXWLRQ�RSHUDWRU��7KLV�VLPSO\�UHSODFHV�ZKDWHYHU�SDUW�RI�D�YDULDEOH �PDWFKHV�D�SDWWHUQ�ZLWK�D�UHSODFHPHQWVWULQJ�

$_ = "He's out bowling with Barney tonight.";s/Barney/Fred/; # Replace Barney with Fredprint "$_\n";

,I�WKH�PDWFK�IDLOV��QRWKLQJ�KDSSHQV��DQG�WKH�YDULDEOH�LV�XQWRXFKHG�

# Continuing from above; $_ has "He's out bowling with Fred tonight."s/Wilma/Betty/; # Replace Wilma with Betty (fails)

2I�FRXUVH��ERWK�WKH�SDWWHUQ�DQG�WKH�UHSODFHPHQW�VWULQJ�FRXOG�EH�PRUH�FRPSOH[��+HUH�WKH�UHSODFHPHQW�VWULQJ�XVHV�WKH�ILUVW�PHPRU\�YDULDEOH��$1��ZKLFK�LV�VHW�E\�WKH�SDWWHUQPDWFK�

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

+HUH�DUH�VRPH�RWKHU�SRVVLEOH�VXEVWLWXWLRQV���7KHVH�DUH�KHUH�RQO\�DV�VDPSOHV��LQ�WKH�UHDOZRUOG��LW�ZRXOG�QRW�EH�W\SLFDO�WR�GR�VR�PDQ\�XQUHODWHG�VXEVWLWXWLRQV�LQ�D�URZ��

8QOLNH�m//��ZKLFK�FDQ�PDWFK�DJDLQVW�DQ\�VWULQJ�H[SUHVVLRQ��s///�LV�PRGLI\LQJ�GDWD�WKDW�PXVW�WKHUHIRUH�EHFRQWDLQHG�LQ�ZKDW¦V�NQRZQ�DV�DQ�OYDOXH��7KLV�LV�QHDUO\�DOZD\V�D�YDULDEOH��DOWKRXJK�LW�FRXOG�DFWXDOO\�EH�DQ\WKLQJWKDW�FRXOG�EH�XVHG�RQ�WKH�OHIW�VLGH�RI�DQ�DVVLJQPHQW�RSHUDWRU�

135

$_ = "green scaly dinosaur";s/(\w+) (\w+)/$2, $1/; # Now it's "scaly, green dinosaur"s/^/huge, /; # Now it's "huge, scaly, green dinosaur"s/,.*een//; # Empty replacement: Now it's "huge dinosaur"s/green/red/; # Failed match: still "huge dinosaur"s/\w+$/($`!)$&/; # Now it's "huge (huge !)dinosaur"s/\s+(!\W+)/$1 /; # Now it's "huge (huge!) dinosaur"s/huge/gigantic/; # Now it's "gigantic (huge!) dinosaur"

7KHUH¦V�D�XVHIXO�%RROHDQ�YDOXH� IURP�s///�� LW¦V� WUXH� LI� D� VXEVWLWXWLRQ�ZDV� VXFFHVVIXO�RWKHUZLVH��LW¦V�IDOVH�

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

Global Replacements with /g$V�\RX�PD\�KDYH�QRWLFHG�LQ�D�SUHYLRXV�H[DPSOH��s///�ZLOO�PDNH�MXVW�RQH�UHSODFHPHQW�HYHQ� LI� RWKHUV� DUH�SRVVLEOH��2I� FRXUVH�� WKDW¦V� MXVW� WKH�GHIDXOW��7KH� /g�PRGLILHU� WHOOVs///�WR�PDNH�DOO�SRVVLEOH�QRQRYHUODSSLQJ �UHSODFHPHQWV�

$_ = "home, sweet home!";s/home/cave/g;print "$_\n"; # "cave, sweet cave!"

$�IDLUO\�FRPPRQ�XVH�RI�D�JOREDO�UHSODFHPHQW�LV�WR�FROODSVH�ZKLWHVSDFH��WKDW�LV��WR�WXUQDQ\�DUELWUDU\�ZKLWHVSDFH�LQWR�D�VLQJOH�VSDFH�

$_ = "Input data\t may have extra whitespace.";s/\s+/ /g; # Now it says "Input data may have extra whitespace."

2QFH�ZH�VKRZ�FROODSVLQJ�ZKLWHVSDFH��HYHU\RQH�ZDQWV�WR�NQRZ�DERXW�VWULSSLQJ�OHDGLQJDQG�WUDLOLQJ�ZKLWHVSDFH��7KDW¦V�HDV\�HQRXJK��LQ�WZR�VWHSV�

s/^\s+//; # Replace leading whitespace with nothings/\s+$//; # Replace trailing whitespace with nothing

:H�FRXOG�GR�WKDW�LQ�RQH�VWHS�ZLWK�DQ�DOWHUQDWLRQ�DQG�WKH�/g�IODJ��EXW�WKDW�WXUQV�RXW�WREH�D�ELW�VORZHU��DW�OHDVW�ZKHQ�ZH�ZURWH�WKLV��7KH�UHJXODU�H[SUHVVLRQ�HQJLQH�LV�DOZD\VEHLQJ�WXQHG��EXW�WR�OHDUQ�PRUH�DERXW�WKDW��\RX�FDQ�JHW�-HIIUH\�)ULHGO¦V�0DVWHULQJ�5HJXODU([SUHVVLRQV��2¦5HLOO\��DQG�ILQG�RXW�ZKDW�PDNHV�UHJXODU�H[SUHVVLRQV�IDVW��RU�VORZ��

s/^\s+|\s+$//g; # Strip leading, trailing whitespace

Different Delimiters-XVW�DV�ZH�GLG�ZLWK�m//�DQG�qw//��ZH�FDQ�FKDQJH�WKH�GHOLPLWHUV�IRU�s///��%XW�WKH�VXE�VWLWXWLRQ�XVHV�WKUHH�GHOLPLWHU�FKDUDFWHUV��VR�WKLQJV�DUH�D�OLWWOH�GLIIHUHQW�

,W¦V�QRQRYHUODSSLQJ�EHFDXVH�HDFK�QHZ�PDWFK�VWDUWV�ORRNLQJ�MXVW�EH\RQG�WKH�ODWHVW�UHSODFHPHQW�

136 | Chapter 9:ಗProcessing Text with Regular Expressions

:LWK�RUGLQDU\��QRQSDLUHG��FKDUDFWHUV��ZKLFK�GRQ¦W�KDYH�D�OHIW�DQG�ULJKW�YDULHW\��MXVWXVH�WKUHH�RI�WKHP��DV�ZH�GLG�ZLWK�WKH�IRUZDUG�VODVK��+HUH��ZH¦YH�FKRVHQ�WKH�SRXQGVLJQ �DV�WKH�GHOLPLWHU�

s#^https://#http://#;

%XW�LI�\RX�XVH�SDLUHG�FKDUDFWHUV��ZKLFK�KDYH�D�OHIW�DQG�ULJKW�YDULHW\��\RX�KDYH�WR�XVHWZR�SDLUV��RQH�WR�KROG�WKH�SDWWHUQ�DQG�RQH�WR�KROG�WKH�UHSODFHPHQW�VWULQJ��,Q�WKLV�FDVH�WKH�GHOLPLWHUV�GRQ¦W�KDYH�WR�EH�WKH�VDPH�NLQG�DURXQG�WKH�VWULQJ�DV�WKH\�DUH�DURXQG�WKHSDWWHUQ��,Q�IDFW��WKH�GHOLPLWHUV�RI�WKH�VWULQJ�FRXOG�HYHQ�EH�QRQSDLUHG��7KHVH�DUH�DOO�WKHVDPH�

s{fred}{barney};s[fred](barney);s<fred>#barney#;

Option Modifiers,Q�DGGLWLRQ�WR�WKH�/g�PRGLILHU���VXEVWLWXWLRQV�PD\�XVH�WKH�/i��/x��DQG�/s�PRGLILHUV�WKDW\RX�VDZ�LQ�RUGLQDU\�SDWWHUQ�PDWFKLQJ��WKH�RUGHU�RI�PRGLILHUV�LVQ¦W�VLJQLILFDQW��

s#wilma#Wilma#gi; # replace every WiLmA or WILMA with Wilmas{__END__.*}{}s; # chop off the end marker and all following lines

The Binding Operator-XVW�DV�\RX�VDZ�ZLWK�m//��ZH�FDQ�FKRRVH�D�GLIIHUHQW�WDUJHW�IRU�s///�E\�XVLQJ�WKH�ELQGLQJRSHUDWRU�

$file_name =~ s#^.*/##s; # In $file_name, remove any Unix-style path

Case Shifting,W�RIWHQ�KDSSHQV�LQ�D�VXEVWLWXWLRQ�WKDW�\RX¦OO�ZDQW�WR�PDNH�VXUH�WKDW�D�UHSODFHPHQW�ZRUGLV�SURSHUO\�FDSLWDOL]HG��RU�QRW��DV�WKH�FDVH�PD\�EH���7KDW¦V�HDV\�WR�DFFRPSOLVK�ZLWK�3HUO�E\�XVLQJ�VRPH�EDFNVODVK�HVFDSHV��7KH�\U�HVFDSH�IRUFHV�ZKDW�IROORZV�WR�DOO�XSSHUFDVH�

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

6LPLODUO\��WKH�\L�HVFDSH�IRUFHV�ORZHUFDVH��&RQWLQXLQJ�IURP�WKH�SUHYLRXV�FRGH�

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

%\�GHIDXOW��WKHVH�DIIHFW�WKH�UHVW�RI�WKH��UHSODFHPHQW��VWULQJ��RU�\RX�FDQ�WXUQ�RII�FDVHVKLIWLQJ�ZLWK�\E�

:LWK�DSRORJLHV�WR�RXU�%ULWLVK�IULHQGV��WR�ZKRP�WKH�SRXQG�VLJQ�LV�VRPHWKLQJ�HOVH��$OWKRXJK�WKH�SRXQG�VLJQLV�JHQHUDOO\�WKH�VWDUW�RI�D�FRPPHQW�LQ�3HUO�� LW�ZRQ¦W�VWDUW�D�FRPPHQW�ZKHQ�WKH�SDUVHU�NQRZV�WR�H[SHFW�DGHOLPLWHU¢LQ�WKLV�FDVH��LPPHGLDWHO\�DIWHU�WKH�s�WKDW�VWDUWV�WKH�VXEVWLWXWLRQ�

� :H�VWLOO�VSHDN�RI�WKH�PRGLILHUV�ZLWK�QDPHV�OLNH�/i��HYHQ�LI�WKH�GHOLPLWHU�LV�VRPHWKLQJ�RWKHU�WKDQ�D�VODVK�

Substitutions with s/// | 137

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

:KHQ�ZULWWHQ�LQ�ORZHUFDVH��\l�DQG�\u����WKH\�DIIHFW�RQO\�WKH�QH[W�FKDUDFWHU�

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

<RX�FDQ�HYHQ�VWDFN�WKHP�XS��8VLQJ�\u�ZLWK�\L�PHDQV�£DOO�ORZHUFDVH��EXW�FDSLWDOL]H�WKHILUVW�OHWWHU¤�

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

$V�LW�KDSSHQV��DOWKRXJK�ZH¦UH�FRYHULQJ�FDVH�VKLIWLQJ�LQ�UHODWLRQ�WR�VXEVWLWXWLRQV��WKHVHHVFDSH�VHTXHQFHV�DUH�DYDLODEOH�LQ�DQ\�GRXEOH�TXRWLVK�VWULQJ�

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

The split Operator$QRWKHU�RSHUDWRU�WKDW�XVHV�UHJXODU�H[SUHVVLRQV�LV�split��ZKLFK�EUHDNV�XS�D�VWULQJ�DF�FRUGLQJ� WR� D� SDWWHUQ�� 7KLV� LV� XVHIXO� IRU� WDE�VHSDUDWHG� GDWD�� RU� FRORQ�VHSDUDWHG�ZKLWHVSDFH�VHSDUDWHG��RU�DQ\WKLQJ�VHSDUDWHG�GDWD��UHDOO\���6R�ORQJ�DV�\RX�FDQ�VSHFLI\WKH�VHSDUDWRU�ZLWK�D�UHJXODU�H[SUHVVLRQ��DQG�JHQHUDOO\��LW¦V�D�VLPSOH�UHJXODU�H[SUHVVLRQ��\RX�FDQ�XVH�split��,W�ORRNV�OLNH�WKLV�

@fields = split /separator/, $string;

7KH�split�RSHUDWRU®�GUDJV�WKH�SDWWHUQ�WKURXJK�D�VWULQJ�DQG�UHWXUQV�D�OLVW�RI�ILHOGV��VXE�VWULQJV��WKDW�ZHUH�VHSDUDWHG�E\�WKH�VHSDUDWRUV��:KHQHYHU�WKH�SDWWHUQ�PDWFKHV��WKDW¦VWKH�HQG�RI�RQH�ILHOG�DQG�WKH�VWDUW�RI�WKH�QH[W��6R��DQ\WKLQJ�WKDW�PDWFKHV�WKH�SDWWHUQ�ZLOOQHYHU�VKRZ�XS�LQ�WKH�UHWXUQHG�ILHOGV��+HUH¦V�D�W\SLFDO�split�SDWWHUQ��VSOLWWLQJ�RQ�FRORQV�

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

<RX�FRXOG�HYHQ�KDYH�DQ�HPSW\�ILHOG��LI�WKHUH�ZHUH�WZR�GHOLPLWHUV�WRJHWKHU�

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

+HUH¦V�D�UXOH�WKDW�VHHPV�RGG�DW�ILUVW��EXW�LW�UDUHO\�FDXVHV�SUREOHPV��OHDGLQJ�HPSW\�ILHOGVDUH�DOZD\V�UHWXUQHG��EXW�WUDLOLQJ�HPSW\�ILHOGV�DUH�GLVFDUGHG��)RU�H[DPSOH�

@fields = split /:/, ":::a:b:c:::"; # gives ("", "", "", "a", "b", "c")

7KH�\L�DQG�\u�PD\�DSSHDU�WRJHWKHU�LQ�HLWKHU�RUGHU��/DUU\�UHDOL]HG�WKDW�SHRSOH�ZRXOG�VRPHWLPHV�JHW�WKRVH�WZREDFNZDUG��VR�KH�PDGH�3HUO�ILJXUH�RXW�WKDW�\RX�ZDQW�MXVW�WKH�ILUVW�OHWWHU�FDSLWDOL]HG�DQG�WKH�UHVW�ORZHUFDVH�/DUU\�LV�D�SUHWW\�QLFH�JX\�

� ([FHSW�£FRPPD�VHSDUDWHG�YDOXHV�¤�QRUPDOO\�FDOOHG�&69�ILOHV��7KRVH�DUH�D�SDLQ�WR�GR�ZLWK�split��\RX¦UH�EHWWHURII�JHWWLQJ�WKH�Text::CSV�PRGXOH�IURP�&3$1�

® ,W¦V�DQ�RSHUDWRU��HYHQ�WKRXJK�LW�DFWV�D�ORW�OLNH�D�IXQFWLRQ��DQG�HYHU\RQH�JHQHUDOO\�FDOOV�LW�D�IXQFWLRQ��%XW�WKHWHFKQLFDO�GHWDLOV�RI�WKH�GLIIHUHQFH�DUH�EH\RQG�WKH�VFRSH�RI�WKLV�ERRN�

7KLV�LV�PHUHO\�WKH�GHIDXOW��,W¦V�WKLV�ZD\�IRU�HIILFLHQF\��,I�\RX�ZRUU\�DERXW�ORVLQJ�WUDLOLQJ�HPSW\�ILHOGV��XVH�!1DV�D�WKLUG�DUJXPHQW�WR�split�DQG�WKH\¦OO�EH�NHSW��VHH�WKH�SHUOIXQF�PDQSDJH�

138 | Chapter 9:ಗProcessing Text with Regular Expressions

,W¦V�DOVR�FRPPRQ�WR�split�RQ�ZKLWHVSDFH��XVLQJ�/\s+/�DV�WKH�SDWWHUQ��8QGHU�WKDW�SDWWHUQ�DOO�ZKLWHVSDFH�UXQV�DUH�HTXLYDOHQW�WR�D�VLQJOH�VSDFH�

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

7KH�GHIDXOW�IRU�split�LV�WR�EUHDN�XS�$_�RQ�ZKLWHVSDFH�

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

7KLV�LV�DOPRVW�WKH�VDPH�DV�XVLQJ�/\s+/�DV�WKH�SDWWHUQ��H[FHSW�WKDW�LQ�WKLV�VSHFLDO�FDVH�DOHDGLQJ�HPSW\�ILHOG�LV�VXSSUHVVHG¢VR��LI�WKH�OLQH�VWDUWV�ZLWK�ZKLWHVSDFH��\RX�ZRQ¦W�VHHDQ�HPSW\�ILHOG�DW�WKH�VWDUW�RI�WKH�OLVW���,I�\RX¦G�OLNH�WR�JHW�WKH�VDPH�EHKDYLRU�ZKHQ�VSOLWWLQJDQRWKHU�VWULQJ�RQ�ZKLWHVSDFH��MXVW�XVH�D�VLQJOH�VSDFH�LQ�SODFH�RI�WKH�SDWWHUQ��split ' ',$other_string��8VLQJ�D�VSDFH�LQVWHDG�RI�WKH�SDWWHUQ�LV�D�VSHFLDO�NLQG�RI�split��

*HQHUDOO\��WKH�SDWWHUQV�XVHG�IRU�split�DUH�DV�VLPSOH�DV�WKH�RQHV�\RX�VHH�KHUH��%XW�LI�WKHSDWWHUQ�EHFRPHV�PRUH�FRPSOH[��EH�VXUH� WR�DYRLG�XVLQJ�PHPRU\�SDUHQWKHVHV� LQ� WKHSDWWHUQ�VLQFH�WKHVH�WULJJHU�WKH��XVXDOO\��ZDQWHG�£VHSDUDWRU�UHWHQWLRQ�PRGH¤��VHH�WKHSHUOIXQF�PDQSDJH�IRU�GHWDLOV���8VH�WKH�QRQFDSWXULQJ�SDUHQWKHVHV��(?:)��LQ�split�LI�\RXQHHG�WR�JURXS�WKLQJV�

The join Function7KH�join�IXQFWLRQ�GRHVQ¦W�XVH�SDWWHUQV��EXW�SHUIRUPV�WKH�RSSRVLWH�IXQFWLRQ�RI�split�split�EUHDNV�XS�D�VWULQJ�LQWR�D�QXPEHU�RI�SLHFHV��DQG�join�JOXHV�WRJHWKHU�D�EXQFK�RISLHFHV�WR�PDNH�D�VLQJOH�VWULQJ��7KH�join�IXQFWLRQ�ORRNV�OLNH�WKLV�

my $result = join $glue, @pieces;

7KH�ILUVW�DUJXPHQW�WR�join�LV�WKH�JOXH��ZKLFK�PD\�EH�DQ\�VWULQJ��7KH�UHPDLQLQJ�DUJX�PHQWV�DUH�D�OLVW�RI�SLHFHV��join�SXWV�WKH�JOXH�VWULQJ�EHWZHHQ�WKH�SLHFHV�DQG�UHWXUQV�WKHUHVXOWLQJ�VWULQJ�

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

,Q�WKDW�H[DPSOH��ZH�KDG�ILYH�LWHPV��VR�WKHUH�DUH�RQO\�IRXU�FRORQV��7KDW�LV��WKHUH�DUH�IRXUSLHFHV�RI�JOXH��7KH�JOXH�VKRZV�XS�RQO\�EHWZHHQ�WKH�SLHFHV��QHYHU�EHIRUH�RU�DIWHU�WKHP�6R��WKHUH�ZLOO�EH�RQH�IHZHU�SLHFH�RI�JOXH�WKDQ�WKH�QXPEHU�RI�LWHPV�LQ�WKH�OLVW�

7KLV�PHDQV�WKDW�WKHUH�PD\�EH�QR�JOXH�DW�DOO�LI�WKH�OLVW�GRHVQ¦W�KDYH�DW�OHDVW�WZR�HOHPHQWV�

my $y = join "foo", "bar"; # gives just "bar", since no fooglue is neededmy @empty; # empty arraymy $empty = join "baz", @empty; # no items, so it's an empty string

8VLQJ�$x�IURP�DERYH��ZH�FDQ�EUHDN�XS�D�VWULQJ�DQG�SXW�LW�EDFN�WRJHWKHU�ZLWK�D�GLIIHUHQWGHOLPLWHU�

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

The join Function | 139

$OWKRXJK�split�DQG�join�ZRUN�ZHOO�WRJHWKHU��GRQ¦W�IRUJHW�WKDW�WKH�ILUVW�DUJXPHQW�WRjoin�LV�DOZD\V�D�VWULQJ��QRW�D�SDWWHUQ�

m// in List Context:KHQ�\RX�XVH�split��WKH�SDWWHUQ�VSHFLILHV�WKH�VHSDUDWRU��WKH�SDUW�WKDW�LVQ¦W�WKH�XVHIXOGDWD��6RPHWLPHV�LW¦V�HDVLHU�WR�VSHFLI\�ZKDW�\RX�ZDQW�WR�NHHS�

:KHQ�D�SDWWHUQ�PDWFK��m//��LV�XVHG�LQ�D�OLVW�FRQWH[W��WKH�UHWXUQ�YDOXH�LV�D�OLVW�RI�WKHPHPRU\�YDULDEOHV�FUHDWHG�LQ�WKH�PDWFK��RU�DQ�HPSW\�OLVW�LI�WKH�PDWFK�IDLOHG�

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

7KLV�PDNHV�LW�HDV\�WR�JLYH�WKH�PDWFK�YDULDEOHV�HDV\�WR�XVH�QDPHV��DQG�WKHVH�QDPHV�PD\SHUVLVW�SDVW�WKH�QH[W�SDWWHUQ�PDWFK���1RWH�DOVR�WKDW�EHFDXVH�WKHUH¦V�QR�=~�LQ�WKDW�FRGH�WKH�SDWWHUQ�PDWFKHV�DJDLQVW�$_�E\�GHIDXOW��

7KH�/g�PRGLILHU�WKDW�\RX�ILUVW�VDZ�RQ�s///�DOVR�ZRUNV�ZLWK�m//��ZKLFK�OHWV�LW�PDWFK�DWPRUH�WKDQ�RQH�SODFH�LQ�D�VWULQJ��,Q�WKLV�FDVH��D�SDWWHUQ�ZLWK�D�SDLU�RI�SDUHQWKHVHV�ZLOOUHWXUQ�D�PHPRU\�IURP�HDFK�WLPH�LW�PDWFKHV�

my $text = "Fred dropped a 5 ton granite block on Mr. Slate";my @words = ($text =~ /([a-z]+)/ig);print "Result: @words\n";# Result: Fred dropped a ton granite block on Mr Slate

7KLV�LV�OLNH�XVLQJ�split�£LQVLGH�RXW¤��LQVWHDG�RI�VSHFLI\LQJ�ZKDW�ZH�ZDQW�WR�UHPRYH��ZHVSHFLI\�ZKDW�ZH�ZDQW�WR�NHHS�

,Q�IDFW��LI�WKHUH�LV�PRUH�WKDQ�RQH�SDLU�RI�SDUHQWKHVHV��HDFK�PDWFK�PD\�UHWXUQ�PRUH�WKDQRQH�VWULQJ��/HW¦V�VD\�WKDW�ZH�KDYH�D�VWULQJ�WKDW�ZH�ZDQW�WR�UHDG�LQWR�D�KDVK��VRPHWKLQJOLNH�WKLV�

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

(DFK�WLPH�WKH�SDWWHUQ�PDWFKHV��LW�UHWXUQV�D�SDLU�RI�PHPRULHV��7KRVH�SDLUV�RI�YDOXHV�WKHQEHFRPH�WKH�NH\�YDOXH�SDLUV�LQ�WKH�QHZO\�FUHDWHG�KDVK�

More Powerful Regular Expressions$IWHU�DOUHDG\�UHDGLQJ�WKUHH��DOPRVW���FKDSWHUV�DERXW�UHJXODU�H[SUHVVLRQV��\RX�NQRZ�WKDWWKH\¦UH�D�SRZHUIXO�IHDWXUH�LQ�WKH�FRUH�RI�3HUO��%XW�WKHUH�DUH�HYHQ�PRUH�IHDWXUHV�WKDW�WKH3HUO�GHYHORSHUV�KDYH�DGGHG��\RX¦OO�VHH�VRPH�RI�WKH�PRVW�LPSRUWDQW�RQHV�LQ�WKLV�VHFWLRQ�$W�WKH�VDPH�WLPH��\RX¦OO�VHH�D�OLWWOH�PRUH�DERXW�WKH�LQWHUQDO�RSHUDWLRQ�RI�WKH�UHJXODUH[SUHVVLRQ�HQJLQH�

140 | Chapter 9:ಗProcessing Text with Regular Expressions

Nongreedy Quantifiers7KH�IRXU�TXDQWLILHUV�\RX¦YH�DOUHDG\�VHHQ��LQ�&KDSWHUV���DQG����DUH�DOO�JUHHG\��7KDW�PHDQVWKDW�WKH\�PDWFK�DV�PXFK�DV�WKH\�FDQ��RQO\�WR�UHOXFWDQWO\�JLYH�VRPH�EDFN�LI�WKDW¦V�QHF�HVVDU\�WR�DOORZ�WKH�RYHUDOO�SDWWHUQ�WR�VXFFHHG��+HUH¦V�DQ�H[DPSOH��6XSSRVH�\RX¦UH�XVLQJWKH�SDWWHUQ�/fred.+barney/�RQ�WKH�VWULQJ�fred and barney went bowling last night�2I�FRXUVH��ZH�NQRZ�WKDW�WKH�UHJXODU�H[SUHVVLRQ�ZLOO�PDWFK�WKDW�VWULQJ��EXW�OHW¦V�VHH�KRZLW�JRHV�DERXW�LW� �)LUVW��RI�FRXUVH��WKH�VXESDWWHUQ�fred�PDWFKHV�WKH�LGHQWLFDO�OLWHUDO�VWULQJ�7KH�QH[W�SDUW�RI�WKH�SDWWHUQ�LV�WKH�.+��ZKLFK�PDWFKHV�DQ\�FKDUDFWHU�H[FHSW�QHZOLQH��DWOHDVW�RQH�WLPH��%XW�WKH�SOXV�TXDQWLILHU�LV�JUHHG\��LW�SUHIHUV�WR�PDWFK�DV�PXFK�DV�SRVVLEOH�6R�LW�LPPHGLDWHO\�PDWFKHV�DOO�RI�WKH�UHVW�RI�WKH�VWULQJ��LQFOXGLQJ�WKH�ZRUG�night���7KLVPD\�VXUSULVH�\RX��EXW�WKH�VWRU\�LVQ¦W�RYHU�\HW��

1RZ�WKH�VXESDWWHUQ�barney�ZRXOG�OLNH�WR�PDWFK��EXW�LW�FDQ¦W¢ZH¦UH�DW�WKH�HQG�RI�WKHVWULQJ��%XW�VLQFH�WKH�.+�FRXOG�VWLOO�EH�VXFFHVVIXO�HYHQ�LI�LW�PDWFKHG�RQH�IHZHU�FKDUDFWHU�LW�UHOXFWDQWO\�JLYHV�EDFN�WKH�OHWWHU�t�DW�WKH�HQG�RI�WKH�VWULQJ���,W¦V�JUHHG\��EXW�LW�ZDQWVWKH�ZKROH�SDWWHUQ�WR�VXFFHHG�HYHQ�PRUH�WKDQ�LW�ZDQWV�WR�PDWFK�HYHU\WKLQJ�DOO�E\�LWVHOI��

7KH�VXESDWWHUQ�barney�WULHV�DJDLQ�WR�PDWFK��DQG�VWLOO�FDQ¦W��6R�WKH�.+�JLYHV�EDFN�WKHOHWWHU�h� DQG� OHWV� LW� WU\�DJDLQ��2QH�FKDUDFWHU�DIWHU�DQRWKHU�� WKH�.+�JLYHV�EDFN�ZKDW� LWPDWFKHG�XQWLO�ILQDOO\�LW�JLYHV�XS�DOO�RI�WKH�OHWWHUV�RI�barney��1RZ��ILQDOO\��WKH�VXESDWWHUQbarney�FDQ�PDWFK��DQG�WKH�RYHUDOO�PDWFK�VXFFHHGV�

5HJXODU�H[SUHVVLRQ�HQJLQHV�GR�D�ORW�RI�EDFNWUDFNLQJ�OLNH�WKDW��WU\LQJ�HYHU\�GLIIHUHQW�ZD\RI�ILWWLQJ�WKH�SDWWHUQ�WR�WKH�VWULQJ�XQWLO�RQH�RI�WKHP�VXFFHHGV��RU�XQWLO�QRQH�RI�WKHPKDV���%XW�DV�\RX�FRXOG�VHH�IURP�WKLV�H[DPSOH��WKDW�FDQ�LQYROYH�D�ORW�RI�EDFNWUDFNLQJ��DVWKH�TXDQWLILHU�JREEOHV�XS�WRR�PXFK�RI� WKH�VWULQJ�DQG�WKH�UHJXODU�H[SUHVVLRQ�HQJLQHIRUFHV�LW�WR�UHWXUQ�VRPH�RI�LW�

)RU�HDFK�RI�WKH�JUHHG\�TXDQWLILHUV��WKRXJK��WKHUH¦V�DOVR�D�QRQJUHHG\�TXDQWLILHU�DYDLODEOH�,QVWHDG�RI�WKH�SOXV��+���ZH�FDQ�XVH�WKH�QRQJUHHG\�TXDQWLILHU�+?��ZKLFK�PDWFKHV�RQH�RUPRUH�WLPHV��MXVW�DV�WKH�SOXV�GRHV���H[FHSW�WKDW�LW�SUHIHUV�WR�PDWFK�DV�IHZ�WLPHV�DV�SRV�VLEOH��UDWKHU�WKDQ�DV�PDQ\�DV�SRVVLEOH��/HW¦V�VHH�KRZ�WKDW�QHZ�TXDQWLILHU�ZRUNV�ZKHQWKH�SDWWHUQ�LV�UHZULWWHQ�DV�/fred.+?barney/�

2QFH�DJDLQ��fred�PDWFKHV�ULJKW�DW�WKH�VWDUW��%XW�WKLV�WLPH�WKH�QH[W�SDUW�RI�WKH�SDWWHUQLV�.+?��ZKLFK�ZRXOG�SUHIHU�WR�PDWFK�QR�PRUH�WKDQ�RQH�FKDUDFWHU��VR�LW�PDWFKHV�MXVW�WKHVSDFH�DIWHU�fred��7KH�QH[W�VXESDWWHUQ�LV�barney��EXW�WKDW�FDQ¦W�PDWFK�KHUH��VLQFH�WKHVWULQJ�DW�WKH�FXUUHQW�SRVLWLRQ�EHJLQV�ZLWK�and barney������6R�WKH�.+?�UHOXFWDQWO\�PDWFKHV

7KH�UHJXODU�H[SUHVVLRQ�HQJLQH�PDNHV�D�IHZ�RSWLPL]DWLRQV�WKDW�PDNH�WKH�WUXH�VWRU\�GLIIHUHQW�WKDQ�ZH�WHOO�LWKHUH��DQG�WKRVH�RSWLPL]DWLRQV�FKDQJH�IURP�RQH�UHOHDVH�RI�3HUO�WR�WKH�QH[W��<RX�VKRXOGQ¦W�EH�DEOH�WR�WHOO�IURPWKH�IXQFWLRQDOLW\�WKDW�LW¦V�QRW�GRLQJ�DV�ZH�VD\��WKRXJK��,I�\RX�ZDQW�WR�NQRZ�KRZ�LW�UHDOO\�ZRUNV��\RX�VKRXOGUHDG�WKH�ODWHVW�VRXUFH�FRGH��%H�VXUH�WR�VXEPLW�SDWFKHV�IRU�DQ\�EXJV�\RX�ILQG�

� ,Q�IDFW��VRPH�UHJXODU�H[SUHVVLRQ�HQJLQHV�WU\�HYHU\�GLIIHUHQW�ZD\��HYHQ�FRQWLQXLQJ�RQ�DIWHU�WKH\�ILQG�RQH�WKDWILWV��%XW�3HUO¦V�UHJXODU�H[SUHVVLRQ�HQJLQH�LV�SULPDULO\�LQWHUHVWHG�LQ�ZKHWKHU�WKH�SDWWHUQ�FDQ�RU�FDQQRW�PDWFK�VR�ILQGLQJ�HYHQ�RQH�PDWFK�PHDQV�WKDW�WKH�HQJLQH¦V�ZRUN�LV�GRQH��$JDLQ��VHH�0DVWHULQJ�5HJXODU�([SUHVVLRQV�

More Powerful Regular Expressions | 141

WKH�a� DQG� OHWV� WKH� UHVW�RI� WKH�SDWWHUQ� WU\�DJDLQ��2QFH�DJDLQ��barney� FDQ¦W�PDWFK�� VRWKH� .+?� DFFHSWV� WKH� OHWWHU� n� DQG� VR� RQ��2QFH� WKH� .+?� KDV�PDWFKHG� ILYH� FKDUDFWHUV�barney�FDQ�PDWFK��DQG�WKH�SDWWHUQ�LV�D�VXFFHVV�

7KHUH�ZDV�VWLOO�VRPH�EDFNWUDFNLQJ��EXW�VLQFH�WKH�HQJLQH�KDG�WR�JR�EDFN�DQG�WU\�DJDLQMXVW�D�IHZ�WLPHV��LW�VKRXOG�EH�D�ELJ�LPSURYHPHQW�LQ�VSHHG��:HOO��LW¦V�DQ�LPSURYHPHQW�LI\RX¦OO�JHQHUDOO\�ILQG�barney�QHDU�fred��,I�\RXU�GDWD�RIWHQ�KDG�fred�QHDU�WKH�VWDUW�RI�WKHVWULQJ�DQG�barney�RQO\�DW�WKH�HQG��WKH�JUHHG\�TXDQWLILHU�PLJKW�EH�D�IDVWHU�FKRLFH��,Q�WKHHQG��WKH�VSHHG�RI�WKH�UHJXODU�H[SUHVVLRQ�GHSHQGV�XSRQ�WKH�GDWD�

%XW� WKH� QRQJUHHG\� TXDQWLILHUV� DUHQ¦W� MXVW� DERXW� HIILFLHQF\�� $OWKRXJK� WKH\¦OO� DOZD\VPDWFK��RU�IDLO�WR�PDWFK��WKH�VDPH�VWULQJV�DV�WKHLU�JUHHG\�FRXQWHUSDUWV��WKH\�PD\�PDWFKGLIIHUHQW�DPRXQWV�RI�WKH�VWULQJV��)RU�H[DPSOH��VXSSRVH�\RX�KDG�VRPH�+70/�OLNH �WH[W�DQG�\RX�ZDQW�WR�UHPRYH�DOO�RI�WKH�WDJV�<BOLD>�DQG�</BOLD>��OHDYLQJ�WKHLU�FRQWHQWV�LQWDFW�+HUH¦V�WKH�WH[W�

I’m talking about the cartoon with Fred and�<BOLD>Wilma</BOLD>!

$QG�KHUH¦V�D�VXEVWLWXWLRQ�WR�UHPRYH�WKRVH�WDJV��%XW�ZKDW¦V�ZURQJ�ZLWK�LW"

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

7KH�SUREOHP�LV�WKDW�WKH�VWDU�LV�JUHHG\���:KDW�LI�WKH�WH[W�KDG�VDLG�WKLV�LQVWHDG"

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

,Q�WKDW�FDVH��WKH�SDWWHUQ�ZRXOG�PDWFK�IURP�WKH�ILUVW�<BOLD>�WR�WKH�ODVW�</BOLD>��OHDYLQJLQWDFW�WKH�RQHV�LQ�WKH�PLGGOH�RI�WKH�OLQH��2RSV��,QVWHDG��ZH�ZDQW�D�QRQJUHHG\�TXDQWLILHU�7KH�QRQJUHHG\�IRUP�RI�VWDU�LV�*?��VR�WKH�VXEVWLWXWLRQ�QRZ�ORRNV�OLNH�WKLV�

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

$QG�LW�GRHV�WKH�ULJKW�WKLQJ�

6LQFH�WKH�QRQJUHHG\�IRUP�RI�WKH�SOXV�ZDV�+?�DQG�WKH�QRQJUHHG\�IRUP�RI�WKH�VWDU�ZDV*?��\RX¦YH�SUREDEO\�UHDOL]HG�WKDW�WKH�RWKHU�WZR�TXDQWLILHUV�ORRN�VLPLODU��7KH�QRQJUHHG\IRUP�RI�DQ\�FXUO\�EUDFH�TXDQWLILHU�ORRNV�WKH�VDPH��EXW�ZLWK�D�TXHVWLRQ�PDUN�DIWHU�WKHFORVLQJ�EUDFH�� OLNH�{5,10}?� RU�{8,}?�®�$QG�HYHQ� WKH�TXHVWLRQ�PDUN�TXDQWLILHU�KDV� DQRQJUHHG\�IRUP��??��7KDW�PDWFKHV�HLWKHU�RQFH�RU�QRW�DW�DOO��EXW�LW�SUHIHUV�QRW�WR�PDWFKDQ\WKLQJ�

2QFH� DJDLQ�� ZH� DUHQ¦W� XVLQJ� UHDO� +70/� EHFDXVH� \RX� FDQ¦W� FRUUHFWO\� SDUVH�+70/�ZLWK� VLPSOH� UHJXODUH[SUHVVLRQV��,I�\RX�UHDOO\�QHHG�WR�ZRUN�ZLWK�+70/�RU�D�VLPLODU�PDUNXS�ODQJXDJH��XVH�D�PRGXOH�WKDW¦V�PDGHWR�KDQGOH�WKH�FRPSOH[LWLHV�

� 7KHUH¦V�DQRWKHU�SRVVLEOH�SUREOHP��ZH�VKRXOG�KDYH�XVHG�WKH�/s�PRGLILHU�DV�ZHOO��VLQFH�WKH�HQG�WDJ�PD\�EH�RQD�GLIIHUHQW�OLQH�WKDQ�WKH�VWDUW�WDJ��,W¦V�D�JRRG�WKLQJ�WKDW�WKLV�LV�MXVW�DQ�H[DPSOH��LI�ZH�ZHUH�ZULWLQJ�VRPHWKLQJOLNH�WKLV�IRU�UHDO��ZH�ZRXOG�KDYH�WDNHQ�RXU�RZQ�DGYLFH�DQG�XVHG�D�ZHOO�ZULWWHQ�PRGXOH�

® ,Q�WKHRU\��WKHUH¦V�DOVR�D�QRQJUHHG\�TXDQWLILHU�IRUP�WKDW�VSHFLILHV�DQ�H[DFW�QXPEHU��OLNH�{3}?��%XW�VLQFH�WKDWVD\V�WR�PDWFK�H[DFWO\�WKUHH�RI�WKH�SUHFHGLQJ�LWHP��LW�KDV�QR�IOH[LELOLW\�WR�EH�HLWKHU�JUHHG\�RU�QRQJUHHG\�

142 | Chapter 9:ಗProcessing Text with Regular Expressions

Matching Multiple-Line Text&ODVVLF�UHJXODU�H[SUHVVLRQV�ZHUH�XVHG�WR�PDWFK�MXVW�VLQJOH�OLQHV�RI�WH[W��%XW�VLQFH�3HUOFDQ�ZRUN�ZLWK�VWULQJV�RI�DQ\�OHQJWK��3HUO¦V�SDWWHUQV�FDQ�PDWFK�PXOWLSOH�OLQHV�RI�WH[W�DVHDVLO\�DV�VLQJOH�OLQHV��2I�FRXUVH��\RX�KDYH�WR�LQFOXGH�DQ�H[SUHVVLRQ�WKDW�KROGV�PRUH�WKDQRQH�OLQH�RI�WH[W��+HUH¦V�D�VWULQJ�WKDW¦V�IRXU�OLQHV�ORQJ�

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

1RZ��WKH�DQFKRUV�̂ �DQG�$�DUH�QRUPDOO\�DQFKRUV�IRU�WKH�VWDUW�DQG�HQG�RI�WKH�ZKROH�VWULQJ�VHH�&KDSWHU�����%XW�WKH�/m�UHJXODU�H[SUHVVLRQ�RSWLRQ�OHWV�WKHP�PDWFK�DW�LQWHUQDO�QHZ�OLQHV�DV�ZHOO��WKLQN�m�IRU�PXOWLSOH�OLQHV���7KLV�PDNHV�WKHP�DQFKRUV�IRU�WKH�VWDUW�DQG�HQGRI�HDFK�OLQH��UDWKHU�WKDQ�WKH�ZKROH�VWULQJ��6R�WKLV�SDWWHUQ�FDQ�PDWFK�

print "Found 'wilma' at start of line\n" if /^wilma\b/im;

6LPLODUO\��\RX�FRXOG�GR�D�VXEVWLWXWLRQ�RQ�HDFK�OLQH�LQ�D�PXOWLOLQH�VWULQJ��+HUH��ZH�UHDGDQ�HQWLUH�ILOH�LQWR�RQH�YDULDEOH� �WKHQ�DGG�WKH�ILOH¦V�QDPH�DV�D�SUHIL[�DW�WKH�VWDUW�RI�HDFKOLQH�

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

Updating Many Files7KH�PRVW�FRPPRQ�ZD\�RI�SURJUDPPDWLFDOO\�XSGDWLQJ�D�WH[W�ILOH�LV�E\�ZULWLQJ�DQ�HQWLUHO\QHZ�ILOH�WKDW�ORRNV�VLPLODU�WR�WKH�ROG�RQH��EXW�PDNLQJ�ZKDWHYHU�FKDQJHV�ZH�QHHG�DV�ZHJR�DORQJ��$V�\RX¦OO�VHH��WKLV�WHFKQLTXH�JLYHV�QHDUO\�WKH�VDPH�UHVXOW�DV�XSGDWLQJ�WKH�ILOHLWVHOI��EXW�LW�KDV�VRPH�EHQHILFLDO�VLGH�HIIHFWV�DV�ZHOO�

,Q� WKLV� H[DPSOH��ZH¦YH�JRW�KXQGUHGV�RI� ILOHV�ZLWK�D� VLPLODU� IRUPDW��2QH�RI� WKHP� LVIUHG���GDW��DQG�LW¦V�IXOO�RI�OLQHV�OLNH�WKHVH�

Program name: graniteAuthor: Gilbert BatesCompany: RockSoftDepartment: R&DPhone: +1 503 555-0095Date: Tues March 9, 2004Version: 2.1Size: 21kStatus: Final beta

:H�QHHG�WR�IL[�WKLV�ILOH�VR�WKDW�LW�KDV�VRPH�GLIIHUHQW�LQIRUPDWLRQ��+HUH¦V�URXJKO\�ZKDWWKLV�RQH�VKRXOG�ORRN�OLNH�ZKHQ�ZH¦UH�GRQH�

Program name: graniteAuthor: Randal L. Schwartz

+RSH�LW¦V�D�VPDOO�RQH��7KH�ILOH��WKDW�LV��QRW�WKH�YDULDEOH�

More Powerful Regular Expressions | 143

Company: RockSoftDepartment: R&DDate: June 12, 2008 6:38 pmVersion: 2.1Size: 21kStatus: Final beta

,Q�VKRUW��ZH�QHHG�WR�PDNH�WKUHH�FKDQJHV��7KH�QDPH�RI�WKH�Author�VKRXOG�EH�FKDQJHG�WKH�Date�VKRXOG�EH�XSGDWHG�WR�WRGD\¦V�GDWH��DQG�WKH�Phone�VKRXOG�EH�UHPRYHG�FRP�SOHWHO\��$QG�ZH�KDYH�WR�PDNH�WKHVH�FKDQJHV�LQ�KXQGUHGV�RI�VLPLODU�ILOHV�DV�ZHOO�

3HUO�VXSSRUWV�D�ZD\�RI�LQ�SODFH�HGLWLQJ�RI�ILOHV�ZLWK�D�OLWWOH�H[WUD�KHOS�IURP�WKH�GLDPRQGRSHUDWRU��<>���+HUH¦V�D�SURJUDP�WR�GR�ZKDW�ZH�ZDQW��DOWKRXJK�LW�PD\�QRW�EH�REYLRXVKRZ�LW�ZRUNV�DW�ILUVW��7KLV�SURJUDP¦V�RQO\�QHZ�IHDWXUH�LV�WKH�VSHFLDO�YDULDEOH�$^I��LJQRUHWKDW�IRU�QRZ��DQG�ZH¦OO�FRPH�EDFN�WR�LW�

#!/usr/bin/perl -w

use strict;

chomp(my $date = `date`);$^I = ".bak";

while (<>) { s/^Author:.*/Author: Randal L. Schwartz/; s/^Phone:.*\n//; s/^Date:.*/Date: $date/; print;}

6LQFH�ZH�QHHG�WRGD\¦V�GDWH��WKH�SURJUDP�VWDUWV�E\�XVLQJ�WKH�V\VWHP�GDWH�FRPPDQG��$EHWWHU�ZD\�WR�JHW�WKH�GDWH��LQ�D�VOLJKWO\�GLIIHUHQW�IRUPDW��ZRXOG�DOPRVW�VXUHO\�EH�WR�XVH3HUO¦V�RZQ�localtime�IXQFWLRQ�LQ�D�VFDODU�FRQWH[W�

my $date = localtime;

7KH�QH[W�OLQH�VHWV�$^I��EXW�NHHS�LJQRULQJ�WKDW�IRU�WKH�PRPHQW�

7KH�OLVW�RI�ILOHV�IRU�WKH�GLDPRQG�RSHUDWRU�KHUH�DUH�FRPLQJ�IURP�WKH�FRPPDQG�OLQH��7KHPDLQ�ORRS�UHDGV��XSGDWHV��DQG�SULQWV�RQH�OLQH�DW�D�WLPH���:LWK�ZKDW�\RX�NQRZ�VR�IDU�WKDW� PHDQV� WKDW� DOO� RI� WKH� ILOHV¦� QHZO\�PRGLILHG� FRQWHQWV� ZLOO� EH� GXPSHG� WR� \RXUWHUPLQDO��VFUROOLQJ�IXULRXVO\�SDVW�\RXU�H\HV��ZLWKRXW�WKH�ILOHV�EHLQJ�FKDQJHG�DW�DOO��%XWVWLFN�ZLWK�XV���1RWH�WKDW�WKH�VHFRQG�VXEVWLWXWLRQ�FDQ�UHSODFH�WKH�HQWLUH�OLQH�FRQWDLQLQJWKH�SKRQH�QXPEHU�ZLWK�DQ�HPSW\�VWULQJ¢OHDYLQJ�QRW�HYHQ�D�QHZOLQH¢VR�ZKHQ�WKDW¦VSULQWHG��QRWKLQJ�FRPHV�RXW��DQG�LW¦V�DV�LI�WKH�Phone�QHYHU�H[LVWHG��0RVW�LQSXW�OLQHV�ZRQ¦WPDWFK�DQ\�RI�WKH�WKUHH�SDWWHUQV��DQG�WKRVH�ZLOO�EH�XQFKDQJHG�LQ�WKH�RXWSXW�

6R�WKLV�UHVXOW� LV�FORVH�WR�ZKDW�ZH�ZDQW��H[FHSW�WKDW�ZH�KDYHQ¦W�VKRZQ�\RX�KRZ�WKHXSGDWHG�LQIRUPDWLRQ�JHWV�EDFN�RXW�RQ�WR�WKH�GLVN��7KH�DQVZHU�LV�LQ�WKH�YDULDEOH�$^I��%\GHIDXOW�LW¦V�undef��DQG�HYHU\WKLQJ�LV�QRUPDO��%XW�ZKHQ�LW¦V�VHW�WR�VRPH�VWULQJ��LW�PDNHVWKH�GLDPRQG�RSHUDWRU��<>��HYHQ�PRUH�PDJLFDO�WKDQ�XVXDO�

144 | Chapter 9:ಗProcessing Text with Regular Expressions

:H�DOUHDG\�NQRZ�DERXW�PXFK�RI�WKH�GLDPRQG¦V�PDJLF¢LW�ZLOO�DXWRPDWLFDOO\�RSHQ�DQGFORVH�D�VHULHV�RI�ILOHV�IRU�\RX��RU�UHDG�IURP�WKH�VWDQGDUG�LQSXW�VWUHDP�LI�WKHUH�DUHQ¦W�DQ\ILOHQDPHV�JLYHQ��%XW�ZKHQ�WKHUH¦V�D�VWULQJ�LQ�$^I��WKDW�VWULQJ�LV�XVHG�DV�D�EDFNXS�ILOH�QDPH¦V�H[WHQVLRQ��/HW¦V�VHH�WKDW�LQ�DFWLRQ�

/HW¦V�VD\�LW¦V�WLPH�IRU�WKH�GLDPRQG�WR�RSHQ�RXU�ILOH�IUHG���GDW��,W�RSHQV�LW�OLNH�EHIRUH�EXW�QRZ�LW�UHQDPHV�LW��FDOOLQJ�LW�IUHG���GDW�EDN� �:H¦YH�VWLOO�JRW�WKH�VDPH�ILOH�RSHQ��EXWQRZ�LW�KDV�D�GLIIHUHQW�QDPH�RQ�WKH�GLVN��1H[W��WKH�GLDPRQG�FUHDWHV�D�QHZ�ILOH�DQG�JLYHVLW�WKH�QDPH�IUHG���GDW��7KDW¦V�RND\��ZH�ZHUHQ¦W�XVLQJ�WKDW�QDPH�DQ\�PRUH��$QG�QRZWKH�GLDPRQG�VHOHFWV�WKH�QHZ�ILOH�DV�WKH�GHIDXOW�IRU�RXWSXW��VR�WKDW�DQ\WKLQJ�WKDW�ZH�SULQWZLOO�JR�LQWR�WKDW�ILOH���6R�QRZ�WKH�while�ORRS�ZLOO�UHDG�D�OLQH�IURP�WKH�ROG�ILOH��XSGDWHWKDW��DQG�SULQW�LW�RXW�WR�WKH�QHZ�ILOH��7KLV�SURJUDP�FDQ�XSGDWH�WKRXVDQGV�RI�ILOHV�LQ�DIHZ�VHFRQGV�RQ�D�W\SLFDO�PDFKLQH��3UHWW\�SRZHUIXO��KXK"

2QFH�WKH�SURJUDP�KDV�ILQLVKHG��ZKDW�GRHV�WKH�XVHU�VHH"�7KH�XVHU�VD\V��£$K��,�VHH�ZKDWKDSSHQHG��3HUO�HGLWHG�P\�ILOH�IUHG���GDW��PDNLQJ�WKH�FKDQJHV�,�QHHGHG��DQG�VDYHG�PHD�FRS\�RI�WKH�RULJLQDO�LQ�WKH�EDFNXS�ILOH�IUHG���GDW�EDN�MXVW�WR�EH�KHOSIXO�¤�%XW�ZH�QRZNQRZ�WKH�WUXWK��3HUO�GLGQ¦W�UHDOO\�HGLW�DQ\�ILOH��,W�PDGH�D�PRGLILHG�FRS\��VDLG�£$EUDFD�GDEUD�¤�DQG�VZLWFKHG�WKH�ILOHV�DURXQG�ZKLOH�ZH�ZHUH�ZDWFKLQJ�VSDUNV�FRPH�RXW�RI�WKHPDJLF�ZDQG��7ULFN\�

6RPH�IRONV�XVH�D�WLOGH��~��DV�WKH�YDOXH�IRU�$^I�VLQFH�WKDW�UHVHPEOHV�ZKDW�HPDFV�GRHV�IRUEDFNXS�ILOHV��$QRWKHU�SRVVLEOH�YDOXH�IRU�$^I�LV�WKH�HPSW\�VWULQJ��7KLV�HQDEOHV�LQ�SODFHHGLWLQJ��EXW�GRHVQ¦W�VDYH�WKH�RULJLQDO�GDWD�LQ�D�EDFNXS�ILOH��%XW�VLQFH�D�VPDOO�W\SR�LQ\RXU�SDWWHUQ�FRXOG�ZLSH�RXW�DOO�RI�WKH�ROG�GDWD��XVLQJ�WKH�HPSW\�VWULQJ�LV�UHFRPPHQGHGRQO\�LI�\RX�ZDQW�WR�ILQG�RXW�KRZ�JRRG�\RXU�EDFNXS�WDSHV�DUH��,W¦V�HDV\�HQRXJK�WR�GHOHWHWKH�EDFNXS�ILOHV�ZKHQ�\RX¦UH�GRQH��$QG�ZKHQ�VRPHWKLQJ�JRHV�ZURQJ�DQG�\RX�QHHG�WRUHQDPH�WKH�EDFNXS�ILOHV�WR�WKHLU�RULJLQDO�QDPHV��\RX¦OO�EH�JODG�WKDW�\RX�NQRZ�KRZ�WRXVH�3HUO�WR�GR�WKDW��VHH�WKH�PXOWLSOH�ILOH�UHQDPH�H[DPSOH�LQ�&KDSWHU�����

In-Place Editing from the Command Line$�SURJUDP�OLNH�WKH�H[DPSOH�IURP�WKH�SUHYLRXV�VHFWLRQ�LV�IDLUO\�HDV\�WR�ZULWH��%XW�/DUU\GHFLGHG�LW�ZDVQ¦W�HDV\�HQRXJK�

,PDJLQH�WKDW�\RX�QHHG�WR�XSGDWH�KXQGUHGV�RI�ILOHV�WKDW�KDYH�WKH�PLVVSHOOLQJ�RandallLQVWHDG�RI�WKH�RQH�l�QDPH�Randal��<RX�FRXOG�ZULWH�D�SURJUDP�OLNH�WKH�RQH�LQ�WKH�SUHYLRXVVHFWLRQ��2U�\RX�FRXOG�GR�LW�DOO�ZLWK�D�RQH�OLQH�SURJUDP��ULJKW�RQ�WKH�FRPPDQG�OLQH�

$ perl -p -i.bak -w -e 's/Randall/Randal/g' fred*.dat

6RPH�RI�WKH�GHWDLOV�RI�WKLV�SURFHGXUH�ZLOO�YDU\�RQ�QRQ�8QL[�V\VWHPV��EXW�WKH�HQG�UHVXOW�VKRXOG�EH�QHDUO\�WKHVDPH��6HH�WKH�UHOHDVH�QRWHV�IRU�\RXU�SRUW�RI�3HUO�

� 7KH�GLDPRQG�DOVR�WULHV�WR�GXSOLFDWH�WKH�RULJLQDO�ILOH¦V�SHUPLVVLRQ�DQG�RZQHUVKLS�VHWWLQJV�DV�PXFK�DV�SRVVLEOH�IRU�H[DPSOH��LI�WKH�ROG�RQH�ZDV�ZRUOG�UHDGDEOH��WKH�QHZ�RQH�VKRXOG�EH�DV�ZHOO�

More Powerful Regular Expressions | 145

3HUO�KDV�D�ZKROH�VOHZ�RI�FRPPDQG�OLQH�RSWLRQV�WKDW�FDQ�EH�XVHG�WR�EXLOG�D�FRPSOHWHSURJUDP�LQ�D�IHZ�NH\VWURNHV� �/HW¦V�VHH�ZKDW�WKHVH�IHZ�GR�

6WDUWLQJ�WKH�FRPPDQG�ZLWK�perl�GRHV�VRPHWKLQJ�OLNH�SXWWLQJ�#!/usr/bin/perl�DW�WKHWRS�RI�D�ILOH�GRHV��LW�VD\V�WR�XVH�WKH�SURJUDP�SHUO�WR�SURFHVV�ZKDW�IROORZV�

7KH�-p�RSWLRQ�WHOOV�3HUO�WR�ZULWH�D�SURJUDP�IRU�\RX��,W¦V�QRW�PXFK�RI�D�SURJUDP��WKRXJK�LW�ORRNV�VRPHWKLQJ�OLNH�WKLV��

while (<>) { print;}

,I�\RX�ZDQW�HYHQ�OHVV��\RX�FRXOG�XVH�-n�LQVWHDG��WKDW�OHDYHV�RXW�WKH�DXWRPDWLF�printVWDWHPHQW��VR�\RX�FDQ�SULQW�RQO\�ZKDW�\RX�ZLVK���)DQV�RI�DZN�ZLOO�UHFRJQL]H�-p�DQG-n���$JDLQ�� LW¦V� QRW�PXFK�RI� D� SURJUDP�� EXW� LW¦V� SUHWW\� JRRG� IRU� WKH� SULFH� RI� D� IHZNH\VWURNHV�

7KH�QH[W�RSWLRQ�LV�-i.bak��ZKLFK�\RX�PLJKW�KDYH�JXHVVHG�VHWV�$^I�WR�".bak"�EHIRUH�WKHSURJUDP�VWDUWV��,I�\RX�GRQ¦W�ZDQW�D�EDFNXS�ILOH��\RX�FDQ�XVH�-i�DORQH��ZLWK�QR�H[WHQVLRQ�,I�\RX�GRQ¦W�ZDQW�D�VSDUH�SDUDFKXWH��\RX�FDQ�OHDYH�WKH�DLUSODQH�ZLWK�MXVW�RQH�

:H¦YH�VHHQ�-w�EHIRUH¢LW�WXUQV�RQ�ZDUQLQJV�

7KH�-e� RSWLRQ� VD\V� £H[HFXWDEOH� FRGH� IROORZV�¤�7KDW�PHDQV� WKH�s/Randall/Randal/gVWULQJ�LV�WUHDWHG�DV�3HUO�FRGH��6LQFH�ZH¦YH�DOUHDG\�JRW�D�while�ORRS��IURP�WKH�-p�RSWLRQ��WKLV�FRGH�LV�SXW�LQVLGH�WKH�ORRS��EHIRUH�WKH�print��)RU�WHFKQLFDO�UHDVRQV��WKH�ODVW�VHPL�FRORQ�LQ�WKH�-e�FRGH�LV�RSWLRQDO��%XW�LI�\RX�KDYH�PRUH�WKDQ�RQH�-e��DQG�WKXV�PRUH�WKDQRQH�FKXQN�RI�FRGH��RQO\�WKH�VHPLFRORQ�DW�WKH�HQG�RI�WKH�ODVW�RQH�PD\�VDIHO\�EH�RPLWWHG�

7KH�ODVW�FRPPDQG�OLQH�SDUDPHWHU�LV�fred*.dat��ZKLFK�VD\V�WKDW�@ARGV�VKRXOG�KROG�WKHOLVW�RI�ILOHQDPHV�WKDW�PDWFK�WKDW�ILOHQDPH�SDWWHUQ��3XW�WKH�SLHFHV�DOO�WRJHWKHU��DQG�LW¦VDV�LI�ZH�KDG�ZULWWHQ�D�SURJUDP�OLNH�WKLV��DQG�SXW�LW�WR�ZRUN�RQ�DOO�RI�WKRVH�fred*.dat�ILOHV�

#!/usr/bin/perl -w

$^I = ".bak";

while (<>) { s/Randall/Randal/g; print;}

&RPSDUH�WKLV�SURJUDP�WR�WKH�RQH�ZH�XVHG�LQ�WKH�SUHYLRXV�VHFWLRQ��,W¦V�SUHWW\�VLPLODU�7KHVH�FRPPDQG�OLQH�RSWLRQV�DUH�SUHWW\�KDQG\��DUHQ¦W�WKH\"

6HH�WKH�SHUOUXQ�PDQSDJH�IRU�WKH�FRPSOHWH�OLVW�

� $FWXDOO\��WKH�print�RFFXUV�LQ�D�continue�EORFN��6HH�WKH�SHUOV\Q�DQG�SHUOUXQ�PDQSDJHV�IRU�PRUH�LQIRUPDWLRQ�

146 | Chapter 9:ಗProcessing Text with Regular Expressions

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >�@�0DNH�D�SDWWHUQ�WKDW�ZLOO�PDWFK�WKUHH�FRQVHFXWLYH�FRSLHV�RI�ZKDWHYHU�LV�FXUUHQWO\FRQWDLQHG� LQ� $what�� 7KDW� LV�� LI� $what� LV� fred�� \RXU� SDWWHUQ� VKRXOG� PDWFK� fredfredfred�� ,I�$what� LV�fred|barney��\RXU�SDWWHUQ�VKRXOG�PDWFK�fredfredbarney�RUbarneyfredfred�RU�barneybarneybarney�RU�PDQ\�RWKHU�YDULDWLRQV���+LQW��\RX�VKRXOGVHW�$what�DW�WKH�WRS�RI�WKH�SDWWHUQ�WHVW�SURJUDP�ZLWK�D�VWDWHPHQW�OLNH�my $what ='fred|barney';��

�� >��@�:ULWH�D�SURJUDP�WKDW�PDNHV�D�PRGLILHG�FRS\�RI�D�WH[W�ILOH��,Q�WKH�FRS\��HYHU\VWULQJ� Fred� �FDVH�LQVHQVLWLYH�� VKRXOG� EH� UHSODFHG�ZLWK� Larry�� �6R�� Manfred MannVKRXOG�EHFRPH�ManLarry Mann���7KH�LQSXW�ILOHQDPH�VKRXOG�EH�JLYHQ�RQ�WKH�FRP�PDQG� OLQH� �GRQ¦W� DVN� WKH� XVHU���� DQG� WKH� RXWSXW� ILOHQDPH� VKRXOG� EH� WKH� FRUUH�VSRQGLQJ�ILOHQDPH�HQGLQJ�ZLWK�.out�

�� >�@�0RGLI\�WKH�SUHYLRXV�SURJUDP�WR�FKDQJH�HYHU\�Fred�WR�Wilma�DQG�HYHU\�Wilma�WRFred��1RZ�LQSXW�OLNH�fred&wilma�VKRXOG�ORRN�OLNH�Wilma&Fred�LQ�WKH�RXWSXW�

�� >��@�([WUD�FUHGLW�H[HUFLVH��ZULWH�D�SURJUDP�WR�DGG�D�FRS\ULJKW�OLQH�WR�DOO�RI�\RXUH[HUFLVH�DQVZHUV�VR�IDU��E\�SODFLQJ�D�OLQH�OLNH�

## Copyright (C) 20XX by Yours Truly

LQ�WKH�ILOH�LPPHGLDWHO\�DIWHU�WKH�£VKHEDQJ¤�OLQH��<RX�VKRXOG�HGLW�WKH�ILOHV�£LQ�SODFH�¤NHHSLQJ�D�EDFNXS��3UHVXPH�WKDW�WKH�SURJUDP�ZLOO�EH�LQYRNHG�ZLWK�WKH�ILOHQDPHV�WRHGLW�DOUHDG\�RQ�WKH�FRPPDQG�OLQH�

�� >��@�([WUD�H[WUD�FUHGLW�H[HUFLVH��PRGLI\�WKH�SUHYLRXV�SURJUDP�VR�WKDW�LW�GRHVQ¦W�HGLWWKH�ILOHV�WKDW�DOUHDG\�FRQWDLQ�WKH�FRS\ULJKW�OLQH���+LQW��\RX�PLJKW�QHHG�WR�NQRZWKDW�WKH�QDPH�RI�WKH�ILOH�EHLQJ�UHDG�E\�WKH�GLDPRQG�RSHUDWRU�LV�LQ�$ARGV��

Exercises | 147

CHAPTER 10

More Control Structures

,Q�WKLV�FKDSWHU��\RX¦OO�VHH�VRPH�DOWHUQDWLYH�ZD\V�WR�ZULWH�3HUO�FRGH��)RU�WKH�PRVW�SDUW�WKHVH�WHFKQLTXHV�GRQ¦W�PDNH�WKH�ODQJXDJH�PRUH�SRZHUIXO��EXW�WKH\�PDNH�LW�HDVLHU�RUPRUH�FRQYHQLHQW�WR�JHW�WKH�MRE�GRQH��<RX�GRQ¦W�KDYH�WR�XVH�WKHVH�WHFKQLTXHV�LQ�\RXURZQ�FRGH��EXW�GRQ¦W�EH�WHPSWHG�WR�VNLS�WKLV�FKDSWHU¢\RX¦UH�FHUWDLQ�WR�VHH�WKHVH�FRQWUROVWUXFWXUHV�LQ�RWKHU�SHRSOH¦V�FRGH��VRRQHU�RU�ODWHU��LQ�IDFW��\RX¦UH�DEVROXWHO\�FHUWDLQ�WRVHH�WKHVH�WKLQJV�LQ�XVH�E\�WKH�WLPH�\RX�ILQLVK�UHDGLQJ�WKLV�ERRN��

The unless Control Structure,Q�DQ�if�FRQWURO�VWUXFWXUH��WKH�EORFN�RI�FRGH�LV�H[HFXWHG�RQO\�ZKHQ�WKH�FRQGLWLRQDOH[SUHVVLRQ�LV�WUXH��,I�\RX�ZDQW�WR�H[HFXWH�D�EORFN�RI�FRGH�RQO\�ZKHQ�WKH�FRQGLWLRQDO�LVIDOVH��FKDQJH�if�WR�unless�

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

8VLQJ�unless�VD\V�WR�UXQ�WKH�EORFN�RI�FRGH�XQOHVV�WKLV�FRQGLWLRQ�LV�WUXH��,W¦V�MXVW�OLNHXVLQJ�DQ�if�WHVW�ZLWK�WKH�RSSRVLWH�FRQGLWLRQ��$QRWKHU�ZD\�WR�VD\�LW�LV�WKDW�LW¦V�OLNH�KDYLQJWKH�else�FODXVH�RQ�LWV�RZQ��7KDW�LV��ZKHQHYHU�\RX�VHH�DQ�unless�WKDW�\RX�GRQ¦W�XQGHU�VWDQG��\RX�FDQ�UHZULWH�LW��HLWKHU�LQ�\RXU�KHDG�RU�LQ�UHDOLW\��DV�DQ�if�WHVW�

if ($fred =~ /^[A-Z_]\w*$/i) { # Do nothing} else { print "The value of \$fred doesn't look like a Perl identifier name.\n";}

,W¦V�QR�PRUH�RU�OHVV�HIILFLHQW��DQG�LW�VKRXOG�FRPSLOH�WR�WKH�VDPH�LQWHUQDO�E\WH�FRGHV��2U�DQRWKHU�ZD\�WR�UHZULWH�LW�ZRXOG�EH�WR�QHJDWH�WKH�FRQGLWLRQDO�H[SUHVVLRQ�E\�XVLQJ�WKHQHJDWLRQ�RSHUDWRU��!��

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

149

*HQHUDOO\��\RX�VKRXOG�SLFN�WKH�ZD\�RI�ZULWLQJ�FRGH�WKDW�PDNHV�WKH�PRVW�VHQVH�WR�\RX�VLQFH�WKDW�ZLOO�SUREDEO\�PDNH�WKH�PRVW�VHQVH�WR�\RXU�PDLQWHQDQFH�SURJUDPPHU��,I�LWPDNHV�WKH�PRVW�VHQVH�WR�ZULWH�if�ZLWK�D�QHJDWLRQ��GR�WKDW��0RUH�RIWHQ��KRZHYHU��\RX¦OOSUREDEO\�ILQG�LW�QDWXUDO�WR�XVH�unless�

The else Clause with unless<RX�FRXOG�HYHQ�KDYH�DQ�else�FODXVH�ZLWK�DQ�unless��:KLOH�WKLV�V\QWD[�LV�VXSSRUWHG��LW¦VSRWHQWLDOO\�FRQIXVLQJ�

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

6RPH�SHRSOH�PD\�ZLVK�WR�XVH�WKLV��HVSHFLDOO\�ZKHQ�WKH�ILUVW�FODXVH�LV�YHU\�VKRUW��SHUKDSVRQO\�RQH�OLQH��DQG�WKH�VHFRQG�LV�VHYHUDO�OLQHV�RI�FRGH��%XW�ZH¦G�PDNH�WKLV�RQH�D�QHJDWHGif��RU�PD\EH�VLPSO\�VZDS�WKH�FODXVHV�WR�PDNH�D�QRUPDO�if�

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

,W¦V�LPSRUWDQW�WR�UHPHPEHU�WKDW�\RX¦UH�DOZD\V�ZULWLQJ�FRGH�IRU�WZR�UHDGHUV��WKH�FRP�SXWHU�WKDW�ZLOO�UXQ�WKH�FRGH�DQG�WKH�KXPDQ�EHLQJ�ZKR�KDV�WR�NHHS�WKH�FRGH�ZRUNLQJ�,I�WKH�KXPDQ�FDQ¦W�XQGHUVWDQG�ZKDW�\RX¦YH�ZULWWHQ��SUHWW\�VRRQ�WKH�FRPSXWHU�ZRQ¦WEH�GRLQJ�WKH�ULJKW�WKLQJ�HLWKHU�

The until Control Structure6RPHWLPHV�\RX¦OO�ZDQW�WR�UHYHUVH�WKH�FRQGLWLRQ�RI�D�while�ORRS��7R�GR�WKDW��MXVW�XVHuntil�

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

7KLV� ORRS� UXQV� XQWLO� WKH� FRQGLWLRQDO� H[SUHVVLRQ� UHWXUQV� WUXH�� %XW� LW¦V� UHDOO\� MXVW� Dwhile�ORRS�LQ�GLVJXLVH��H[FHSW�WKDW�WKLV�RQH�UHSHDWV�DV�ORQJ�DV�WKH�FRQGLWLRQDO�LV�IDOVH�UDWKHU�WKDQ�WUXH��7KH�FRQGLWLRQDO�H[SUHVVLRQ�LV�HYDOXDWHG�EHIRUH�WKH�ILUVW�LWHUDWLRQ��VRWKLV�LV�VWLOO�D�]HUR�RU�PRUH�WLPHV�ORRS��MXVW�OLNH�WKH�while�ORRS� �$V�ZLWK�if�DQG�unless�\RX�FRXOG�UHZULWH�DQ\�until�ORRS�WR�EHFRPH�D�while�ORRS�E\�QHJDWLQJ�WKH�FRQGLWLRQ�%XW�JHQHUDOO\��\RX¦OO�ILQG�LW�VLPSOH�DQG�QDWXUDO�WR�XVH�until�IURP�WLPH�WR�WLPH�

3DVFDO�SURJUDPPHUV��WDNH�QRWH��LQ�3DVFDO��WKH�UHSHDW�XQWLO�DOZD\V�UXQV�DW�OHDVW�RQH�LWHUDWLRQ��EXW�DQ�untilORRS�LQ�3HUO�PD\�QRW�UXQ�DW�DOO��LI�WKH�FRQGLWLRQDO�H[SUHVVLRQ�LV�WUXH�EHIRUH�WKH�ORRS�VWDUWV�

150 | Chapter 10:ಗMore Control Structures

Expression Modifiers,Q�RUGHU�WR�KDYH�D�PRUH�FRPSDFW�QRWDWLRQ��DQ�H[SUHVVLRQ�PD\�EH�IROORZHG�E\�D�PRGLILHUWKDW�FRQWUROV�LW��)RU�H[DPSOH��WKH�if�PRGLILHU�ZRUNV�LQ�D�ZD\�DQDORJRXV�WR�DQ�if�EORFN�

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

7KDW�JLYHV�H[DFWO\�WKH�VDPH�UHVXOW�DV�LI�ZH�KDG�XVHG�WKLV�FRGH��H[FHSW�WKDW�ZH�VDYHGVRPH�W\SLQJ�E\�OHDYLQJ�RXW�WKH�SDUHQWKHVHV�DQG�FXUO\�EUDFHV�

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

$V�ZH¦YH�VDLG��3HUO�IRONV�JHQHUDOO\�OLNH�WR�DYRLG�W\SLQJ��$QG�WKH�VKRUWHU�IRUP�UHDGV�LQ(QJOLVK��SULQW�WKLV�PHVVDJH�LI�$n�LV�OHVV�WKDQ�]HUR�

1RWLFH�WKDW�WKH�FRQGLWLRQDO�H[SUHVVLRQ�LV�VWLOO�HYDOXDWHG�ILUVW��HYHQ�WKRXJK�LW¦V�ZULWWHQDW�WKH�HQG��7KLV�LV�EDFNZDUG�IURP�WKH�XVXDO�OHIW�WR�ULJKW�RUGHULQJ��LQ�XQGHUVWDQGLQJ�3HUOFRGH��\RX¦OO�KDYH�WR�GR�DV�3HUO¦V� LQWHUQDO�FRPSLOHU�GRHV��DQG�UHDG�WR�WKH�HQG�RI� WKHVWDWHPHQW�EHIRUH�\RX�FDQ�WHOO�ZKDW�LW¦V�UHDOO\�GRLQJ�

7KHUH�DUH�RWKHU�PRGLILHUV�DV�ZHOO�

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

7KHVH�DOO�ZRUN�MXVW�DV��ZH�KRSH��\RX�ZRXOG�H[SHFW��7KDW�LV��HDFK�RQH�FRXOG�EH�UHZULWWHQLQ�D�VLPLODU�ZD\�WR�UHZULWLQJ�WKH�if�PRGLILHU�H[DPSOH�HDUOLHU��+HUH�LV�RQH�

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

7KH�H[SUHVVLRQ�LQ�SDUHQWKHVHV�LQVLGH�WKH�print�DUJXPHQW�OLVW�LV�QRWHZRUWK\�EHFDXVH�LWDGGV�WZR�WR�$n��VWRULQJ�WKH�UHVXOW�EDFN�LQWR�$n��7KHQ�LW�UHWXUQV�WKDW�QHZ�YDOXH��ZKLFKZLOO�EH�SULQWHG�

7KHVH�VKRUWHU�IRUPV�UHDG�DOPRVW�OLNH�D�QDWXUDO�ODQJXDJH��FDOO�WKH�&greet�VXEURXWLQH�IRUHDFK�@person�LQ�WKH�OLVW��'RXEOH�$i�XQWLO�LW¦V�ODUJHU�WKDQ�$j���2QH�RI�WKH�FRPPRQ�XVHVRI�WKHVH�PRGLILHUV�LV�LQ�D�VWDWHPHQW�OLNH�WKLV�RQH�

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

:H�DOVR�OHIW�RXW�WKH�OLQHEUHDNV��%XW�ZH�VKRXOG�PHQWLRQ�WKDW�WKH�FXUO\�EUDFH�IRUP�GRHV�FUHDWH�D�QHZ�VFRSH�,Q�WKH�UDUH�FDVH�WKDW�\RX�QHHG�WKH�IXOO�GHWDLOV��FKHFN�WKH�GRFXPHQWDWLRQ�

� :HOO��LW�KHOSV�XV�WR�WKLQN�RI�WKHP�OLNH�WKDW�

Expression Modifiers | 151

%\�ZULWLQJ�WKH�FRGH�£LQ�UHYHUVH¤�OLNH�WKLV��\RX�FDQ�SXW�WKH�LPSRUWDQW�SDUW�RI�WKH�VWDWH�PHQW�DW�WKH�EHJLQQLQJ��7KH�SRLQW�RI�WKDW�VWDWHPHQW�LV�WR�PRQLWRU�VRPH�YDULDEOHV��WKHSRLQW�LV�QRW�WR�FKHFN�ZKHWKHU�\RX¦UH�FXULRXV� �6RPH�SHRSOH�SUHIHU�WR�ZULWH�WKH�ZKROHVWDWHPHQW�RQ�RQH�OLQH��SHUKDSV�ZLWK�VRPH�WDE�FKDUDFWHUV�EHIRUH�WKH�if��WR�PRYH�LW�RYHUWRZDUG�WKH�ULJKW�PDUJLQ��DV�ZH�VKRZHG�LQ�WKH�SUHYLRXV�H[DPSOH��ZKLOH�RWKHUV�SXW�WKHif�PRGLILHU�LQGHQWHG�RQ�D�QHZ�OLQH�

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

$OWKRXJK�\RX�FDQ�UHZULWH�DQ\�RI�WKHVH�H[SUHVVLRQV�ZLWK�PRGLILHUV�DV�D�EORFN��WKH�£ROG�IDVKLRQHG¤�ZD\���WKH�FRQYHUVH�LVQ¦W�QHFHVVDULO\�WUXH��2QO\�D�VLQJOH�H[SUHVVLRQ�LV�DOORZHGRQ�HLWKHU�VLGH�RI�WKH�PRGLILHU��6R�\RX�FDQ¦W�ZULWH�VRPHWKLQJ�if�VRPHWKLQJ�while�VRPH�WKLQJ�until�VRPHWKLQJ�unless�VRPHWKLQJ�foreach�VRPHWKLQJ��ZKLFK�ZRXOG�MXVW�EH�WRRFRQIXVLQJ��$QG�\RX�FDQ¦W�SXW�PXOWLSOH�VWDWHPHQWV�RQ�WKH�OHIW�RI�WKH�PRGLILHU��,I�\RXQHHG�PRUH� WKDQ� MXVW�D� VLPSOH�H[SUHVVLRQ�RQ�HDFK� VLGH�� MXVW�ZULWH� WKH�FRGH� WKH�ROG�IDVKLRQHG�ZD\��ZLWK�WKH�SDUHQWKHVHV�DQG�FXUO\�EUDFHV�

$V�ZH�PHQWLRQHG�LQ�UHODWLRQ�WR�WKH�if�PRGLILHU��WKH�FRQWURO�H[SUHVVLRQ��RQ�WKH�ULJKW��LVDOZD\V�HYDOXDWHG�ILUVW��MXVW�DV�LW�ZRXOG�EH�LQ�WKH�ROG�IDVKLRQHG�IRUP�

:LWK�WKH�foreach�PRGLILHU��WKHUH¦V�QR�ZD\�WR�FKRRVH�D�GLIIHUHQW�FRQWURO�YDULDEOH¢LW¦VDOZD\V�$_��8VXDOO\��WKDW¦V�QR�SUREOHP��EXW�LI�\RX�ZDQW�WR�XVH�D�GLIIHUHQW�YDULDEOH��\RX¦OOQHHG�WR�UHZULWH�LW�DV�D�WUDGLWLRQDO�foreach�ORRS�

The Naked Block Control Structure7KH�VR�FDOOHG�QDNHG�EORFN�LV�RQH�ZLWKRXW�D�NH\ZRUG�RU�FRQGLWLRQ��7KDW�LV��VXSSRVH�\RXVWDUW�ZLWK�D�while�ORRS��ZKLFK�ORRNV�VRPHWKLQJ�OLNH�WKLV�

while (condition) { body; body; body;}

1RZ��WDNH�DZD\�WKH�while�NH\ZRUG�DQG�WKH�FRQGLWLRQDO�H[SUHVVLRQ��DQG�\RX¦OO�KDYH�DQDNHG�EORFN�

{ body; body; body;}

7KH�QDNHG�EORFN� LV� OLNH�D�while�RU�foreach� ORRS��H[FHSW� WKDW� LW�GRHVQ¦W� ORRS�� LW� MXVWH[HFXWHV�WKH�ERG\�RI�WKH�ORRS�RQFH��DQG�LW¦V�GRQH��,W¦V�DQ�XQ�ORRS�

2I�FRXUVH��ZH�PDGH�XS�WKH�QDPH�$I_am_curious��LW¦V�QRW�D�EXLOW�LQ�3HUO�YDULDEOH��*HQHUDOO\��IRONV�ZKR�XVH�WKLVWHFKQLTXH�ZLOO�HLWKHU�FDOO�WKHLU�YDULDEOH�$TRACING�RU�XVH�D�FRQVWDQW�GHFODUHG�ZLWK�WKH�constant�SUDJPD�

152 | Chapter 10:ಗMore Control Structures

<RX¦OO�VHH�LQ�D�ZKLOH�WKDW�WKHUH�DUH�RWKHU�XVHV�IRU�WKH�QDNHG�EORFN��EXW�RQH�RI�LWV�IHDWXUHVLV�WKDW�LW�SURYLGHV�D�VFRSH�IRU�WHPSRUDU\�OH[LFDO�YDULDEOHV�

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

,Q�WKLV�EORFN��$n�DQG�$root�DUH�WHPSRUDU\�YDULDEOHV�VFRSHG�WR�WKH�EORFN��$V�D�JHQHUDOJXLGHOLQH��DOO�YDULDEOHV�VKRXOG�EH�GHFODUHG�LQ�WKH�VPDOOHVW�VFRSH�DYDLODEOH��,I�\RX�QHHGD�YDULDEOH�IRU�MXVW�D�IHZ�OLQHV�RI�FRGH��\RX�FDQ�SXW�WKRVH�OLQHV�LQWR�D�QDNHG�EORFN�DQGGHFODUH�WKH�YDULDEOH�LQVLGH�WKDW�EORFN��2I�FRXUVH��LI�\RX�ZRXOG�QHHG�WKH�YDOXH�RI�HLWKHU$n�RU�$root�ODWHU��\RX�ZRXOG�QHHG�WR�GHFODUH�WKHP�LQ�D�ODUJHU�VFRSH�

<RX�PD\�KDYH�QRWLFHG�WKH�sqrt�IXQFWLRQ�LQ�WKDW�FRGH�DQG�ZRQGHUHG�DERXW�LW¢\HV��LW¦VD�IXQFWLRQ�ZH�KDYHQ¦W�VKRZQ�EHIRUH��3HUO�KDV�PDQ\�EXLOW�LQ�IXQFWLRQV�WKDW�DUH�EH\RQGWKH�VFRSH�RI�WKLV�ERRN��:KHQ�\RX¦UH�UHDG\��FKHFN�WKH�SHUOIXQF�PDQSDJH�WR�OHDUQ�DERXWPRUH�RI�WKHP�

The elsif Clause(YHU\�VR�RIWHQ��\RX�PD\�QHHG�WR�FKHFN�D�QXPEHU�RI�FRQGLWLRQDO�H[SUHVVLRQV��RQH�DIWHUDQRWKHU��WR�VHH�ZKLFK�RQH�RI�WKHP�LV�WUXH��7KLV�FDQ�EH�GRQH�ZLWK�WKH�if�FRQWURO�VWUXF�WXUH¦V�elsif�FODXVH��DV�LQ�WKLV�H[DPSOH�

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

3HUO�ZLOO�WHVW�WKH�FRQGLWLRQDO�H[SUHVVLRQV�RQH�DIWHU�DQRWKHU��:KHQ�RQH�VXFFHHGV��WKHFRUUHVSRQGLQJ� EORFN� RI� FRGH� LV� H[HFXWHG�� DQG� WKHQ� WKH� ZKROH� FRQWURO� VWUXFWXUH� LVGRQH� �DQG�H[HFXWLRQ�JRHV�RQ�WR�WKH�UHVW�RI�WKH�SURJUDP��,I�QRQH�KDV�VXFFHHGHG��WKHelse�EORFN�DW�WKH�HQG�LV�H[HFXWHG���2I�FRXUVH��WKH�else�FODXVH�LV�VWLOO�RSWLRQDO��EXW��LQWKLV�FDVH��LW¦V�RIWHQ�D�JRRG�LGHD�WR�LQFOXGH�LW��

7KHUH¦V�QR�OLPLW�WR�WKH�QXPEHU�RI�elsif�FODXVHV��EXW�UHPHPEHU�WKDW�3HUO�KDV�WR�HYDOXDWHWKH�ILUVW����WHVWV�EHIRUH�LW�FDQ�JHW�WR�WKH����WK��,I�\RX¦OO�KDYH�PRUH�WKDQ�KDOI�D�GR]HQelsifV��\RX�VKRXOG�FRQVLGHU�ZKHWKHU�WKHUH¦V�D�PRUH�HIILFLHQW�ZD\�WR�ZULWH�LW��7KH�3HUO

7KHUH¦V�QR�£IDOO�WKURXJK¤�WR�WKH�QH[W�EORFN��DV�LQ�WKH�£VZLWFK¤�VWUXFWXUH�RI�ODQJXDJHV�OLNH�&�

The elsif Clause | 153

)$4��VHH�WKH�SHUOIDT�PDQSDJH��KDV�D�QXPEHU�RI�VXJJHVWLRQV�IRU�HPXODWLQJ�WKH�£FDVH¤RU�£VZLWFK¤�VWDWHPHQWV�RI�RWKHU�ODQJXDJHV��DQG�XVHUV�RI�3HUO������RU�ODWHU�FDQ�XVH�given-when��GHVFULEHG�LQ�&KDSWHU�����DV�DQ�DOWHUQDWLYH�

<RX�PD\�KDYH�QRWLFHG�E\�WKLV�SRLQW�WKDW�WKH�NH\ZRUG�LV�VSHOOHG�elsif��ZLWK�RQO\�RQHe��,I�\RX�ZULWH�LW�DV�£HOVHLI¤��ZLWK�D�VHFRQG�e��3HUO�ZLOO�WHOO�\RX�WKDW�LW�LV�QRW�WKH�FRUUHFWVSHOOLQJ��:K\�QRW"�%HFDXVH�/DUU\�VD\V�VR�

Autoincrement and Autodecrement<RX¦OO�RIWHQ�ZDQW�D�VFDODU�YDULDEOH�WR�FRXQW�XS�RU�GRZQ�E\�RQH��6LQFH�WKHVH�DUH�IUHTXHQWFRQVWUXFWV��WKHUH�DUH�VKRUWFXWV�IRU�WKHP��OLNH�QHDUO\�HYHU\WKLQJ�HOVH�ZH�GR�IUHTXHQWO\�

7KH�DXWRLQFUHPHQW�RSHUDWRU��++��DGGV�RQH�WR�D�VFDODU�YDULDEOH��OLNH�WKH�VDPH�RSHUDWRULQ�&�DQG�VLPLODU�ODQJXDJHV�

my $bedrock = 42;$bedrock++; # add one to $bedrock; it's now 43

-XVW�OLNH�RWKHU�ZD\V�RI�DGGLQJ�RQH�WR�D�YDULDEOH��WKH�VFDODU�ZLOO�EH�FUHDWHG�LI�QHFHVVDU\�

my @people = qw{ fred barney fred wilma dino barney fred pebbles };my %count; # new empty hash$count{$_}++ foreach @people; # creates new keys and values as needed

7KH� ILUVW� WLPH� WKURXJK� WKDW� foreach� ORRS�� $count{$_}� LV� LQFUHPHQWHG�� 7KDW¦V$count{"fred"}��ZKLFK�WKXV�JRHV�IURP�undef��VLQFH�LW�GLGQ¦W�SUHYLRXVO\�H[LVW�LQ�WKH�KDVK�XS� WR� 1�� 7KH� QH[W� WLPH� WKURXJK� WKH� ORRS�� $count{"barney"}� EHFRPHV� 1�� DIWHU� WKDW�$count{"fred"}�EHFRPHV�2��(DFK�WLPH�WKURXJK�WKH�ORRS��RQH�HOHPHQW�LQ�%count�LV�LQ�FUHPHQWHG��DQG�SRVVLEO\�FUHDWHG�DV�ZHOO��$IWHU�WKDW�ORRS�LV�GRQH��$count{"fred"}�LV�3�7KLV�SURYLGHV�D�TXLFN�DQG�HDV\�ZD\�WR�VHH�ZKLFK�LWHPV�DUH�LQ�D�OLVW�DQG�KRZ�PDQ\�WLPHVHDFK�RQH�DSSHDUV�

6LPLODUO\��WKH�DXWRGHFUHPHQW�RSHUDWRU��--��VXEWUDFWV�RQH�IURP�D�VFDODU�YDULDEOH�

$bedrock--; # subtract one from $bedrock; it's 42 again

The Value of Autoincrement<RX�FDQ�IHWFK�WKH�YDOXH�RI�D�YDULDEOH�DQG�FKDQJH�WKDW�YDOXH�DW�WKH�VDPH�WLPH��3XW�WKH++�RSHUDWRU�LQ�IURQW�RI�WKH�YDULDEOH�QDPH�WR�LQFUHPHQW�WKH�YDULDEOH�ILUVW�DQG�WKHQ�IHWFKLWV�YDOXH��7KLV�LV�D�SUHLQFUHPHQW�

my $m = 5;my $n = ++$m; # increment $m to 6, and put that value into $n

,Q�IDFW��KH�UHVLVWV�DQ\�VXJJHVWLRQ�WKDW�LW�HYHQ�EH�SHUPLWWHG�DV�D�YDOLG�DOWHUQDWLYH�VSHOOLQJ��£,I�\RX�ZDQW�WR�VSHOOLW�ZLWK�D�VHFRQG�e��LW¦V�VLPSOH��6WHS��¢PDNH�XS�\RXU�RZQ�ODQJXDJH��6WHS��¢PDNH�LW�SRSXODU�¤�:KHQ�\RXPDNH�\RXU�RZQ�SURJUDPPLQJ�ODQJXDJH��\RX�FDQ�VSHOO�WKH�NH\ZRUGV�LQ�DQ\�ZD\�\RX¦G�OLNH��:H�KRSH�WKDW�\RXZLOO�GHFLGH�WKDW�\RXUV�VKRXOGQ¦W�EH�WKH�ILUVW�WR�KDYH�DQ�£HOVHXQOHVV�¤

154 | Chapter 10:ಗMore Control Structures

2U�SXW�WKH�--�RSHUDWRU�LQ�IURQW�WR�GHFUHPHQW�WKH�YDULDEOH�ILUVW�DQG�WKHQ�IHWFK�LWV�YDOXH�7KLV�LV�D�SUHGHFUHPHQW�

my $c = --$m; # decrement $m to 5, and put that value into $c

+HUH¦V�WKH�WULFN\�SDUW��3XW�WKH�YDULDEOH�QDPH�ILUVW�WR�IHWFK�WKH�YDOXH�ILUVW��DQG�WKHQ�GRWKH�LQFUHPHQW�RU�GHFUHPHQW��7KLV�LV�FDOOHG�D�SRVWLQFUHPHQW�RU�SRVWGHFUHPHQW�

my $d = $m++; # $d gets the old value (5), then increment $m to 6my $e = $m--; # $e gets the old value (6), then decrement $m to 5

,W¦V�WULFN\�EHFDXVH�ZH¦UH�GRLQJ�WZR�WKLQJV�DW�RQFH��:H¦UH�IHWFKLQJ�WKH�YDOXH��DQG�ZH¦UHFKDQJLQJ�LW�LQ�WKH�VDPH�H[SUHVVLRQ��,I�WKH�RSHUDWRU�LV�ILUVW��ZH�LQFUHPHQW��RU�GHFUHPHQW�ILUVW��WKHQ�XVH�WKH�QHZ�YDOXH��,I�WKH�YDULDEOH�LV�ILUVW��ZH�UHWXUQ�LWV��ROG��YDOXH�ILUVW��WKHQGR�WKH�LQFUHPHQW�RU�GHFUHPHQW��$QRWKHU�ZD\�WR�VD\�LW�LV�WKDW�WKHVH�RSHUDWRUV�UHWXUQ�DYDOXH��EXW�WKH\�DOVR�KDYH�WKH�VLGH�HIIHFW�RI�PRGLI\LQJ�WKH�YDULDEOH¦V�YDOXH�

,I�\RX�ZULWH�WKHVH�LQ�DQ�H[SUHVVLRQ�RI�WKHLU�RZQ� �QRW�XVLQJ�WKH�YDOXH�EXW�RQO\�WKH�VLGHHIIHFW��WKHUH¦V�QR�GLIIHUHQFH��LI�\RX�SXW�WKH�RSHUDWRU�EHIRUH�RU�DIWHU�WKH�YDULDEOH�

$bedrock++; # adds one to $bedrock++$bedrock; # just the same; adds one to $bedrock

$�FRPPRQ�XVH�RI�WKHVH�RSHUDWRUV�LV�LQ�FRQQHFWLRQ�ZLWK�D�KDVK��WR�LGHQWLI\�ZKHQ�DQ�LWHPKDV�EHHQ�VHHQ�EHIRUH�

my @people = qw{ fred barney bamm-bamm wilma dino barney betty pebbles };my %seen;

foreach (@people) { print "I've seen you somewhere before, $_!\n" if $seen{$_}++;}

:KHQ�barney�VKRZV�XS�IRU�WKH�ILUVW�WLPH��WKH�YDOXH�RI�$seen{$_}++�LV�IDOVH��VLQFH�LW¦V�WKHYDOXH�RI�$seen{$_}��ZKLFK�LV�$seen{"barney"}��ZKLFK�LV�undef��%XW�WKDW�H[SUHVVLRQ�KDVWKH� VLGH� HIIHFW� RI� LQFUHPHQWLQJ� $seen{"barney"}�� :KHQ� barney� VKRZV� XS� DJDLQ�$seen{"barney"}�LV�QRZ�D�WUXH�YDOXH��VR�WKH�PHVVDJH�LV�SULQWHG�

The for Control Structure3HUO¦V�for�FRQWURO�VWUXFWXUH�LV�OLNH�WKH�FRPPRQ�for�FRQWURO�VWUXFWXUH�\RX�PD\�KDYH�VHHQLQ�RWKHU�ODQJXDJHV��VXFK�DV�&��,W�ORRNV�OLNH�WKLV�

7KDW�LV��LQ�D�YRLG�FRQWH[W�

� 3URJUDPPHUV� ZKR� JHW� LQVLGH� WKH� LPSOHPHQWDWLRQV� RI� ODQJXDJHV� PD\� H[SHFW� WKDW� SRVWLQFUHPHQW� DQGSRVWGHFUHPHQW�ZRXOG�EH�OHVV�HIILFLHQW�WKDQ�WKHLU�FRXQWHUSDUWV��EXW�3HUO¦V�QRW�OLNH�WKDW��3HUO�DXWRPDWLFDOO\RSWLPL]HV�WKH�SRVW��IRUPV�ZKHQ�WKH\¦UH�XVHG�LQ�D�YRLG�FRQWH[W�

The for Control Structure | 155

for (initialization; test; increment) { body; body;}

7R�3HUO��WKRXJK��WKLV�NLQG�RI�ORRS�LV�UHDOO\�D�while�ORRS�LQ�GLVJXLVH��VRPHWKLQJ�OLNH�WKLV�

initialization;while (test) { body; body; increment;}

7KH�PRVW�FRPPRQ�XVH�RI�WKH�for�ORRS��E\�IDU��LV�IRU�PDNLQJ�FRPSXWHG�LWHUDWLRQV�

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

:KHQ�\RX¦YH�VHHQ�WKHVH�EHIRUH��\RX¦OO�NQRZ�ZKDW�WKH�ILUVW�OLQH�LV�VD\LQJ�HYHQ�EHIRUH\RX�UHDG�WKH�FRPPHQW��%HIRUH�WKH�ORRS�VWDUWV��WKH�FRQWURO�YDULDEOH��$i��LV�VHW�WR�1��7KHQ�WKH�ORRS�LV�UHDOO\�D�while�ORRS�LQ�GLVJXLVH��ORRSLQJ�ZKLOH�$i�LV�OHVV�WKDQ�RU�HTXDO�WR�10�%HWZHHQ�HDFK�LWHUDWLRQ�DQG�WKH�QH[W�LV�WKH�LQFUHPHQW��ZKLFK�KHUH�LV�D�OLWHUDO�LQFUHPHQW�DGGLQJ�RQH�WR�WKH�FRQWURO�YDULDEOH��ZKLFK�LV�$i�

6R��WKH�ILUVW�WLPH�WKURXJK�WKLV�ORRS��$i�LV�1��%HFDXVH�WKDW¦V�OHVV�WKDQ�RU�HTXDO�WR�10��ZHVHH�WKH�PHVVDJH��$OWKRXJK�WKH�LQFUHPHQW�LV�ZULWWHQ�DW�WKH�WRS�RI�WKH�ORRS��LW�ORJLFDOO\KDSSHQV�DW�WKH�ERWWRP�RI�WKH�ORRS��DIWHU�SULQWLQJ�WKH�PHVVDJH��6R��$i�EHFRPHV�2��ZKLFKLV�OHVV�WKDQ�RU�HTXDO�WR�10��VR�ZH�SULQW�WKH�PHVVDJH�DJDLQ��DQG�$i�LV�LQFUHPHQWHG�WR�3�ZKLFK�LV�OHVV�WKDQ�RU�HTXDO�WR�10��DQG�VR�RQ�

(YHQWXDOO\��ZH�SULQW�WKH�PHVVDJH�WKDW�RXU�SURJUDP�FDQ�FRXQW�WR�9��7KHQ�$i�LV�LQFUH�PHQWHG�WR�10��ZKLFK�LV�OHVV�WKDQ�RU�HTXDO�WR�10��VR�ZH�UXQ�WKH�ORRS�RQH�ODVW�WLPH�DQGSULQW�WKDW�RXU�SURJUDP�FDQ�FRXQW�WR�10��)LQDOO\��$i�LV�LQFUHPHQWHG�IRU�WKH�ODVW�WLPH��WR11��ZKLFK�LV�QRW�OHVV�WKDQ�RU�HTXDO�WR�10��6R�FRQWURO�GURSV�RXW�RI�WKH�ORRS��DQG�ZH¦UH�RQWR�WKH�UHVW�RI�WKH�SURJUDP�

$OO�WKUHH�SDUWV�DUH�WRJHWKHU�DW�WKH�WRS�RI�WKH�ORRS�VR�WKDW�LW¦V�HDV\�IRU�DQ�H[SHULHQFHGSURJUDPPHU�WR�UHDG�WKDW�ILUVW�OLQH�DQG�VD\��£$K��LW¦V�D�ORRS�WKDW�FRXQWV�$i�IURP�RQH�WRWHQ�¤

1RWH�WKDW�DIWHU�WKH�ORRS�LV�GRQH��WKH�FRQWURO�YDULDEOH�KDV�D�YDOXH�£DIWHU¤�WKH�ORRS��7KDWLV�� LQ�WKLV�FDVH��WKH�FRQWURO�YDULDEOH�KDV�JRQH�DOO� WKH�ZD\�WR�11���7KLV� ORRS�LV�D�YHU\YHUVDWLOH�ORRS��\RX�FDQ�PDNH�LW�FRXQW�LQ�DOO�VRUWV�RI�ZD\V��)RU�H[DPSOH��ZH�FDQ�FRXQWGRZQ�IURP����WR���

$FWXDOO\�� WKH� LQFUHPHQW� KDSSHQV� LQ� D� continue� EORFN��ZKLFK� LV� EH\RQG� WKH� VFRSH� RI� WKLV� ERRN�� 6HH� WKHSHUOV\Q�PDQSDJH�IRU�WKH�WUXWK�

� 2EOLJDWRU\�7KLV�LV�6SLQDO�7DS�RXWGDWHG�SRS�FXOWXUH�UHIHUHQFH�

156 | Chapter 10:ಗMore Control Structures

for ($i = 10; $i >= 1; $i--) { print "I can count down to $i\n";}

$QG�WKLV�ORRS�FRXQWV�IURP�!150�WR�1000�E\�WKUHHV�

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

,Q�IDFW��\RX�FRXOG�PDNH�DQ\�RI�WKH�WKUHH�FRQWURO�SDUWV��LQLWLDOL]DWLRQ��WHVW��RU�LQFUHPHQW�HPSW\��LI�\RX�ZLVK��EXW�\RX�VWLOO�QHHG�WKH�WZR�VHPLFRORQV��,Q�WKLV��TXLWH�XQXVXDO��H[�DPSOH��WKH�WHVW�LV�D�VXEVWLWXWLRQ��DQG�WKH�LQFUHPHQW�LV�HPSW\�

for ($_ = "bedrock"; s/(.)//; ) { # loops while the s/// is successful print "One character is: $1\n";}

7KH�WHVW�H[SUHVVLRQ��LQ�WKH�LPSOLHG�while�ORRS��LV�WKH�VXEVWLWXWLRQ��ZKLFK�ZLOO�UHWXUQ�DWUXH�YDOXH�LI�LW�VXFFHHGHG��,Q�WKLV�FDVH��WKH�ILUVW�WLPH�WKURXJK�WKH�ORRS��WKH�VXEVWLWXWLRQZLOO�UHPRYH�WKH�b�IURP�bedrock��(DFK�LWHUDWLRQ�ZLOO�UHPRYH�DQRWKHU�OHWWHU��:KHQ�WKHVWULQJ�LV�HPSW\��WKH�VXEVWLWXWLRQ�ZLOO�IDLO��DQG�WKH�ORRS�LV�GRQH�

,I�WKH�WHVW�H[SUHVVLRQ��WKH�RQH�EHWZHHQ�WKH�WZR�VHPLFRORQV��LV�HPSW\��LW¦V�DXWRPDWLFDOO\WUXH��PDNLQJ�DQ�LQILQLWH�ORRS��%XW�GRQ¦W�PDNH�DQ�LQILQLWH�ORRS�OLNH�WKLV�XQWLO�\RX�VHHKRZ�WR�EUHDN�RXW�RI�VXFK�D�ORRS��ZKLFK�ZH¦OO�GLVFXVV�ODWHU�LQ�WKLV�FKDSWHU�

for (;;) { print "It's an infinite loop!\n";}

$�PRUH� 3HUO�OLNH� ZD\� WR� ZULWH� DQ� LQWHQWLRQDO� LQILQLWH� ORRS�� ZKHQ� \RX� UHDOO\� ZDQWRQH���LV�ZLWK�while�

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

$OWKRXJK�&�SURJUDPPHUV�DUH�IDPLOLDU�ZLWK�WKH�ILUVW�ZD\��HYHQ�D�EHJLQQLQJ�3HUO�SUR�JUDPPHU�VKRXOG�UHFRJQL]H�WKDW�1�LV�DOZD\V�WUXH��PDNLQJ�DQ�LQWHQWLRQDO�LQILQLWH�ORRS��VRWKH�VHFRQG�LV�JHQHUDOO\�D�EHWWHU�ZD\�WR�ZULWH� LW��3HUO� LV�VPDUW�HQRXJK�WR�UHFRJQL]H�DFRQVWDQW�H[SUHVVLRQ�OLNH�WKDW�DQG�RSWLPL]H�LW�DZD\��VR�WKHUH¦V�QR�GLIIHUHQFH�LQ�HIILFLHQF\�

The Secret Connection Between foreach and for,W�WXUQV�RXW�WKDW��LQVLGH�WKH�3HUO�SDUVHU��WKH�NH\ZRUG�foreach�LV�H[DFWO\�HTXLYDOHQW�WRWKH�NH\ZRUG�for��7KDW�LV��DQ\�WLPH�3HUO�VHHV�RQH�RI�WKHP��LW¦V�WKH�VDPH�DV�LI�\RX�KDG

2I�FRXUVH��LW�QHYHU�JHWV�WR�1000�H[DFWO\��7KH�ODVW�LWHUDWLRQ�XVHV�999��VLQFH�HDFK�YDOXH�RI�$i�LV�D�PXOWLSOH�RI�WKUHH�

� ,I�\RX�VRPHKRZ�PDGH�DQ�LQILQLWH�ORRS�WKDW¦V�JRWWHQ�DZD\�IURP�\RX��VHH�ZKHWKHU�&RQWURO�&�ZLOO�KDOW�LW��,W¦VSRVVLEOH�WKDW�\RX¦OO�JHW�D�ORW�RI�RXWSXW�HYHQ�DIWHU�W\SLQJ�&RQWURO�&��GHSHQGLQJ�XSRQ�\RXU�V\VWHP¦V�,�2�DQGRWKHU�IDFWRUV��+H\��ZH�ZDUQHG�\RX�

The for Control Structure | 157

W\SHG�WKH�RWKHU��3HUO�FDQ�WHOO�ZKLFK�\RX�PHDQW�E\�ORRNLQJ�LQVLGH�WKH�SDUHQWKHVHV��,I\RX¦YH�JRW�WKH�WZR�VHPLFRORQV��LW¦V�D�FRPSXWHG�for�ORRS��OLNH�ZH¦YH�MXVW�EHHQ�WDONLQJDERXW���,I�\RX�GRQ¦W�KDYH�WKH�VHPLFRORQV��LW¦V�UHDOO\�D�foreach�ORRS�

for (1..10) { # Really a foreach loop from 1 to 10 print "I can count to $_!\n";}

7KDW¦V� UHDOO\� D� foreach� ORRS�� EXW� LW¦V�ZULWWHQ� for�� ([FHSW� IRU� WKDW� RQH� H[DPSOH�� DOOWKURXJK�WKLV�ERRN��ZH¦OO�VSHOO�RXW�foreach�ZKHUHYHU�LW�DSSHDUV��%XW�LQ�WKH�UHDO�ZRUOG�GR�\RX�WKLQN�WKDW�3HUO�IRONV�ZLOO�W\SH�WKRVH�H[WUD�IRXU�OHWWHUV" �([FHSWLQJ�RQO\�EHJLQQHUV¦FRGH��LW¦V�DOZD\V�ZULWWHQ�for��DQG�\RX¦OO�KDYH�WR�GR�DV�3HUO�GRHV�DQG�ORRN�IRU�WKH�VHPL�FRORQV�WR�WHOO�ZKLFK�NLQG�RI�ORRS�LW�LV�

,Q�3HUO�� WKH� WUXH�foreach� ORRS� LV�DOPRVW�DOZD\V�D�EHWWHU�FKRLFH�� ,Q� WKH�foreach� ORRS�ZULWWHQ�for��LQ�WKDW�SUHYLRXV�H[DPSOH��LW¦V�HDV\�WR�VHH�DW�D�JODQFH�WKDW�WKH�ORRS�ZLOO�JRIURP�1�WR�10��%XW�GR�\RX�VHH�ZKDW¦V�ZURQJ�ZLWK�WKLV�FRPSXWHG�ORRS�WKDW¦V�WU\LQJ�WR�GRWKH�VDPH�WKLQJ"�'RQ¦W�SHHN�DW�WKH�DQVZHU�LQ�WKH�IRRWQRWH�XQWLO�\RX�WKLQN�\RX¦YH�IRXQGZKDW¦V�ZURQJ��

for ($i = 1; $i < 10; $i++) { # Oops! Something is wrong here! print "I can count to $_!\n";}

Loop Controls$V�\RX¦YH�VXUHO\�QRWLFHG�E\�QRZ��3HUO�LV�RQH�RI�WKH�VR�FDOOHG�VWUXFWXUHG�SURJUDPPLQJODQJXDJHV��,Q�SDUWLFXODU��WKHUH¦V�MXVW�RQH�HQWUDQFH�WR�DQ\�EORFN�RI�FRGH��DW�WKH�WRS�RIWKDW�EORFN��%XW�WKHUH�DUH�WLPHV�ZKHQ�\RX�PD\�QHHG�PRUH�FRQWURO�RU�YHUVDWLOLW\�WKDQZKDW�ZH¦YH�VKRZQ�VR�IDU��)RU�H[DPSOH��\RX�PD\�QHHG�WR�PDNH�D�ORRS�OLNH�D�while�ORRS�EXW�RQH�WKDW�DOZD\V�UXQV�DW�OHDVW�RQFH��2U�PD\EH�\RX�QHHG�WR�RFFDVLRQDOO\�H[LW�D�EORFNRI�FRGH�HDUO\��3HUO�KDV�WKUHH�ORRS�FRQWURO�RSHUDWRUV�\RX�FDQ�XVH�LQ�ORRS�EORFNV�WR�PDNHWKH�ORRS�GR�DOO�VRUWV�RI�WULFNV�

,I�\RX�WKLQN�WKDW��\RX�KDYHQ¦W�EHHQ�SD\LQJ�DWWHQWLRQ��$PRQJ�SURJUDPPHUV��HVSHFLDOO\�3HUO�SURJUDPPHUV�OD]LQHVV�LV�RQH�RI�WKH�FODVVLF�YLUWXHV��,I�\RX�GRQ¦W�EHOLHYH�XV��DVN�VRPHRQH�DW�WKH�QH[W�3HUO�0RQJHUV¦�PHHWLQJ�

� 7KHUH�DUH�WZR�DQG�RQH�KDOI�EXJV��)LUVW��WKH�FRQGLWLRQDO�XVHV�D�OHVV�WKDQ�VLJQ��VR�WKH�ORRS�ZLOO�UXQ���WLPHV�LQVWHDG�RI�����,W¦V�HDV\�WR�JHW�D�VR�FDOOHG�IHQFHSRVW�EXJ�ZLWK�WKLV�NLQG�RI�ORRS��OLNH�ZKDW�KDSSHQHG�ZKHQ�WKHUDQFKHU�QHHGHG�HQRXJK�IHQFHSRVWV�WR�PDNH�D����PHWHU�ORQJ�IHQFH�ZLWK�D�SRVW�HYHU\���PHWHUV���7KH�DQVZHULV�QRW����IHQFHSRVWV���6HFRQG��WKH�FRQWURO�YDULDEOH�LV�$i��EXW�WKH�ORRS�ERG\�LV�XVLQJ�$_��$QG�VHFRQG�DQG�D�KDOI�LW¦V�D�ORW�PRUH�ZRUN�WR�UHDG��ZULWH��PDLQWDLQ��DQG�GHEXJ�WKLV�W\SH�RI�ORRS��ZKLFK�LV�ZK\�ZH�VD\�WKDW�WKH�WUXHforeach�LV�JHQHUDOO\�D�EHWWHU�FKRLFH�LQ�3HUO�

158 | Chapter 10:ಗMore Control Structures

The last Operator7KH�last�RSHUDWRU�LPPHGLDWHO\�HQGV�H[HFXWLRQ�RI�WKH�ORRS���,I�\RX¦YH�XVHG�WKH�£EUHDN¤RSHUDWRU�LQ�&�RU�D�VLPLODU�ODQJXDJH��LW¦V�OLNH�WKDW���,W¦V�WKH�£HPHUJHQF\�H[LW¤�IRU�ORRSEORFNV��:KHQ�\RX�KLW�last��WKH�ORRS�LV�GRQH��)RU�H[DPSOH�

# Print all input lines mentioning fred, until the __END__ markerwhile (<STDIN>) { if (/__END__/) { # No more input on or after this marker line last; } elsif (/fred/) { print; }}## last comes here #

2QFH�DQ�LQSXW�OLQH�KDV�WKH�__END__�PDUNHU��WKDW�ORRS�LV�GRQH��2I�FRXUVH��WKDW�FRPPHQWOLQH�DW�WKH�HQG�LV�PHUHO\�D�FRPPHQW¢LW¦V�QRW�UHTXLUHG�LQ�DQ\�ZD\��:H�MXVW�WKUHZ�WKDWLQ�WR�PDNH�LW�FOHDUHU�ZKDW¦V�KDSSHQLQJ�

7KHUH�DUH�ILYH�NLQGV�RI�ORRS�EORFNV�LQ�3HUO��7KHVH�DUH�WKH�EORFNV�RI�for��foreach��while�until��RU�WKH�QDNHG�EORFN� �7KH�FXUO\�EUDFHV�RI�DQ�if�EORFN�RU�VXEURXWLQH��GRQ¦W�TXDOLI\�$V�\RX�PD\�KDYH�QRWLFHG�LQ�WKH�H[DPSOH�DERYH��WKH�last�RSHUDWRU�DSSOLHG�WR�WKH�HQWLUHORRS�EORFN�

7KH�last�RSHUDWRU�ZLOO�DSSO\�WR�WKH�LQQHUPRVW�FXUUHQWO\�UXQQLQJ�ORRS�EORFN��7R�MXPSRXW�RI�RXWHU�EORFNV��VWD\�WXQHG��WKDW¦V�FRPLQJ�XS�LQ�D�OLWWOH�ELW�

The next Operator6RPHWLPHV�\RX¦UH�QRW�UHDG\�IRU�WKH�ORRS�WR�ILQLVK��EXW�\RX¦UH�GRQH�ZLWK�WKH�FXUUHQWLWHUDWLRQ��7KDW¦V�ZKDW�WKH�next�RSHUDWRU�LV�JRRG�IRU��,W�MXPSV�WR�WKH�LQVLGH�RI�WKH�ERWWRPRI�WKH�FXUUHQW�ORRS�EORFN�®�$IWHU�next��FRQWURO�FRQWLQXHV�ZLWK�WKH�QH[W�LWHUDWLRQ�RI�WKHORRS��PXFK�OLNH�WKH�£FRQWLQXH¤�RSHUDWRU�LQ�&�RU�D�VLPLODU�ODQJXDJH��

# Analyze words in the input file or fileswhile (<>) { foreach (split) { # break $_ into words, assign each to $_ in turn $total++;

<HV��\RX�FDQ�XVH�last�WR�MXPS�RXW�RI�D�QDNHG�EORFN��7KDW¦V�QRW�H[DFWO\�WKH�VDPH�DV�MXPSLQJ�QDNHG�RXW�LQWR\RXU�EORFN�

� ,W¦V�SUREDEO\�QRW�D�JRRG�LGHD��EXW�\RX�FRXOG�XVH�WKHVH�ORRS�FRQWURO�RSHUDWRUV�IURP�LQVLGH�D�VXEURXWLQH�WRFRQWURO�D�ORRS�WKDW�LV�RXWVLGH�WKH�VXEURXWLQH��7KDW�LV��LI�D�VXEURXWLQH�LV�FDOOHG�LQ�D�ORRS�EORFN��DQG�WKH�VXEURXWLQHH[HFXWHV�last�ZKHQ�WKHUH¦V�QR�ORRS�EORFN�UXQQLQJ�LQVLGH�WKH�VXEURXWLQH��WKH�IORZ�RI�FRQWURO�ZLOO�MXPS�WR�MXVWDIWHU�WKH�ORRS�EORFN�LQ�WKH�PDLQ�FRGH��7KLV�DELOLW\�WR�XVH�ORRS�FRQWURO�IURP�ZLWKLQ�D�VXEURXWLQH�PD\�JR�DZD\LQ�D�IXWXUH�YHUVLRQ�RI�3HUO��DQG�QR�RQH�LV�OLNHO\�WR�PLVV�LW�

® 7KLV�LV�DQRWKHU�RI�RXU�PDQ\�OLHV��,Q�WUXWK��next�MXPSV�WR�WKH�VWDUW�RI�WKH��XVXDOO\�RPLWWHG��continue�EORFN�IRUWKH�ORRS��6HH�WKH�SHUOV\Q�PDQSDJH�IRU�WKH�IXOO�GHWDLOV�

Loop Controls | 159

next if /\W/; # strange words skip the remainder of the loop $valid++; $count{$_}++; # count each separate word ## next comes here ## }}

print "total things = $total, valid words = $valid\n";foreach $word (sort keys %count) { print "$word was seen $count{$word} times.\n";}

7KLV�RQH�LV�D�OLWWOH�PRUH�FRPSOH[�WKDQ�PRVW�RI�RXU�H[DPSOHV�XS�WR�WKLV�SRLQW��VR�OHW¦VWDNH�LW�VWHS�E\�VWHS��7KH�while�ORRS�LV�UHDGLQJ�OLQHV�RI�LQSXW�IURP�WKH�GLDPRQG�RSHUDWRU�RQH�DIWHU�DQRWKHU��LQWR�$_��\RX¦YH�VHHQ�WKDW�EHIRUH��(DFK�WLPH�WKURXJK�WKDW�ORRS��DQRWKHUOLQH�RI�LQSXW�ZLOO�EH�LQ�$_�

,QVLGH�WKDW�ORRS��WKH�foreach�ORRS�LV�LWHUDWLQJ�RYHU�WKH�UHWXUQ�YDOXH�split��'R�\RX�UH�PHPEHU�WKH�GHIDXOW�IRU�split�ZLWK�QR�DUJXPHQWV" �7KDW�VSOLWV�$_�RQ�ZKLWHVSDFH��LQ�HIIHFWEUHDNLQJ�$_�LQWR�D�OLVW�RI�ZRUGV��6LQFH�WKH�foreach�ORRS�GRHVQ¦W�PHQWLRQ�VRPH�RWKHUFRQWURO�YDULDEOH��WKH�FRQWURO�YDULDEOH�ZLOO�EH�$_��6R��ZH¦OO�VHH�RQH�ZRUG�DIWHU�DQRWKHU�LQ$_�

%XW�GLGQ¦W�ZH�MXVW�VD\�WKDW�$_�KROGV�RQH�OLQH�RI�LQSXW�DIWHU�DQRWKHU"�:HOO��LQ�WKH�RXWHUORRS��WKDW¦V�ZKDW�LW�LV��%XW�LQVLGH�WKH�foreach�ORRS��LW�KROGV�RQH�ZRUG�DIWHU�DQRWKHU��,W¦VQR�SUREOHP�IRU�3HUO�WR�UHXVH�$_�IRU�D�QHZ�SXUSRVH��WKLV�KDSSHQV�DOO�WKH�WLPH�

1RZ��LQVLGH�WKH�foreach�ORRS��ZH¦UH�VHHLQJ�RQH�ZRUG�DW�D�WLPH�LQ�$_��$total�LV�LQFUH�PHQWHG��VR�LW�PXVW�EH�WKH�WRWDO�QXPEHU�RI�ZRUGV��%XW�WKH�QH[W�OLQH��ZKLFK�LV�WKH�SRLQWRI�WKLV�H[DPSOH��FKHFNV�WR�VHH�ZKHWKHU�WKH�ZRUG�KDV�DQ\�QRQZRUG�FKDUDFWHUV¢DQ\WKLQJEXW�OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV��6R��LI�WKH�ZRUG�LV�Tom's��RU�LI�LW�LV�full-sized��RU�LILW�KDV�DQ�DGMRLQLQJ�FRPPD��TXRWH�PDUN��RU�DQ\�RWKHU�VWUDQJH�FKDUDFWHU��LW�ZLOO�PDWFKWKDW�SDWWHUQ�DQG�ZH¦OO�VNLS�WKH�UHVW�RI�WKH�ORRS��JRLQJ�RQ�WR�WKH�QH[W�ZRUG�

%XW�OHW¦V�VD\�WKDW�LW¦V�DQ�RUGLQDU\�ZRUG��OLNH�fred��,Q�WKDW�FDVH��ZH�FRXQW�$valid�XS�E\RQH��DQG�DOVR�$count{$_}��NHHSLQJ�D�FRXQW�IRU�HDFK�GLIIHUHQW�ZRUG��6R��ZKHQ�ZH�ILQLVKWKH�WZR�ORRSV��ZH¦YH�FRXQWHG�HYHU\�ZRUG�LQ�HYHU\�OLQH�RI�LQSXW�IURP�HYHU\�ILOH�WKH�XVHUZDQWHG�XV�WR�XVH�

:H¦UH�QRW�JRLQJ�WR�H[SODLQ�WKH�ODVW�IHZ�OLQHV��%\�QRZ��ZH�KRSH�\RX¦YH�JRW�VWXII�OLNH�WKDWGRZQ�DOUHDG\�

/LNH�last��next�PD\�EH�XVHG�LQ�DQ\�RI�WKH�ILYH�NLQGV�RI�ORRS�EORFNV��for��foreach��while�until��RU�WKH�QDNHG�EORFN��$OVR��LI�ORRS�EORFNV�DUH�QHVWHG��next�ZRUNV�ZLWK�WKH�LQQHUPRVWRQH��<RX¦OO�VHH�KRZ�WR�FKDQJH�WKDW�DW�WKH�HQG�RI�WKLV�VHFWLRQ�

,I�\RX�GRQ¦W�UHPHPEHU�LW��GRQ¦W�ZRUU\�WRR�PXFK��'RQ¦W�ZDVWH�DQ\�EUDLQ�FHOOV�UHPHPEHULQJ�WKLQJV�WKDW�\RXFDQ�ORRN�XS�ZLWK�SHUOGRF�

160 | Chapter 10:ಗMore Control Structures

The redo Operator7KH�WKLUG�PHPEHU�RI�WKH�ORRS�FRQWURO�WULDG�LV�redo��,W�VD\V�WR�JR�EDFN�WR�WKH�WRS�RI�WKHFXUUHQW�ORRS�EORFN��ZLWKRXW�WHVWLQJ�DQ\�FRQGLWLRQDO�H[SUHVVLRQ�RU�DGYDQFLQJ�WR�WKH�QH[WLWHUDWLRQ���,I�\RX¦YH�XVHG�&�RU�D�VLPLODU�ODQJXDJH��\RX¦YH�QHYHU�VHHQ�WKLV�RQH�EHIRUH�7KRVH�ODQJXDJHV�GRQ¦W�KDYH�WKLV�NLQG�RI�RSHUDWRU���+HUH¦V�DQ�H[DPSOH�

# Typing testmy @words = qw{ fred barney pebbles dino wilma betty };my $errors = 0;

foreach (@words) { ## redo comes here ## print "Type the word '$_': "; chomp(my $try = <STDIN>); if ($try ne $_) { print "Sorry - That's not right.\n\n"; $errors++; redo; # jump back up to the top of the loop }}print "You've completed the test, with $errors errors.\n";

/LNH�WKH�RWKHU�WZR�RSHUDWRUV��redo�ZLOO�ZRUN�ZLWK�DQ\�RI�WKH�ILYH�NLQGV�RI�ORRS�EORFNV�DQG�LW�ZLOO�ZRUN�ZLWK�WKH�LQQHUPRVW�ORRS�EORFN�ZKHQ�WKH\¦UH�QHVWHG�

7KH�ELJ�GLIIHUHQFH�EHWZHHQ�next�DQG�redo�LV�WKDW�next�ZLOO�DGYDQFH�WR�WKH�QH[W�LWHUDWLRQ�EXW�redo�ZLOO�UHGR�WKH�FXUUHQW�LWHUDWLRQ��+HUH¦V�DQ�H[DPSOH�SURJUDP�WKDW�\RX�FDQ�SOD\ZLWK�WR�JHW�D�IHHO�IRU�KRZ�WKHVH�WKUHH�RSHUDWRUV�ZRUN�

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

,I�\RX�MXVW�SUHVV�5HWXUQ�ZLWKRXW�W\SLQJ�DQ\WKLQJ��WU\�LW�WZR�RU�WKUHH�WLPHV���WKH�ORRSFRXQWV�DORQJ�IURP�RQH�QXPEHU�WR�WKH�QH[W��,I�\RX�FKRRVH�last�ZKHQ�\RX�JHW�WR�QXPEHUIRXU��WKH�ORRS�LV�GRQH��DQG�\RX�ZRQ¦W�JR�RQ�WR�QXPEHU�ILYH��,I�\RX�FKRRVH�next�ZKHQ\RX¦UH�RQ�IRXU��\RX¦UH�RQ�WR�QXPEHU�ILYH�ZLWKRXW�SULQWLQJ�WKH�£RQZDUG¤�PHVVDJH��$QGLI�\RX�FKRRVH�redo�ZKHQ�\RX¦UH�RQ�IRXU��\RX¦UH�EDFN�WR�GRLQJ�QXPEHU�IRXU�DOO�RYHU�DJDLQ�

,I�\RX¦YH�GRZQORDGHG�WKH�H[DPSOH�ILOHV�IURP�WKH�2¦5HLOO\�ZHE�VLWH��DV�GHVFULEHG�LQ�WKH�3UHIDFH���\RX¦OO�ILQGWKLV�SURJUDP��FDOOHG�OQU�H[DPSOH�

Loop Controls | 161

Labeled Blocks:KHQ�\RX�QHHG�WR�ZRUN�ZLWK�D�ORRS�EORFN�WKDW¦V�QRW�WKH�LQQHUPRVW�RQH��XVH�D�ODEHO�/DEHOV�LQ�3HUO�DUH�OLNH�RWKHU�LGHQWLILHUV¢PDGH�RI�OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV��EXWWKH\�FDQ¦W�VWDUW�ZLWK�D�GLJLW¢KRZHYHU��VLQFH�WKH\�KDYH�QR�SUHIL[�FKDUDFWHU��ODEHOV�FRXOGEH�FRQIXVHG�ZLWK�WKH�QDPHV�RI�EXLOW�LQ�IXQFWLRQ�QDPHV��RU�HYHQ�ZLWK�\RXU�RZQ�VXE�URXWLQHV¦�QDPHV��6R��LW�ZRXOG�EH�D�SRRU�FKRLFH�WR�PDNH�D�ODEHO�FDOOHG�print�RU�if��%HFDXVHRI�WKDW��/DUU\�UHFRPPHQGV�WKDW�WKH\�EH�DOO�XSSHUFDVH��7KDW�QRW�RQO\�HQVXUHV�WKDW�WKHODEHO�ZRQ¦W�FRQIOLFW�ZLWK�DQRWKHU�LGHQWLILHU�EXW�LW�DOVR�PDNHV�LW�HDV\�WR�VSRW�WKH�ODEHO�LQWKH�FRGH��,Q�DQ\�FDVH��ODEHOV�DUH�UDUH��RQO\�VKRZLQJ�XS�LQ�D�VPDOO�SHUFHQWDJH�RI�3HUOSURJUDPV�

7R�ODEHO�D�ORRS�EORFN��MXVW�SXW�WKH�ODEHO�DQG�D�FRORQ�LQ�IURQW�RI�WKH�ORRS��7KHQ��LQVLGHWKH�ORRS��\RX�PD\�XVH�WKH�ODEHO�DIWHU�last��next��RU�redo�DV�QHHGHG�

LINE: while (<>) { foreach (split) { last LINE if /__END__/; # bail out of the LINE loop ... }}

)RU�UHDGDELOLW\��LW¦V�JHQHUDOO\�QLFH�WR�SXW�WKH�ODEHO�DW�WKH�OHIW�PDUJLQ��HYHQ�LI�WKH�FXUUHQWFRGH�LV�DW�D�KLJKHU�LQGHQWDWLRQ��1RWLFH�WKDW�WKH�ODEHO�QDPHV�WKH�HQWLUH�EORFN��LW¦V�QRWPDUNLQJ�D�WDUJHW�SRLQW�LQ�WKH�FRGH� �,Q�WKDW�SUHYLRXV�VQLSSHW�RI�VDPSOH�FRGH��WKH�VSHFLDO__END__�WRNHQ�PDUNV�WKH�HQG�RI�DOO�LQSXW��2QFH�WKDW�WRNHQ�VKRZV�XS��WKH�SURJUDP�ZLOOLJQRUH�DQ\�UHPDLQLQJ�OLQHV��HYHQ�IURP�RWKHU�ILOHV��

,W�RIWHQ�PDNHV�VHQVH�WR�FKRRVH�D�QRXQ�DV�WKH�QDPH�RI�WKH�ORRS���7KDW�LV��WKH�RXWHU�ORRSLV�SURFHVVLQJ�D�OLQH�DW�D�WLPH��VR�ZH�FDOOHG�LW�LINE��,I�ZH�KDG�WR�QDPH�WKH�LQQHU�ORRS��ZHZRXOG�KDYH�FDOOHG�LW�WORD��VLQFH�LW�SURFHVVHV�D�ZRUG�DW�D�WLPH��7KDW�PDNHV�LW�FRQYHQLHQWWR�VD\�WKLQJV�OLNH�£�PRYH�RQ�WR�WKH��next WORD¤RU�£redo��WKH�FXUUHQW��LINE¤�

The Ternary Operator, ?::KHQ�/DUU\�ZDV�GHFLGLQJ�ZKLFK�RSHUDWRUV�WR�PDNH�DYDLODEOH�LQ�3HUO��KH�GLGQ¦W�ZDQWIRUPHU�&�SURJUDPPHUV�WR�PLVV�VRPHWKLQJ�WKDW�&�KDG�DQG�3HUO�GLGQ¦W��VR�KH�EURXJKW�DOORI�&¦V�RSHUDWRUV�RYHU�WR�3HUO�®�7KDW�PHDQW�EULQJLQJ�RYHU�&¦V�PRVW�FRQIXVLQJ�RSHUDWRU�WKH�WHUQDU\�?:�RSHUDWRU��:KLOH�LW�PD\�EH�FRQIXVLQJ��LW�FDQ�DOVR�EH�TXLWH�XVHIXO�

7KLV�LVQ¦W�goto��DIWHU�DOO�

� 7KDW�LV��LW�PDNHV�PRUH�VHQVH�WR�GR�WKDW�WKDQ�QRW�WR�GR�WKDW��3HUO�GRHVQ¦W�FDUH�LI�\RX�FDOO�\RXU�ORRS�ODEHOV�WKLQJVOLNH�XYZZY�RU�PLUGH��+RZHYHU��XQOHVV�\RX�ZHUH�IULHQGO\�ZLWK�WKH�&RORVVDO�&DYH�LQ�WKH�¦��V��\RX�PLJKW�QRW�JHWWKH�UHIHUHQFH�

® :HOO��WR�EH�VXUH��KH�GLG�OHDYH�RXW�WKH�RQHV�WKDW�KDYH�QR�XVH�LQ�3HUO��VXFK�DV�WKH�RSHUDWRU�WKDW�WXUQV�D�QXPEHULQWR�WKH�PHPRU\�DGGUHVV�RI�D�YDULDEOH��$QG�KH�DGGHG�VHYHUDO�RSHUDWRUV��OLNH�WKH�VWULQJ�FRQFDWHQDWLRQ�RSHUDWRU�WKDW�PDNH�&�IRONV�MHDORXV�RI�3HUO�

162 | Chapter 10:ಗMore Control Structures

7KH�WHUQDU\�RSHUDWRU�LV�OLNH�DQ�LI�WKHQ�HOVH�WHVW��DOO�UROOHG�LQWR�DQ�H[SUHVVLRQ��,W�LV�FDOOHGD�£WHUQDU\¤�RSHUDWRU�EHFDXVH�LW�WDNHV�WKUHH�RSHUDQGV��,W�ORRNV�OLNH�WKLV�

expression ? if_true_expr : if_false_expr

)LUVW��WKH�H[SUHVVLRQ�LV�HYDOXDWHG�WR�VHH�ZKHWKHU�LW¦V�WUXH�RU�IDOVH��,I�LW¦V�WUXH��WKH�VHFRQGH[SUHVVLRQ�LV�XVHG��RWKHUZLVH��WKH�WKLUG�H[SUHVVLRQ�LV�XVHG��(YHU\�WLPH��RQH�RI�WKH�WZRH[SUHVVLRQV�RQ�WKH�ULJKW�LV�HYDOXDWHG��DQG�RQH�LV�LJQRUHG��7KDW�LV��LI�WKH�ILUVW�H[SUHVVLRQLV�WUXH��WKHQ�WKH�VHFRQG�H[SUHVVLRQ�LV�HYDOXDWHG��DQG�WKH�WKLUG�LV�LJQRUHG��,I�WKH�ILUVWH[SUHVVLRQ�LV�IDOVH��WKHQ�WKH�VHFRQG�LV�LJQRUHG��DQG�WKH�WKLUG�LV�HYDOXDWHG�DV�WKH�YDOXHRI�WKH�ZKROH�WKLQJ�

,Q�WKLV�H[DPSOH��WKH�UHVXOW�RI�WKH�VXEURXWLQH�&is_weekend�GHWHUPLQHV�ZKLFK�VWULQJ�H[�SUHVVLRQ�ZLOO�EH�DVVLJQHG�WR�WKH�YDULDEOH�

my $location = &is_weekend($day) ? "home" : "work";

$QG�KHUH��ZH�FDOFXODWH�DQG�SULQW�RXW�DQ�DYHUDJH¢RU�MXVW�D�SODFHKROGHU�OLQH�RI�K\SKHQV�LI�WKHUH¦V�QR�DYHUDJH�DYDLODEOH�

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

<RX�FRXOG�DOZD\V�UHZULWH�DQ\�XVH�RI�WKH�?:�RSHUDWRU�DV�DQ�if�VWUXFWXUH��RIWHQ�PXFK�OHVVFRQYHQLHQWO\�DQG�OHVV�FRQFLVHO\�

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

+HUH¦V�D�WULFN�\RX�PLJKW�VHH�XVHG�WR�FRGH�XS�D�QLFH�PXOWLZD\�EUDQFK�

my $size = ($width < 10) ? "small" : ($width < 20) ? "medium" : ($width < 50) ? "large" : "extra-large"; # default

7KDW�LV�UHDOO\�MXVW�WKUHH�QHVWHG�?:�RSHUDWRUV��DQG�LW�ZRUNV�TXLWH�ZHOO��RQFH�\RX�JHW�WKHKDQJ�RI�LW�

2I�FRXUVH��\RX¦UH�QRW�REOLJHG�WR�XVH�WKLV�RSHUDWRU��%HJLQQHUV�PD\�ZLVK�WR�DYRLG�LW��%XW\RX¦OO�VHH�LW�LQ�RWKHUV¦�FRGH��VRRQHU�RU�ODWHU��DQG�ZH�KRSH�WKDW�RQH�GD\�\RX¦OO�ILQG�D�JRRGUHDVRQ�WR�XVH�LW�LQ�\RXU�RZQ�SURJUDPV�

The Ternary Operator, ?: | 163

Logical Operators$V�\RX�PLJKW�H[SHFW��3HUO�KDV�DOO�RI�WKH�QHFHVVDU\�ORJLFDO�RSHUDWRUV�QHHGHG�WR�ZRUN�ZLWK%RROHDQ��WUXH�IDOVH��YDOXHV��)RU�H[DPSOH��LW¦V�RIWHQ�XVHIXO�WR�FRPELQH�ORJLFDO�WHVWV�E\XVLQJ�WKH�ORJLFDO�$1'�RSHUDWRU��&&��DQG�WKH�ORJLFDO�25�RSHUDWRU��||��

if ($dessert{'cake'} && $dessert{'ice cream'}) { # Both are true print "Hooray! Cake and ice cream!\n";} elsif ($dessert{'cake'} || $dessert{'ice cream'}) { # At least one is true print "That's still good...\n";} else { # Neither is true - do nothing (we're sad)}

7KHUH�PD\�EH�D�VKRUWFXW��,I�WKH�OHIW�VLGH�RI�D�ORJLFDO�$1'�RSHUDWLRQ�LV�IDOVH��WKH�ZKROHWKLQJ�LV�IDOVH��VLQFH�ORJLFDO�$1'�QHHGV�ERWK�VLGHV�WR�EH�WUXH�LQ�RUGHU�WR�UHWXUQ�WUXH��,QWKDW�FDVH��WKHUH¦V�QR�UHDVRQ�WR�FKHFN�WKH�ULJKW�VLGH��VR�LW�ZLOO�QRW�HYHQ�EH�HYDOXDWHG�&RQVLGHU�ZKDW�KDSSHQV�LQ�WKLV�H[DPSOH�LI�$hour�LV�3�

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

6LPLODUO\�� LI� WKH�OHIW�VLGH�RI�D� ORJLFDO�25�RSHUDWLRQ�LV�WUXH�� WKH�ULJKW�VLGH�ZLOO�QRW�EHHYDOXDWHG��&RQVLGHU�ZKDW�KDSSHQV�KHUH�LI�$name�LV�fred�

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

%HFDXVH�RI�WKLV�EHKDYLRU��WKHVH�RSHUDWRUV�DUH�FDOOHG�£VKRUW�FLUFXLW¤�ORJLFDO�RSHUDWRUV�7KH\�WDNH�D�VKRUW�FLUFXLW�WR�WKH�UHVXOW�ZKHQHYHU�WKH\�FDQ��,Q�IDFW��LW¦V�IDLUO\�FRPPRQ�WRUHO\�XSRQ�WKLV�VKRUW�FLUFXLW�EHKDYLRU��6XSSRVH�\RX�QHHG�WR�FDOFXODWH�DQ�DYHUDJH�

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

,Q�WKDW�H[DPSOH��WKH�ULJKW�VLGH�ZLOO�EH�HYDOXDWHG�RQO\�LI�WKH�OHIW�VLGH�LV�WUXH��VR�ZH�FDQ¦WDFFLGHQWDOO\�GLYLGH�E\�]HUR�DQG�FUDVK�WKH�SURJUDP�

The Value of a Short-Circuit Operator8QOLNH�ZKDW�KDSSHQV�LQ�&��DQG�VLPLODU�ODQJXDJHV���WKH�YDOXH�RI�D�VKRUW�FLUFXLW�ORJLFDORSHUDWRU�LV�WKH�ODVW�SDUW�HYDOXDWHG��QRW�MXVW�D�%RROHDQ�YDOXH��7KLV�SURYLGHV�WKH�VDPHUHVXOW��LQ�WKDW�WKH�ODVW�SDUW�HYDOXDWHG�LV�DOZD\V�WUXH�ZKHQ�WKH�ZKROH�WKLQJ�VKRXOG�EHWUXH��DQG�LW¦V�DOZD\V�IDOVH�ZKHQ�WKH�ZKROH�WKLQJ�VKRXOG�EH�IDOVH�

%XW�LW¦V�D�PXFK�PRUH�XVHIXO�UHWXUQ�YDOXH��$PRQJ�RWKHU�WKLQJV��WKH�ORJLFDO�25�RSHUDWRULV�TXLWH�KDQG\�IRU�VHOHFWLQJ�D�GHIDXOW�YDOXH�

164 | Chapter 10:ಗMore Control Structures

my $last_name = $last_name{$someone} || '(No last name)';

,I�$someone�LV�QRW�OLVWHG�LQ�WKH�KDVK��WKH�OHIW�VLGH�ZLOO�EH�undef��ZKLFK�LV�IDOVH��6R��WKHORJLFDO�25�ZLOO�KDYH�WR�ORRN�WR�WKH�ULJKW�VLGH�IRU�WKH�YDOXH��PDNLQJ�WKH�ULJKW�VLGH�WKHGHIDXOW��,Q�WKLV�LGLRP��WKH�GHIDXOW�YDOXH�ZRQ¦W�PHUHO\�UHSODFH�undef��LW�ZRXOG�UHSODFHDQ\�IDOVH�YDOXH�HTXDOO\�ZHOO��<RX�FRXOG�IL[�WKDW�ZLWK�WKH�WHUQDU\�RSHUDWRU�

my $last_name = defined $last_name{$someone} ? $last_name{$someone} : '(No last name)';

7KDW¦V�WRR�PXFK�ZRUN��DQG�\RX�KDG�WR�VD\�$last_name{$someone}�WZLFH��3HUO������DGGHGD�EHWWHU�ZD\�WR�GR�WKLV��DQG�LW¦V�WKH�QH[W�VHFWLRQ�

The defined-or Operator,Q�WKH�SUHYLRXV�VHFWLRQ��\RX�VDZ�XV�XVH�WKH�||�RSHUDWRU�WR�JLYH�D�GHIDXOW�YDOXH��7KDWLJQRUHG�WKH�VSHFLDO�FDVH��WKHUH�WKH�GHILQHG�YDOXH�ZDV�IDOVH�EXW�SHUIHFWO\�DFFHSWDEOH�DV�DYDOXH��<RX�WKHQ�VDZ�WKH�XJOLHU�YHUVLRQ�XVLQJ�WKH�WHUQDU\�RSHUDWRU�

3HUO������JHWV�DURXQG�WKLV�VRUW�RI�EXJ�ZLWK�WKH�GHILQHG�RU�RSHUDWRU��//��ZKLFK�VKRUW�FLUFXLWV�ZKHQ�LW�ILQGV�D�GHILQHG�YDOXH��QR�PDWWHU�LI�WKDW�YDOXH�RQ�WKH�OHIWKDQG�VLGH�LV�WUXHRU�IDOVH��(YHQ�LI�VRPHRQH¦V�ODVW�QDPH�LV�0��WKLV�YHUVLRQ�VWLOO�ZRUNV�

use 5.010;

my $last_name = $last_name{$someone} // '(No last name)';

6RPHWLPHV�\RX�MXVW�ZDQW�WR�JLYH�D�YDULDEOH�D�YDOXH�LI�LW�GRHVQ¦W�DOUHDG\�KDYH�RQH��DQGOHDYH� LW� DORQH� LI� LW� GRHV�� 6XSSRVH� \RX� ZDQW� WR� SULQW� PHVVDJHV� RQO\� LI� \RX� VHW� WKHVERBOSE�HQYLURQPHQW�YDULDEOH��<RX�FKHFN�WKH�YDOXH�IRU�WKH�VERBOSE�NH\�LQ�WKH�%ENV�KDVK�,I�LW�GRHVQ¦W�KDYH�D�YDOXH��\RX�ZDQW�WR�JLYH�LW�RQH�

use 5.010;

my $Verbose = $ENV{VERBOSE} // 1;print "I can talk to you!\n" if $Verbose;

<RX�FDQ�VHH�WKLV�LQ�DFWLRQ�E\�WU\LQJ�VHYHUDO�YDOXHV�ZLWK�//�WR�VHH�ZKLFK�RQHV�SDVV�WKURXJKWR�WKH�default�YDOXH�

use 5.010;

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

7KH�RXWSXW�VKRZV�WKDW�\RX�RQO\�JHW�WKH�default�VWULQJ�ZKHQ�$try�LV�undef�

Trying [0] ---> got [0]Trying [] ---> got [default]Trying [0] ---> got [0]

Logical Operators | 165

Trying [1] ---> got [1]Trying [25] ---> got [25]

6RPHWLPHV�\RX�ZDQW�WR�VHW�D�YDOXH�ZKHQ�WKHUH�LVQ¦W�RQH�DOUHDG\��)RU�LQVWDQFH��ZKHQ\RX�KDYH�ZDUQLQJV�HQDEOHG�DQG�WU\�WR�SULQW�DQ�XQGHILQHG�YDOXH��\RX�JHW�DQ�DQQR\LQJHUURU�

use warnings;

my $name; # no value, so undefined!printf "%s", $name; # Use of uninitialized value in printf ...

6RPHWLPHV�WKDW�HUURU�LV�KDUPOHVV��<RX�FRXOG�MXVW�LJQRUH�LW��EXW�LI�\RX�H[SHFW�WKDW�\RXPLJKW�WU\�WR�SULQW�DQ�XQGHILQHG�YDOXH��\RX�FDQ�XVH�WKH�HPSW\�VWULQJ�LQVWHDG�

use 5.010;use warnings;

my $name; # no value, so undefined!printf "%s", $name // '';

Control Structures Using Partial-Evaluation Operators7KH�IRXU�RSHUDWRUV�WKDW�\RX¦YH�MXVW�VHHQ¢&&��||��//��DQG�?:¢DOO�VKDUH�D�SHFXOLDU�SURS�HUW\�� GHSHQGLQJ� XSRQ� WKH� YDOXH� RQ� WKH� OHIW� VLGH�� WKH\�PD\� RU�PD\� QRW� HYDOXDWH� DQH[SUHVVLRQ��6RPHWLPHV�WKH�H[SUHVVLRQ� LV�HYDOXDWHG��DQG�VRPHWLPHV� LW� LVQ¦W��)RU�WKDWUHDVRQ�� WKHVH�DUH� VRPHWLPHV�FDOOHG�SDUWLDO�HYDOXDWLRQ�RSHUDWRUV�� VLQFH� WKH\�PD\�QRWHYDOXDWH� DOO� RI� WKH� H[SUHVVLRQV� DURXQG� WKHP�� $QG� SDUWLDO�HYDOXDWLRQ� RSHUDWRUV� DUHDXWRPDWLFDOO\�FRQWURO�VWUXFWXUHV� �,W¦V�QRW�DV�LI�/DUU\�IHOW�D�EXUQLQJ�QHHG�WR�DGG�PRUHFRQWURO�VWUXFWXUHV�WR�3HUO��%XW�RQFH�KH�KDG�GHFLGHG�WR�SXW�WKHVH�SDUWLDO�HYDOXDWLRQ�RS�HUDWRUV�LQWR�3HUO��WKH\�DXWRPDWLFDOO\�EHFDPH�FRQWURO�VWUXFWXUHV�DV�ZHOO��$IWHU�DOO��DQ\�WKLQJ�WKDW�FDQ�DFWLYDWH�DQG�GHDFWLYDWH�D�FKXQN�RI�FRGH�LV��E\�WKDW�YHU\�IDFW��D�FRQWUROVWUXFWXUH�

)RUWXQDWHO\��\RX¦OO�QRWLFH�WKLV�RQO\�ZKHQ�WKH�FRQWUROOHG�H[SUHVVLRQ�KDV�VLGH�HIIHFWV��OLNHDOWHULQJ�D�YDULDEOH¦V�YDOXH�RU�FDXVLQJ�VRPH�RXWSXW��)RU�H[DPSOH��VXSSRVH�\RX�UDQ�DFURVVWKLV�OLQH�RI�FRGH�

($m < $n) && ($m = $n);

5LJKW�DZD\��\RX�VKRXOG�QRWLFH�WKDW�WKH�UHVXOW�RI�WKH�ORJLFDO�$1'�LVQ¦W�EHLQJ�DVVLJQHGDQ\ZKHUH���:K\�QRW"

,I�$m�LV�UHDOO\�OHVV�WKDQ�$n��WKH�OHIW�VLGH�LV�WUXH��VR�WKH�ULJKW�VLGH�ZLOO�EH�HYDOXDWHG��WKHUHE\GRLQJ�WKH�DVVLJQPHQW��%XW�LI�$m�LV�QRW�OHVV�WKDQ�$n��WKH�OHIW�VLGH�ZLOO�EH�IDOVH��DQG�WKXVWKH�ULJKW�VLGH�ZRXOG�EH�VNLSSHG��6R�WKDW�OLQH�RI�FRGH�ZRXOG�GR�HVVHQWLDOO\�WKH�VDPH�WKLQJDV�WKLV�RQH��ZKLFK�LV�HDVLHU�WR�XQGHUVWDQG�

6RPH�RI�\RX�ZHUH�ZRQGHULQJ�ZK\�WKHVH�ORJLFDO�RSHUDWRUV�DUH�EHLQJ�FRYHUHG�LQ�WKLV�FKDSWHU��ZHUHQ¦W�\RX"

� %XW�GRQ¦W�IRUJHW�WR�FRQVLGHU�WKDW�LW�PLJKW�EH�D�UHWXUQ�YDOXH��DV�WKH�ODVW�H[SUHVVLRQ�LQ�D�VXEURXWLQH�

166 | Chapter 10:ಗMore Control Structures

if ($m < $n) { $m = $n }

2U�PD\EH�\RX¦OO�EH�PDLQWDLQLQJ�D�SURJUDP��DQG�\RX¦OO�VHH�D�OLQH�OLNH�WKLV�RQH�

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

,I�$m�LV�UHDOO\�JUHDWHU�WKDQ�����WKH�OHIW�VLGH�LV�WUXH��DQG�WKH�ORJLFDO�25�LV�GRQH��%XW�LI�LW¦VQRW��WKH�OHIW�VLGH�LV�IDOVH��DQG�WKLV�ZLOO�JR�RQ�WR�SULQW�WKH�PHVVDJH��2QFH�DJDLQ��WKLV�FRXOG�DQG�SUREDEO\�VKRXOG��EH�ZULWWHQ�LQ�WKH�WUDGLWLRQDO�ZD\��SUREDEO\�ZLWK�if�RU�unless�

,I�\RX�KDYH�D�SDUWLFXODUO\�WZLVWHG�EUDLQ��\RX�PLJKW�HYHQ�OHDUQ�WR�UHDG�WKHVH�OLQHV�DV�LIWKH\�ZHUH�ZULWWHQ�LQ�(QJOLVK��)RU�H[DPSOH��FKHFN�WKDW�$m�LV�OHVV�WKDQ�$n��DQG�LI�LW�LV��WKHQGR�WKH�DVVLJQPHQW��&KHFN�WKDW�$m�LV�PRUH�WKDQ�����RU�LI�LW¦V�QRW��WKHQ�SULQW�WKH�PHVVDJH�

,W¦V�JHQHUDOO\�IRUPHU�&�SURJUDPPHUV�RU�ROG�WLPH�3HUO�SURJUDPPHUV�ZKR�PRVW�RIWHQ�XVHWKHVH�ZD\V�RI�ZULWLQJ�FRQWURO�VWUXFWXUHV��:K\�GR�WKH\�GR�LW"�6RPH�KDYH�WKH�PLVWDNHQLGHD�WKDW�WKHVH�DUH�PRUH�HIILFLHQW��6RPH�WKLQN�WKHVH�WULFNV�PDNH�WKHLU�FRGH�FRROHU��6RPHDUH�PHUHO\�FRS\LQJ�ZKDW�WKH\�VDZ�VRPHRQH�HOVH�GR�

,Q�WKH�VDPH�ZD\��WKH�WHUQDU\�RSHUDWRU�PD\�EH�XVHG�IRU�FRQWURO��,Q�WKLV�FDVH��ZH�ZDQW�WRDVVLJQ�$x�WR�WKH�VPDOOHU�RI�WZR�YDULDEOHV�

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

,I�$m�LV�VPDOOHU��LW�JHWV�$x��2WKHUZLVH��$n�GRHV�

7KHUH�LV�DQRWKHU�ZD\�WR�ZULWH�WKH�ORJLFDO�$1'�DQG�ORJLFDO�25�RSHUDWRUV��<RX�PD\�ZLVKWR�ZULWH�WKHP�RXW�DV�ZRUGV��and�DQG�or� �7KHVH�ZRUG�RSHUDWRUV�KDYH�WKH�VDPH�EHKDYLRUVDV�WKH�RQHV�ZULWWHQ�ZLWK�SXQFWXDWLRQ��EXW�WKH�ZRUGV�DUH�GRZQ�DW�WKH�ERWWRP�RI�WKH�SUHFHGHQFH�FKDUW��6LQFH�WKH�ZRUGV�GRQ¦W�£VWLFN¤�VR�WLJKWO\�WR�WKH�QHDUE\�SDUWV�RI�WKHH[SUHVVLRQ��WKH\�PD\�QHHG�IHZHU�SDUHQWKHVHV�

$m < $n and $m = $n; # but better written as the corresponding if

7KHQ�DJDLQ��\RX�PD\�QHHG�PRUH�SDUHQWKHVHV��3UHFHGHQFH�LV�D�EXJDERR��%H�VXUH�WR�XVHSDUHQWKHVHV�WR�VD\�ZKDW�\RX�PHDQ��XQOHVV�\RX¦UH�VXUH�RI�WKH�SUHFHGHQFH��1HYHUWKHOHVV�VLQFH�WKH�ZRUG�IRUPV�DUH�YHU\�ORZ�SUHFHGHQFH��\RX�FDQ�JHQHUDOO\�XQGHUVWDQG�WKDW�WKH\FXW�WKH�H[SUHVVLRQ�LQWR�ELJ�SLHFHV��GRLQJ�HYHU\WKLQJ�RQ�WKH�OHIW�ILUVW��DQG�WKHQ��LI�QHHGHG�HYHU\WKLQJ�RQ�WKH�ULJKW�

'HVSLWH�WKH�IDFW� WKDW�XVLQJ� ORJLFDO�RSHUDWRUV�DV�FRQWURO�VWUXFWXUHV�FDQ�EH�FRQIXVLQJ�VRPHWLPHV�WKH\¦UH�WKH�DFFHSWHG�ZD\�WR�ZULWH�FRGH��7KH�LGLRPDWLF�ZD\�RI�RSHQLQJ�D�ILOHLQ�3HUO�ORRNV�OLNH�WKLV�

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

%\�XVLQJ�WKH�ORZ�SUHFHGHQFH�VKRUW�FLUFXLW�or�RSHUDWRU��ZH¦UH�WHOOLQJ�3HUO�WKDW�LW�VKRXOG£RSHQ�WKLV�ILOH��RU�GLH�¤�,I�WKH�open�VXFFHHGV��UHWXUQLQJ�D�WUXH�YDOXH��WKH�or�LV�FRPSOHWH�

7KHUH�DUH�DOVR�WKH�ORZ�SUHFHGHQFH�not��OLNH�WKH�ORJLFDO�QHJDWLRQ�RSHUDWRU��!��DQG�WKH�UDUH�xor�

Logical Operators | 167

%XW�LI�LW�IDLOV��WKH�IDOVH�YDOXH�FDXVHV�WKH�or�WR�HYDOXDWH�WKH�SDUW�RQ�WKH�ULJKW��ZKLFK�ZLOOGLH�ZLWK�D�PHVVDJH�

6R��XVLQJ�WKHVH�RSHUDWRUV�DV�FRQWURO�VWUXFWXUHV�LV�SDUW�RI�LGLRPDWLF�3HUO¢3HUO�DV�VKH�LVVSRNHQ��8VHG�SURSHUO\��WKH\�FDQ�PDNH�\RXU�FRGH�PRUH�SRZHUIXO��RWKHUZLVH��WKH\�FDQPDNH�\RXU�FRGH�XQPDLQWDLQDEOH��'RQ¦W�RYHUXVH�WKHP�

Exercises6HH�$SSHQGL[�$�IRU�WKH�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >��@�0DNH�D�SURJUDP�WKDW�ZLOO�UHSHDWHGO\�DVN�WKH�XVHU�WR�JXHVV�D�VHFUHW�QXPEHUIURP���WR�����XQWLO�WKH�XVHU�JXHVVHV�WKH�VHFUHW�QXPEHU��<RXU�SURJUDP�VKRXOG�SLFNWKH�QXPEHU�DW�UDQGRP�E\�XVLQJ�WKH�PDJLFDO�IRUPXOD�int(1 + rand 100)���:KHQWKH�XVHU�JXHVVHV�ZURQJ��WKH�SURJUDP�VKRXOG�UHVSRQG�£7RR�KLJK¤�RU�£7RR�ORZ�¤�,IWKH�XVHU�HQWHUV�WKH�ZRUG�quit�RU�exit��RU�LI�WKH�XVHU�HQWHUV�D�EODQN�OLQH��WKH�SURJUDPVKRXOG�TXLW��2I�FRXUVH��LI�WKH�XVHU�JXHVVHV�FRUUHFWO\��WKH�SURJUDP�VKRXOG�TXLW�WKHQDV�ZHOO�

�� >��@�0RGLI\�WKH�SURJUDP�IURP�WKH�SUHYLRXV�H[HUFLVH�WR�SULQW�H[WUD�GHEXJJLQJ�LQ�IRUPDWLRQ�DV�LW�JRHV�DORQJ��VXFK�DV�WKH�VHFUHW�QXPEHU�LW�FKRVH��0DNH�\RXU�FKDQJHVXFK�WKDW�\RX�FDQ�WXUQ�LW�RII��EXW�\RXU�SURJUDP�HPLWV�QR�ZDUQLQJV�LI�\RX�WXUQ�LW�RII�,I�\RX�DUH�XVLQJ�3HUO�������XVH�WKH�//�RSHUDWRU��2WKHUZLVH��XVH�WKH�WHUQDU\�RSHUDWRU�

�� >��@�0RGLI\�WKH�SURJUDP�IURP�([HUFLVH���LQ�&KDSWHU����WKH�HQYLURQPHQW�OLVWHU��WRSULQW�(undefined value)�IRU�HQYLURQPHQW�YDULDEOHV�ZLWKRXW�D�YDOXH��<RX�FDQ�VHWWKH�QHZ�HQYLURQPHQW�YDULDEOHV�LQ�WKH�SURJUDP��(QVXUH�WKDW�\RXU�SURJUDP�UHSRUWVWKH� ULJKW� WKLQJ� IRU� YDULDEOHV�ZLWK� D� IDOVH� YDOXH�� ,I� \RX� DUH� XVLQJ� 3HUO� ������ XVHWKH�//�RSHUDWRU��2WKHUZLVH��XVH�WKH�WHUQDU\�RSHUDWRU�

8VLQJ�WKHVH�ZHLUG�IRUPV��DQ\WKLQJ�EXW�or die��PRUH�WKDQ�RQFH�SHU�PRQWK�FRXQWV�DV�RYHUXVH�

� 6HH�ZKDW�WKH�SHUOIXQF�PDQSDJH�VD\V�DERXW�int�DQG�rand�LI�\RX¦UH�FXULRXV�DERXW�WKHVH�IXQFWLRQV�

168 | Chapter 10:ಗMore Control Structures

CHAPTER 11

Perl Modules

7KHUH�LV�D�ORW�PRUH�WR�3HUO�WKDQ�ZKDW�ZH¦UH�DEOH�WR�VKRZ�\RX�LQ�WKLV�ERRN��DQG�WKHUHDUH�D�ORW�RI�SHRSOH�GRLQJ�D�ORW�RI�LQWHUHVWLQJ�WKLQJV�ZLWK�3HUO��,I�WKHUH�LV�D�SUREOHP�WRVROYH��WKHQ�VRPHERG\�KDV�SUREDEO\�DOUHDG\�VROYHG�LW�DQG�PDGH�WKHLU�VROXWLRQ�DYDLODEOHRQ�WKH�&RPSUHKHQVLYH�3HUO�$UFKLYH�1HWZRUN��&3$1���ZKLFK�LV�D�ZRUOGZLGH�FROOHFWLRQRI�VHUYHUV�DQG�PLUURUV�FRQWDLQLQJ�WKRXVDQGV�RI�PRGXOHV�RI�UHXVDEOH�3HUO�FRGH�

:H¦UH�QRW�JRLQJ�WR�WHDFK�\RX�KRZ�WR�ZULWH�PRGXOHV�KHUH��\RX¦OO�KDYH�WR�JHW�WKDW�IURPWKH�$OSDFD�ERRN��,Q�WKLV�FKDSWHU��ZH¦OO�VKRZ�\RX�KRZ�WR�XVH�PRGXOHV�WKDW�DOUHDG\�H[LVW�

Finding Modules0RGXOHV�FRPH�LQ�WZR�W\SHV��WKRVH�WKDW�FRPH�ZLWK�3HUO�DQG�WKDW�\RX�VKRXOG�KDYH�DYDLO�DEOH�WR�\RX��DQG�WKRVH�WKDW�\RX�FDQ�JHW�IURP�&3$1�WR�LQVWDOO�\RXUVHOI��8QOHVV�ZH�VD\RWKHUZLVH��WKH�PRGXOHV�WKDW�ZH�GLVFXVV�FRPH�ZLWK�3HUO�

7R� ILQG� PRGXOHV� WKDW� GRQ¦W� FRPH� ZLWK� 3HUO�� VWDUW� DW� HLWKHU� &3$1� 6HDUFK� �KWWS���VHDUFK�FSDQ�RUJ�� RU� .REHV¦� 6HDUFK� �KWWS���NREHVHDUFK�FSDQ�RUJ��� � <RX� FDQ� EURZVHWKURXJK�WKH�FDWHJRULHV�RU�VHDUFK�GLUHFWO\�

(LWKHU�RI�WKRVH�UHVRXUFHV�LV�JUHDW�VLQFH�\RX�FDQ�UHDG�WKH�PRGXOH��EHIRUH�\RX�GRZQORDGWKH�HQWLUH�SDFNDJH��<RX�FDQ�DOVR�EURZVH�WKH�GLVWULEXWLRQ�DQG�KDYH�D�SHHN�DW�WKH�ILOHVZLWKRXW�WKH�ERWKHU�RI�LQVWDOOLQJ�WKH�PRGXOHV�

%HIRUH�\RX�JR�ORRNLQJ�IRU�D�PRGXOH��\RX�VKRXOG�FKHFN�ZKHWKHU�LW�LV�DOUHDG\�LQVWDOOHG�2QH�ZD\� LV� WR� MXVW� WU\� WR�UHDG�WKH�GRFXPHQWDWLRQ�ZLWK�SHUOGRF��7KH�CGI.pm�PRGXOHFRPHV�ZLWK�3HUO��DQG�ZH¦OO�GLVFXVV�LW�ODWHU�LQ�WKLV�FKDSWHU���VR�\RX�VKRXOG�EH�DEOH�WR�UHDGLWV�GRFXPHQWDWLRQ�

$ perldoc CGI

7U\�LW�ZLWK�D�PRGXOH�WKDW�GRHV�QRW�H[LVW�DQG�\RX¦OO�JHW�DQ�HUURU�PHVVDJH�

<HV��WKHUH�VKRXOG�EH�WZR�V¦V�LQ�WKDW�85/��EXW�WKHUH�DUHQ¦W�DQG�QRERG\�HYHU�IL[HG�LW�

169

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

7KH�GRFXPHQWDWLRQ�PD\�EH�DYDLODEOH�LQ�RWKHU�IRUPDWV��VXFK�DV�+70/��RQ�\RXU�V\VWHP�WRR��,I�WKH�GRFXPHQWDWLRQ�LV�WKHUH�

Installing Modules:KHQ�\RX�ZDQW�WR�LQVWDOO�D�PRGXOH�WKDW�\RX�GRQ¦W�DOUHDG\�KDYH��VRPHWLPHV�\RX�FDQVLPSO\�GRZQORDG�WKH�GLVWULEXWLRQ��XQSDFN�LW��DQG�UXQ�D�VHULHV�RI�FRPPDQGV�IURP�WKHVKHOO��&KHFN�IRU�D�5($'0(�RU�,167$//�ILOH�WKDW�JLYHV�\RX�PRUH�LQIRUPDWLRQ��,I�WKHPRGXOH�XVHV�0DNH0DNHU���WKH�VHTXHQFH�ZLOO�EH�VRPHWKLQJ�OLNH�WKLV�

$ perl Makefile.PL$ make install

,I�\RX�FDQ¦W� LQVWDOO�PRGXOHV� LQ�WKH�V\VWHP�ZLGH�GLUHFWRULHV��\RX�FDQ�VSHFLI\�DQRWKHUGLUHFWRU\�ZLWK�D�PREFIX�DUJXPHQW�WR�0DNHILOH�3/�

$ perl Makefile.PL PREFIX=/Users/fred/lib

6RPH�3HUO�PRGXOH�DXWKRUV�XVH�DQRWKHU�PRGXOH��Module::Build��WR�EXLOG�DQG�LQVWDOO�WKHLUFUHDWLRQV��7KDW�VHTXHQFH�ZLOO�EH�VRPHWKLQJ�OLNH�WKLV�

$ perl Build.PL$ ./Build install

6RPH�PRGXOHV�GHSHQG�RQ�RWKHU�PRGXOHV� WKRXJK��DQG� WKH\�ZRQ¦W�ZRUN�XQOHVV�\RXLQVWDOO�\HW�PRUH�PRGXOHV��,QVWHDG�RI�GRLQJ�DOO�WKDW�ZRUN�RXUVHOYHV��ZH�FDQ�XVH�RQH�RIWKH�PRGXOHV�WKDW�FRPHV�ZLWK�3HUO��CPAN.pm�®�)URP�WKH�FRPPDQG�OLQH��\RX�FDQ�VWDUW�XSWKH�CPAN.pm��IURP�ZKLFK�\RX�FDQ�LVVXH�FRPPDQGV�

$ perl -MCPAN -e shell

(YHQ�WKLV�FDQ�EH�D�OLWWOH�FRPSOLFDWHG��VR�D�ZKLOH�DJR�RQH�RI�RXU�DXWKRUV�ZURWH�D�OLWWOHVFULSW�FDOOHG�£FSDQ�¤�ZKLFK�DOVR�FRPHV�ZLWK�3HUO�DQG�LV�XVXDOO\�LQVWDOOHG�ZLWK�SHUO�DQGLWV�WRROV��-XVW�FDOO�WKH�VFULSW�ZLWK�D�OLVW�RI�WKH�PRGXOHV�\RX�ZDQW�WR�LQVWDOO�

$ cpan Module::CoreList LWP CGI::Prototype

:H�FRYHU�3HUO�GRFXPHQWDWLRQ�LQ�,QWHUPHGLDWH�3HUO��2¦5HLOO\���EXW�IRU�QRZ��MXVW�EHOLHYH�XV�WKDW�PRVW�PRGXOHGRFXPHQWDWLRQ�LV�LQ�WKH�VDPH�ILOH�DV�WKH�DFWXDO�FRGH�

� 7KDW¦V�UHDOO\�WKH�3HUO�PRGXOH�ExtUtils::MakeMaker��ZKLFK�FRPHV�ZLWK�3HUO��,W�KDQGOHV�DOO�RI�WKH�VWXII�WR�FUHDWHWKH�ILOH�WKDW�ZLOO�KDYH�WKH�LQVWDOODWLRQ�LQVWUXFWLRQV�DSSURSULDWH�IRU�\RXU�V\VWHP�DQG�LQVWDOODWLRQ�RI�3HUO�

® 7KH�£�SP¤�ILOH�H[WHQVLRQ�VWDQGV�IRU�£3HUO�0RGXOH�¤�DQG�VRPH�SRSXODU�PRGXOHV�DUH�SURQRXQFHG�ZLWK�WKH£�SP¤�WR�GLVWLQJXLVK�WKHP�IURP�VRPHWKLQJ�HOVH��,Q�WKLV�FDVH��&3$1�WKH�DUFKLYH�LV�GLIIHUHQW�WKDQ�&3$1�WKHPRGXOH��VR�WKH�ODWWHU�LV�VDLG�£CPAN.pm�¤

170 | Chapter 11:ಗPerl Modules

<RX�PLJKW�EH�VD\LQJ��£%XW�,�GRQ¦W�KDYH�D�FRPPDQG�OLQH�¤�,I�\RX�DUH�XVLQJ�WKH�$FWLYH6WDWHSRUW�RI�3HUO��IRU�:LQGRZV��/LQX[��RU�6RODULV���\RX�FDQ�XVH�WKH�3HUO�3DFNDJH�0DQDJHU�330�� �ZKLFK�LQVWDOOV�PRGXOHV�IRU�\RX��<RX�FDQ�HYHQ�JHW�WKH�$FWLYH6WDWH�SRUWV�RQ�&'RU�'9'���%HVLGHV�ZKDW�\RX¦YH�VHHQ�VR�IDU��\RXU�SDUWLFXODU�RSHUDWLQJ�V\VWHP�PD\�KDYHZD\V�WR�LQVWDOO�VRIWZDUH��LQFOXGLQJ�3HUO�PRGXOHV�

Using Simple Modules6XSSRVH�WKDW�\RX¦YH�JRW�D�ORQJ�ILOHQDPH�OLNH��XVU�ORFDO�ELQ�SHUO�LQ�\RXU�SURJUDP��DQG\RX�QHHG�WR�ILQG�RXW�WKH�EDVHQDPH��7KDW¦V�HDV\�HQRXJK��VLQFH�WKH�EDVHQDPH�LV�HYHU\WKLQJDIWHU�WKH�ODVW�VODVK��LW¦V�MXVW�SHUO�LQ�WKLV�FDVH��

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

$V�\RX�VDZ�HDUOLHU��ILUVW�3HUO�ZLOO�GR�WKH�DVVLJQPHQW�LQVLGH�WKH�SDUHQWKHVHV��WKHQ�LW�ZLOOGR�WKH�VXEVWLWXWLRQ��7KH�VXEVWLWXWLRQ�LV�VXSSRVHG�WR�UHSODFH�DQ\�VWULQJ�HQGLQJ�ZLWK�DVODVK� �WKDW� LV�� WKH� GLUHFWRU\� QDPH� SRUWLRQ�� ZLWK� DQ� HPSW\� VWULQJ�� OHDYLQJ� MXVW� WKHEDVHQDPH�

$QG�LI�\RX�WU\�WKLV��LW�VHHPV�WR�ZRUN��:HOO��LW�VHHPV�WR��EXW�DFWXDOO\��WKHUH�DUH�WKUHHSUREOHPV�

)LUVW��D�8QL[�ILOH�RU�GLUHFWRU\�QDPH�FRXOG�FRQWDLQ�D�QHZOLQH�FKDUDFWHU���,W¦V�QRW�VRPH�WKLQJ�WKDW¦V�OLNHO\�WR�KDSSHQ�E\�DFFLGHQW��EXW�LW¦V�SHUPLWWHG���6R��VLQFH�WKH�UHJXODU�H[�SUHVVLRQ�GRW��.��FDQ¦W�PDWFK�D�QHZOLQH��D�ILOHQDPH�OLNH�WKH�VWULQJ�"/home/fred/flintstone\n/brontosaurus"� ZRQ¦W� ZRUN� ULJKW¢WKDW� FRGH� ZRXOG� WKLQN� WKH� EDVHQDPH� LV"flintstone\n/brontosaurus"��<RX�FRXOG�IL[�WKDW�ZLWK�WKH�/s�RSWLRQ�WR�WKH�SDWWHUQ��LI\RX�UHPHPEHUHG�DERXW�WKLV�VXEWOH�DQG�LQIUHTXHQW�FDVH���PDNLQJ�WKH�VXEVWLWXWLRQ�ORRNOLNH�WKLV��s#.*/##s��7KH�VHFRQG�SUREOHP�LV�WKDW�WKLV�LV�8QL[�VSHFLILF��,W�DVVXPHV�WKDW�WKHIRUZDUG�VODVK�ZLOO�DOZD\V�EH�WKH�GLUHFWRU\�VHSDUDWRU��DV�LW�LV�RQ�8QL[��DQG�QRW�WKH�EDFN�VODVK�RU�FRORQ�WKDW�VRPH�V\VWHPV�XVH�

$QG�WKH�WKLUG��DQG�ELJJHVW��SUREOHP�ZLWK�WKLV�LV�WKDW�ZH¦UH�WU\LQJ�WR�VROYH�D�SUREOHPWKDW�VRPHRQH�HOVH�KDV�DOUHDG\�VROYHG��3HUO�FRPHV�ZLWK�D�QXPEHU�RI�PRGXOHV��ZKLFK�DUHVPDUW�H[WHQVLRQV�WR�3HUO�WKDW�DGG�WR�LWV�IXQFWLRQDOLW\��$QG�LI�WKRVH�DUHQ¦W�HQRXJK��WKHUHDUH�PDQ\�RWKHU�XVHIXO�PRGXOHV�DYDLODEOH�RQ�&3$1��ZLWK�QHZ�RQHV�EHLQJ�DGGHG�HYHU\ZHHN��<RX��RU��EHWWHU�\HW��\RXU�V\VWHP�DGPLQLVWUDWRU��FDQ�LQVWDOO�WKHP�LI�\RX�QHHG�WKHLUIXQFWLRQDOLW\�

KWWS���DVSQ�DFWLYHVWDWH�FRP�$631�GRFV�$FWLYH3HUO�IDT�$FWLYH3HUO�IDT��KWPO

� <RX�FDQ�PDNH�\RXU�RZQ�&'V�RU�'9'V�WRR�E\�FUHDWLQJ�D�ORFDO�UHSRVLWRU\��(YHQ�WKRXJK�&3$1�LV�DOPRVW���*%E\�QRZ��D�£PLQLFSDQ¤��DJDLQ��E\�RQH�RI�WKH�DXWKRUV��SDUHV�LW�GRZQ�WR�MXVW�WKH�ODWHVW�YHUVLRQV�RI�HYHU\WKLQJ�ZKLFK�LV�DERXW�����0%��6HH�WKH�CPAN::Mini�PRGXOH�

Using Simple Modules | 171

,Q�WKH�UHVW�RI�WKLV�VHFWLRQ��ZH¦OO�VKRZ�\RX�KRZ�WR�XVH�VRPH�RI�WKH�IHDWXUHV�RI�D�FRXSOHRI�VLPSOH�PRGXOHV�WKDW�FRPH�ZLWK�3HUO���7KHUH¦V�PRUH�WKDW�WKHVH�PRGXOHV�FDQ�GR��WKLVLV�MXVW�DQ�RYHUYLHZ�WR�LOOXVWUDWH�WKH�JHQHUDO�SULQFLSOHV�RI�KRZ�WR�XVH�D�VLPSOH�PRGXOH��

$ODV��ZH�FDQ¦W�VKRZ�\RX�HYHU\WKLQJ�\RX¦G�QHHG�WR�NQRZ�DERXW�XVLQJ�PRGXOHV�LQ�JHQHUDO�VLQFH�\RX¦G�KDYH�WR�XQGHUVWDQG�DGYDQFHG�WRSLFV�OLNH�UHIHUHQFHV�DQG�REMHFWV�LQ�RUGHU�WRXVH�VRPH�PRGXOHV� �7KRVH�WRSLFV��LQFOXGLQJ�KRZ�WR�FUHDWH�D�PRGXOH��DUH�FRYHUHG�LQJUHDW�GHWDLO�LQ�WKH�$OSDFD��%XW�WKLV�VHFWLRQ�VKRXOG�SUHSDUH�\RX�IRU�XVLQJ�PDQ\�VLPSOHPRGXOHV��)XUWKHU�LQIRUPDWLRQ�RQ�VRPH�LQWHUHVWLQJ�DQG�XVHIXO�PRGXOHV�LV�LQFOXGHG�LQ$SSHQGL[�%�

The File::Basename Module,Q� WKH�SUHYLRXV�H[DPSOH��ZH� IRXQG�WKH�EDVHQDPH�RI�D� ILOHQDPH� LQ�D�ZD\� WKDW¦V�QRWSRUWDEOH��:H�VKRZHG�WKDW�VRPHWKLQJ�WKDW�VHHPHG�VWUDLJKWIRUZDUG�ZDV�VXVFHSWLEOH�WRVXEWOH�PLVWDNHQ�DVVXPSWLRQV� �KHUH�� WKH�DVVXPSWLRQ�ZDV� WKDW�QHZOLQHV�ZRXOG�QHYHUDSSHDU�LQ�ILOH�RU�GLUHFWRU\�QDPHV���$QG�ZH�ZHUH�UHLQYHQWLQJ�WKH�ZKHHO��VROYLQJ�D�SURE�OHP�WKDW�RWKHUV�KDYH�VROYHG��DQG�GHEXJJHG��PDQ\�WLPHV�EHIRUH�XV�

+HUH¦V�D�EHWWHU�ZD\�WR�H[WUDFW�WKH�EDVHQDPH�RI�D�ILOHQDPH��3HUO�FRPHV�ZLWK�D�PRGXOHFDOOHG�File::Basename��:LWK�WKH�FRPPDQG�SHUOGRF�)LOH��%DVHQDPH��RU�ZLWK�\RXU�V\V�WHP¦V�GRFXPHQWDWLRQ�V\VWHP��\RX�FDQ�UHDG�DERXW�ZKDW�LW�GRHV��7KDW¦V�WKH�ILUVW�VWHSZKHQ�XVLQJ�D�QHZ�PRGXOH���,W¦V�RIWHQ�WKH�WKLUG�DQG�ILIWK�VWHSV��DV�ZHOO��

6RRQ�\RX¦UH�UHDG\�WR�XVH�LW��VR�\RX�GHFODUH�LW�ZLWK�D�use�GLUHFWLYH�QHDU�WKH�WRS�RI�\RXUSURJUDP��

use File::Basename

'XULQJ�FRPSLODWLRQ��3HUO�VHHV�WKDW�OLQH�DQG�ORDGV�XS�WKH�PRGXOH��1RZ��LW¦V�DV�LI�3HUOKDV�VRPH�QHZ�IXQFWLRQV�WKDW�\RX�PD\�XVH�LQ�WKH�UHPDLQGHU�RI�\RXU�SURJUDP�®�7KH�RQHZH�ZDQWHG�LQ�WKH�HDUOLHU�H[DPSOH�LV�WKH�basename�IXQFWLRQ�LWVHOI�

my $name = "/usr/local/bin/perl";my $basename = basename $name; # gives 'perl'

:HOO��WKDW�ZRUNHG�IRU�8QL[��:KDW�LI�RXU�SURJUDP�ZHUH�UXQQLQJ�RQ�0DF3HUO�RU�:LQGRZVRU�906�� WR�QDPH� D� IHZ"�7KHUH¦V� QR�SUREOHP¢WKLV�PRGXOH� FDQ� WHOO�ZKLFK�NLQG�RI

$V�ZH¦OO�VHH�LQ�WKH�QH[W�IHZ�SDJHV��WKRXJK��\RX�PD\�EH�DEOH�WR�XVH�D�PRGXOH�WKDW�XVHV�REMHFWV�DQG�UHIHUHQFHVZLWKRXW�KDYLQJ�WR�XQGHUVWDQG�WKRVH�DGYDQFHG�WRSLFV�

� ,W¦V� WUDGLWLRQDO� WR�GHFODUH�PRGXOHV�QHDU� WKH� WRS�RI� WKH� ILOH�� VLQFH� WKDW�PDNHV� LW� HDV\� IRU� WKH�PDLQWHQDQFHSURJUDPPHU�WR�VHH�ZKLFK�PRGXOHV�\RX¦OO�EH�XVLQJ��7KDW�JUHDWO\�VLPSOLILHV�PDWWHUV�ZKHQ�LW¦V�WLPH�WR�LQVWDOO\RXU�SURJUDP�RQ�D�QHZ�PDFKLQH��IRU�H[DPSOH�

® <RX�JXHVVHG�LW��WKHUH¦V�PRUH�WR�WKH�VWRU\��KDYLQJ�WR�GR�ZLWK�SDFNDJHV�DQG�IXOO\�TXDOLILHG�QDPHV��:KHQ�\RXUSURJUDPV�DUH�JURZLQJ�EH\RQG�D�IHZ�KXQGUHG�OLQHV�LQ�WKH�PDLQ�SURJUDP��QRW�FRXQWLQJ�FRGH�LQ�PRGXOHV��ZKLFK� LV�TXLWH� ODUJH� LQ�3HUO�� \RX� VKRXOG�SUREDEO\� UHDG�XS�DERXW� WKHVH�DGYDQFHG� IHDWXUHV��6WDUW�ZLWK� WKHSHUOPRG�PDQSDJH�

172 | Chapter 11:ಗPerl Modules

PDFKLQH�\RX¦UH�XVLQJ��DQG�LW�XVHV�WKDW�PDFKLQH¦V�ILOHQDPH�UXOHV�E\�GHIDXOW���2I�FRXUVH�\RX¦G�KDYH�WKDW�PDFKLQH¦V�NLQG�RI�ILOHQDPH�VWULQJ�LQ�$name��LQ�WKDW�FDVH��

7KHUH�DUH�VRPH�UHODWHG� IXQFWLRQV�DOVR�SURYLGHG�E\�WKLV�PRGXOH��2QH� LV� WKH�dirnameIXQFWLRQ��ZKLFK�SXOOV�WKH�GLUHFWRU\�QDPH�IURP�D�IXOO�ILOHQDPH��7KH�PRGXOH�DOVR�OHWV�\RXVHSDUDWH�D�ILOHQDPH�IURP�LWV�H[WHQVLRQ��RU�FKDQJH�WKH�GHIDXOW�VHW�RI�ILOHQDPH�UXOHV�

Using Only Some Functions from a Module6XSSRVH�\RX�GLVFRYHUHG�WKDW�ZKHQ�\RX�ZHQW�WR�DGG�WKH�File::Basename�PRGXOH�WR�\RXUH[LVWLQJ�SURJUDP��\RX�DOUHDG\�KDYH�D�VXEURXWLQH�FDOOHG�&dirname¢WKDW�LV��\RX�DOUHDG\KDYH�D�VXEURXWLQH�ZLWK�WKH�VDPH�QDPH�DV�RQH�RI�WKH�PRGXOH¦V�IXQFWLRQV���1RZ�WKHUH¦VWURXEOH�EHFDXVH�WKH�QHZ�dirname�LV�DOVR�LPSOHPHQWHG�DV�D�3HUO�VXEURXWLQH��LQVLGH�WKHPRGXOH���:KDW�GR�\RX�GR"

6LPSO\�JLYH�File::Basename�� LQ�\RXU�use�GHFODUDWLRQ��DQ� LPSRUW� OLVW� VKRZLQJ�H[DFWO\ZKLFK�IXQFWLRQ�QDPHV�LW�VKRXOG�JLYH�\RX��DQG�LW¦OO�VXSSO\�WKRVH�DQG�QR�RWKHUV��+HUH�ZH¦OO�JHW�QRWKLQJ�EXW�basename�

use File::Basename qw/ basename /;

$QG�KHUH��ZH¦OO�DVN�IRU�QR�QHZ�IXQFWLRQV�DW�DOO�

use File::Basename qw/ /;

7KLV�LV�DOVR�IUHTXHQWO\�ZULWWHQ�DV�

use File::Basename ();

:K\�ZRXOG� \RX�ZDQW� WR� GR� WKDW"�:HOO�� WKLV� GLUHFWLYH� WHOOV� 3HUO� WR� ORDG� File::Basename��MXVW�DV�EHIRUH��EXW�QRW�WR�LPSRUW�DQ\�IXQFWLRQ�QDPHV��,PSRUWLQJ�OHWV�XV�XVH�WKHVKRUW��VLPSOH�IXQFWLRQ�QDPHV�OLNH�basename�DQG�dirname��%XW�HYHQ�LI�ZH�GRQ¦W�LPSRUWWKRVH�QDPHV��ZH�FDQ�VWLOO�XVH�WKH�IXQFWLRQV��:KHQ�WKH\¦UH�QRW�LPSRUWHG��WKRXJK��ZHKDYH�WR�FDOO�WKHP�E\�WKHLU�IXOO�QDPHV�

use File::Basename qw/ /; # import no function names

my $betty = &dirname($wilma); # uses our own subroutine &dirname #(not shown)

my $name = "/usr/local/bin/perl";my $dirname = File::Basename::dirname $name; # dirname from the module

<RX�PLJKW�QHHG�WR�FKDQJH�WKH�ILOHQDPH�UXOHV�LI�\RX�ZHUH�WU\LQJ�WR�ZRUN�ZLWK�D�8QL[�PDFKLQH¦V�ILOHQDPHVIURP�D�:LQGRZV�PDFKLQH¢SHUKDSV�ZKLOH�VHQGLQJ�FRPPDQGV�RYHU�DQ�)73�FRQQHFWLRQ��IRU�H[DPSOH�

� :HOO��LW¦V�QRW�OLNHO\�WKDW�\RX�ZRXOG�DOUHDG\�KDYH�D�&dirname�VXEURXWLQH�WKDW�\RX�XVH�IRU�DQRWKHU�SXUSRVH��EXWWKLV�LV�MXVW�DQ�H[DPSOH��6RPH�PRGXOHV�RIIHU�KXQGUHGV��UHDOO\���RI�QHZ�IXQFWLRQV��PDNLQJ�D�QDPH�FROOLVLRQWKDW�PXFK�PRUH�IUHTXHQW�

Using Simple Modules | 173

$V�\RX�FDQ�VHH��WKH�IXOO�QDPH�RI�WKH�dirname�IXQFWLRQ�IURP�WKH�PRGXOH�LV�File::Basename::dirname��:H�FDQ�DOZD\V�XVH� WKH� IXQFWLRQ¦V� IXOO�QDPH��RQFH�ZH¦YH� ORDGHG� WKHPRGXOH��ZKHWKHU�ZH¦YH�LPSRUWHG�WKH�VKRUW�QDPH�dirname�RU�QRW�

0RVW�RI�WKH�WLPH��\RX¦OO�ZDQW�WR�XVH�D�PRGXOH¦V�GHIDXOW�LPSRUW�OLVW��%XW�\RX�FDQ�DOZD\VRYHUULGH�WKDW�ZLWK�D�OLVW�RI�\RXU�RZQ�LI�\RX�ZDQW�WR�OHDYH�RXW�VRPH�RI�WKH�GHIDXOW�LWHPV�$QRWKHU�UHDVRQ�WR�VXSSO\�\RXU�RZQ�OLVW�ZRXOG�EH�LI�\RX�ZDQWHG�WR�LPSRUW�VRPH�IXQFWLRQQRW�RQ�WKH�GHIDXOW�OLVW��VLQFH�PRVW�PRGXOHV�LQFOXGH�VRPH��LQIUHTXHQWO\�QHHGHG��IXQF�WLRQV�WKDW�DUH�QRW�RQ�WKH�GHIDXOW�LPSRUW�OLVW�

$V�\RX¦G�JXHVV��VRPH�PRGXOHV�ZLOO��E\�GHIDXOW��LPSRUW�PRUH�V\PEROV�WKDQ�RWKHUV��(DFKPRGXOH¦V�GRFXPHQWDWLRQ�VKRXOG�PDNH�LW�FOHDU�ZKLFK�V\PEROV�LW�LPSRUWV��LI�DQ\��EXW\RX�DUH�DOZD\V�IUHH�WR�RYHUULGH�WKH�GHIDXOW�LPSRUW�OLVW�E\�VSHFLI\LQJ�RQH�RI�\RXU�RZQ�MXVW�DV�ZH�GLG�ZLWK�File::Basename��6XSSO\LQJ�DQ�HPSW\�OLVW�LPSRUWV�QR�V\PEROV�

The File::Spec Module1RZ�\RX�FDQ�ILQG�RXW�D�ILOH¦V�EDVHQDPH��7KDW¦V�XVHIXO��EXW�\RX¦OO�RIWHQ�ZDQW�WR�SXW�WKDWWRJHWKHU�ZLWK�D�GLUHFWRU\�QDPH�WR�JHW�D�IXOO�ILOHQDPH��)RU�H[DPSOH��KHUH�ZH�ZDQW�WR�WDNHD�ILOHQDPH�OLNH��KRPH�URRWEHHU�LFH�����W[W�DQG�DGG�D�SUHIL[�WR�WKH�EDVHQDPH�

use File::Basename;

print "Please enter a filename: ";chomp(my $old_name = <STDIN>);

my $dirname = dirname $old_name;my $basename = basename $old_name;

$basename =~ s/^/not/; # Add a prefix to the basenamemy $new_name = "$dirname/$basename";

rename($old_name, $new_name) or warn "Can't rename '$old_name' to '$new_name': $!";

'R�\RX�VHH�WKH�SUREOHP�KHUH"�2QFH�DJDLQ��ZH¦UH�PDNLQJ�WKH�DVVXPSWLRQ�WKDW�ILOHQDPHVZLOO�IROORZ�WKH�8QL[�FRQYHQWLRQV�DQG�XVH�D�IRUZDUG�VODVK�EHWZHHQ�WKH�GLUHFWRU\�QDPHDQG�WKH�EDVHQDPH��)RUWXQDWHO\��3HUO�FRPHV�ZLWK�D�PRGXOH�WR�KHOS�ZLWK�WKLV�SUREOHP�WRR�

7KH�File::Spec�PRGXOH�LV�XVHG�IRU�PDQLSXODWLQJ�ILOH�VSHFLILFDWLRQV��ZKLFK�DUH�WKH�QDPHVRI�ILOHV��GLUHFWRULHV��DQG�WKH�RWKHU�WKLQJV�WKDW�DUH�VWRUHG�RQ�ILOHV\VWHPV��/LNH�File::Basename��LW�XQGHUVWDQGV�ZKDW�NLQG�RI�V\VWHP�LW¦V�UXQQLQJ�RQ��DQG�LW�FKRRVHV�WKH�ULJKW�VHWRI�UXOHV�HYHU\�WLPH��%XW�XQOLNH�File::Basename��File::Spec�LV�DQ�REMHFW�RULHQWHG��RIWHQDEEUHYLDWHG�22��PRGXOH�

,I�\RX¦YH�QHYHU�FDXJKW�WKH�IHYHU�RI�22��GRQ¦W�OHW�WKDW�ERWKHU�\RX��,I�\RX�XQGHUVWDQGREMHFWV��WKDW¦V�JUHDW��\RX�FDQ�XVH�WKLV�22�PRGXOH��,I�\RX�GRQ¦W�XQGHUVWDQG�REMHFWV�WKDW¦V�RND\��WRR��<RX�MXVW�W\SH�WKH�V\PEROV�DV�ZH�VKRZ�\RX��DQG�LW�ZRUNV�MXVW�DV�LI�\RXNQHZ�ZKDW�\RX�ZHUH�GRLQJ�

174 | Chapter 11:ಗPerl Modules

,Q�WKLV�FDVH��ZH�OHDUQ�IURP�UHDGLQJ�WKH�GRFXPHQWDWLRQ�IRU�File::Spec�WKDW�ZH�ZDQW�WRXVH�D�PHWKRG�FDOOHG�catfile��:KDW¦V�D�PHWKRG"�,W¦V�MXVW�D�GLIIHUHQW�NLQG�RI�IXQFWLRQ��DVIDU�DV�ZH¦UH�FRQFHUQHG�KHUH��7KH�GLIIHUHQFH�LV�WKDW�\RX¦OO�DOZD\V�FDOO�WKH�PHWKRGV�IURPFile::Spec�ZLWK�WKHLU�IXOO�QDPHV��OLNH�WKLV�

use File::Spec;

.

. # Get the values for $dirname and $basename as above

.

my $new_name = File::Spec->catfile($dirname, $basename);

rename($old_name, $new_name) or warn "Can't rename '$old_name' to '$new_name': $!";

$V�\RX�FDQ�VHH��WKH�IXOO�QDPH�RI�D�PHWKRG�LV�WKH�QDPH�RI�WKH�PRGXOH��FDOOHG�D�FODVVKHUH���D�VPDOO�DUURZ��->��DQG�WKH�VKRUW�QDPH�RI�WKH�PHWKRG��,W�LV�LPSRUWDQW�WR�XVH�WKHVPDOO�DUURZ��UDWKHU�WKDQ�WKH�GRXEOH�FRORQ�ZH�XVHG�ZLWK�moreinfo="none">File::Basename�

6LQFH�ZH¦UH�FDOOLQJ�WKH�PHWKRG�E\�LWV�IXOO�QDPH��WKRXJK��ZKDW�V\PEROV�GRHV�WKH�PRGXOHLPSRUW"�1RQH�RI�WKHP��7KDW¦V�QRUPDO�IRU�22�PRGXOHV��6R�\RX�GRQ¦W�KDYH�WR�ZRUU\DERXW� KDYLQJ� D� VXEURXWLQH� ZLWK� WKH� VDPH� QDPH� DV� RQH� RI� WKH� PDQ\� PHWKRGV� RIFile::Spec�

6KRXOG�\RX�ERWKHU�XVLQJ�PRGXOHV�OLNH�WKHVH"�,W¦V�XS�WR�\RX��DV�DOZD\V��,I�\RX¦UH�VXUH\RXU�SURJUDP�ZLOO�QHYHU�EH�UXQ�DQ\ZKHUH�EXW�RQ�D�8QL[�PDFKLQH��VD\��DQG�\RX¦UH�VXUH\RX�FRPSOHWHO\�XQGHUVWDQG�WKH�UXOHV�IRU�ILOHQDPHV�RQ�8QL[� �WKHQ�\RX�PD\�SUHIHU�WRKDUGFRGH�\RXU�DVVXPSWLRQV�LQWR�\RXU�SURJUDPV��%XW�WKHVH�PRGXOHV�JLYH�\RX�DQ�HDV\ZD\�WR�PDNH�\RXU�SURJUDPV�PRUH�UREXVW�LQ�OHVV�WLPH¢DQG�PRUH�SRUWDEOH�DW�QR�H[WUDFKDUJH�

CGI.pm,I� \RX� QHHG� WR� FUHDWH�&*,� SURJUDPV� �ZKLFK�ZH� GRQ¦W� FRYHU� LQ� WKLV� ERRN��� XVH� WKHCGI.pm�PRGXOH���8QOHVV�\RX�UHDOO\�NQRZ�ZKDW�\RX�DUH�GRLQJ��DQG�VRPHWLPHV�HYHQ�WKHQ��\RX�GRQ¦W�QHHG�WR�KDQGOH�WKH�DFWXDO�LQWHUIDFH�DQG�LQSXW�SDUVLQJ�SRUWLRQ�RI�WKH�VFULSW�ZKLFK�JHWV�VR�PDQ\�RWKHU�SHRSOH�LQWR�WURXEOH��7KH�CGI.pm�DXWKRU��/LQFROQ�6WHLQ��VSHQWD�ORW�RI�WLPH�HQVXULQJ�WKDW�WKH�PRGXOH�ZRXOG�ZRUN�ZLWK�PRVW�VHUYHUV�DQG�RSHUDWLQJV\VWHPV��-XVW�XVH�WKH�PRGXOH�DQG�IRFXV�RQ�WKH�LQWHUHVWLQJ�SDUWV�RI�\RXU�VFULSW�

7KH�&*,�PRGXOH�KDV�WZR�IODYRUV�� WKH�SODLQ�ROG�IXQFWLRQDO� LQWHUIDFH�DQG�WKH�REMHFW�RULHQWHG�LQWHUIDFH��:H¦OO�XVH�WKH�ILUVW�RQH��$V�EHIRUH��\RX�FDQ�IROORZ�WKH�H[DPSOHV�LQ

,I�\RX�GLGQ¦W�NQRZ�WKDW�ILOHQDPHV�DQG�GLUHFWRU\�QDPHV�FRXOG�FRQWDLQ�QHZOLQH�FKDUDFWHUV��DV�ZH�PHQWLRQHGHDUOLHU�LQ�WKLV�VHFWLRQ��WKHQ�\RX�GRQ¦W�NQRZ�DOO�WKH�UXOHV��GR�\RX"

� $V�ZLWK�WKH�CPAN.pm�PRGXOH��ZH�SURQRXQFH�WKH�£�SP¤�LQ�CGI.pm�WR�GLVWLQJXLVK�LW�IURP�WKH�SURWRFRO�LWVHOI�

Using Simple Modules | 175

WKH�CGI.pm�GRFXPHQWDWLRQ��2XU�VLPSOH�&*,�VFULSW�SDUVHV�WKH�&*,�LQSXW�DQG�GLVSOD\VWKH�LQSXW�QDPHV�DQG�YDOXHV�DV�D�SODLQ�WH[W�GRFXPHQW��,Q�WKH�LPSRUW�OLVW��ZH�XVH�:all�ZKLFK�LV�DQ�H[SRUW�WDJ�WKDW�VSHFLILHV�D�JURXS�RI�IXQFWLRQV�UDWKHU�WKDQ�D�VLQJOH�IXQFWLRQOLNH�\RX�VDZ�ZLWK�WKH�SUHYLRXV�PRGXOHV�

#!/usr/bin/perl

use CGI qw(:all);

print header("text/plain");

foreach my $param ( param() ) { print "$param: " . param($param) . "\n"; }

:H�FDQ�JHW�IDQFLHU�WKRXJK�EHFDXVH�ZH�ZDQW�WR�RXWSXW�+70/��DQG�CGI.pm�KDV�PDQ\�PDQ\�FRQYHQLHQFH�IXQFWLRQV�WR�GR�WKDW��,W�KDQGOHV�WKH�&*,�KHDGHU��WKH�EHJLQQLQJ�SDUWVRI�+70/�ZLWK�start_html()��DQG�PDQ\�RI�WKH�+70/�WDJV�ZLWK�IXQFWLRQV�RI�WKH�VDPHQDPH��OLNH�h1()�IRU�WKH�H1�WDJ�

#!/usr/bin/perl

use CGI qw(:all);

print header(), start_html("This is the page title"), h1( "Input parameters" );

my $list_items;foreach my $param ( param() ) { $list_items .= li( "$param: " . param($param) ); }

print ul( $list_items );

print end_html();

:DVQ¦W�WKDW�HDV\"�<RX�GRQ¦W�KDYH�WR�NQRZ�KRZ�CGI.pm�LV�GRLQJ�DOO�WKLV�VWXII��\RX�MXVWKDYH�WR�WUXVW�WKDW�LW�GRHV�LW�FRUUHFWO\��2QFH�\RX�OHW�CGI.pm�GR�DOO�WKH�KDUG�ZRUN��\RX�JHWWR�IRFXV�RQ�WKH�LQWHUHVWLQJ�SDUWV�RI�\RXU�SURJUDP�

7KH�CGI.pm PRGXOH�GRHV� D� ORW�PRUH�� LW� FDQ�KDQGOH� FRRNLHV�� UHGLUHFWLRQ��PXOWLSDJHIRUPV��DQG�D�ORW�PRUH��:H�GRQ¦W�KDYH�URRP�WR�FRYHU�LW�KHUH��EXW�\RX¦OO�OHDUQ�PRUH�IURPWKH�H[DPSOHV�LQ�WKH�PRGXOH�GRFXPHQWDWLRQ�

7KH�PRGXOH�KDV�VHYHUDO�RWKHU�H[SRUW�WDJV�WR�VHOHFW�GLIIHUHQW�JURXSV�RI�IXQFWLRQV��)RU�LQVWDQFH��LI�\RX�ZDQWWKH�RQHV�WKDW�GHDO�ZLWK�MXVW�WKH�&*,��\RX�FDQ�XVH�:cgi��RU�LI�\RX�MXVW�ZDQW�WKH�+70/�JHQHUDWLRQ�IXQFWLRQV�\RX�FDQ�XVH�:html4��6HH�WKH�CGI.pm�GRFXPHQWDWLRQ�IRU�PRUH�GHWDLOV�

176 | Chapter 11:ಗPerl Modules

Databases and DBI7KH��'%,��'DWDEDVH�,QWHUIDFH��PRGXOH�GRHVQ¦W�FRPH�ZLWK�3HUO��EXW�LW¦V�RQH�RI�WKH�PRVWSRSXODU�PRGXOHV�VLQFH�PRVW�SHRSOH�KDYH�WR�FRQQHFW�WR�D�GDWDEDVH�RI�VRPH�VRUW��7KHEHDXW\�RI�'%,�LV�WKDW�LW�DOORZV�\RX�WR�XVH�WKH�VDPH�LQWHUIDFH�IRU�MXVW�DERXW�DQ\�FRPPRQGDWDEDVH��IURP�VLPSOH�FRPPD�VHSDUDWHG�YDOXH�ILOHV�WR�ELJ�GDWDEDVH�VHUYHUV�OLNH�2UDFOH�,W�KDV�2'%&�GULYHUV��DQG�VRPH�RI�LWV�GULYHUV�DUH�HYHQ�YHQGRU�VXSSRUWHG��7R�JHW�WKH�IXOOGHWDLOV��JHW�3URJUDPPLQJ�WKH�3HUO�'%,�E\�$OOLJDWRU�'HVFDUWHV�DQG�7LP�%XQFH��2¦5HLOO\��<RX�FDQ�DOVR�FKHFN�RXW�WKH�'%,�ZHE�VLWH�DW�KWWS���GEL�SHUO�RUJ��

2QFH�\RX�LQVWDOO�'%,��\RX�DOVR�KDYH�WR�LQVWDOO�D�'%'��'DWDEDVH�'ULYHU���<RX�FDQ�JHW�DORQJ�OLVW�RI�'%'V�IURP�&3$1�6HDUFK��,QVWDOO�WKH�ULJKW�RQH�IRU�\RXU�GDWDEDVH�VHUYHU��DQGHQVXUH�WKDW�\RX�JHW�WKH�YHUVLRQ�WKDW�JRHV�ZLWK�WKH�YHUVLRQ�RI�\RXU�VHUYHU�

7KH�'%,�LV�DQ�REMHFW�RULHQWHG�PRGXOH��EXW�\RX�GRQ¦W�KDYH�WR�NQRZ�HYHU\WKLQJ�DERXW22�SURJUDPPLQJ�WR�XVH�LW��<RX�MXVW�KDYH�WR�IROORZ�WKH�H[DPSOHV�LQ�WKH�GRFXPHQWDWLRQ�7R�FRQQHFW�WR�D�GDWDEDVH��\RX�use�WKH�'%,�PRGXOH��WKHQ�FDOO�LWV�connect�PHWKRG�

use DBI;

$dbh = DBI->connect($data_source, $username, $password);

7KH�$data_source�FRQWDLQV�LQIRUPDWLRQ�SDUWLFXODU�WR�WKH�'%'�WKDW�\RX�ZDQW�WR�XVH��VR\RX¦OO� JHW� WKDW� IURP� WKH� '%'�� )RU� 3RVWJUH64/�� WKH� GULYHU� LV� DBD::Pg�� DQG� WKH$data_source�LV�VRPHWKLQJ�OLNH�

my $data_source = "dbi:Pg:dbname=name_of_database";

2QFH�\RX�FRQQHFW�WR�WKH�GDWDEDVH��\RX�JR�WKURXJK�D�F\FOH�RI�SUHSDULQJ��H[HFXWLQJ��DQGUHDGLQJ�TXHULHV�

$sth = $dbh->prepare("SELECT * FROM foo WHERE bla");$sth->execute();@row_ary = $sth->fetchrow_array;$sth->finish;

:KHQ�\RX�DUH�ILQLVKHG��\RX�GLVFRQQHFW�IURP�WKH�GDWDEDVH�

$dbh->disconnect();

7KHUH�DUH�DOO�VRUWV�RI�RWKHU�WKLQJV�WKDW�WKH�'%,�FDQ�GR�WRR��6HH�LWV�GRFXPHQWDWLRQ�IRUPRUH�GHWDLOV�

Exercise6HH�$SSHQGL[�$�IRU�WKH�DQVZHU�WR�WKH�IROORZLQJ�H[HUFLVH�

�� >��@�,QVWDOO�WKH�Module::CoreList�PRGXOH�IURP�&3$1��3ULQW�D�OLVW�RI�DOO�RI�WKH�PRG�XOHV�WKDW�FDPH�ZLWK�3HUO��������7R�EXLOG�D�KDVK�ZKRVH�NH\V�DUH�WKH�QDPHV�RI�WKHPRGXOHV�WKDW�FDPH�ZLWK�D�JLYHQ�YHUVLRQ�RI�3HUO��XVH�WKLV�OLQH�

my %modules = %{ $Module::CoreList::version{5.008} };

Exercise | 177

CHAPTER 12

File Tests

(DUOLHU��ZH�VKRZHG�KRZ�WR�RSHQ�D�ILOHKDQGOH�IRU�RXWSXW��1RUPDOO\��WKDW�ZLOO�FUHDWH�DQHZ�ILOH��ZLSLQJ�RXW�DQ\�H[LVWLQJ�ILOH�ZLWK�WKH�VDPH�QDPH��3HUKDSV�\RX�ZDQW�WR�FKHFNWKDW�WKHUH�LVQ¦W�D�ILOH�E\�WKDW�QDPH��3HUKDSV�\RX�QHHG�WR�NQRZ�KRZ�ROG�D�JLYHQ�ILOH�LV�2U�SHUKDSV�\RX�ZDQW�WR�JR�WKURXJK�D�OLVW�RI�ILOHV�WR�ILQG�ZKLFK�RQHV�DUH�ODUJHU�WKDQ�DFHUWDLQ�QXPEHU�RI�E\WHV�DQG�QRW�DFFHVVHG�IRU�D�FHUWDLQ�DPRXQW�RI�WLPH��3HUO�KDV�D�FRP�SOHWH�VHW�RI�WHVWV�\RX�FDQ�XVH�WR�ILQG�RXW�LQIRUPDWLRQ�DERXW�ILOHV�

File Test Operators%HIRUH�ZH�VWDUW�D�SURJUDP�WKDW�FUHDWHV�D�QHZ�ILOH��OHW¦V�PDNH�VXUH�WKDW�WKH�ILOH�GRHVQ¦WDOUHDG\�H[LVW�VR�WKDW�ZH�GRQ¦W�DFFLGHQWDOO\�RYHUZULWH�D�YLWDO�VSUHDGVKHHW�GDWDILOH�RU�WKDWLPSRUWDQW�ELUWKGD\�FDOHQGDU��)RU� WKLV��ZH�XVH� WKH�-e� ILOH� WHVW�� WHVWLQJ�D� ILOHQDPH�IRUH[LVWHQFH�

die "Oops! A file called '$filename' already exists.\n" if -e $filename;

1RWLFH�WKDW�ZH�GRQ¦W�LQFOXGH�$!�LQ�WKLV�die�PHVVDJH��VLQFH�ZH¦UH�QRW�UHSRUWLQJ�WKDW�WKHV\VWHP�UHIXVHG�D�UHTXHVW�LQ�WKLV�FDVH��+HUH¦V�DQ�H[DPSOH�RI�FKHFNLQJ�ZKHWKHU�D�ILOH�LVEHLQJ�NHSW�XS�WR�GDWH��,Q�WKLV�FDVH��ZH¦UH�WHVWLQJ�DQ�DOUHDG\�RSHQHG�ILOHKDQGOH��LQVWHDGRI�D�VWULQJ�ILOHQDPH��/HW¦V�VD\�WKDW�RXU�SURJUDP¦V�FRQILJXUDWLRQ�ILOH�VKRXOG�EH�XSGDWHGHYHU\�ZHHN�RU�WZR���0D\EH�LW¦V�FKHFNLQJ�IRU�FRPSXWHU�YLUXVHV��VD\���,I�WKH�ILOH�KDVQ¦WEHHQ�PRGLILHG�LQ�WKH�SDVW����GD\V��WKHQ�VRPHWKLQJ�LV�ZURQJ�

warn "Config file is looking pretty old!\n" if -M CONFIG > 28;

179

7KH�WKLUG�H[DPSOH�LV�PRUH�FRPSOH[��+HUH��OHW¦V�VD\�WKDW�GLVN�VSDFH�LV�ILOOLQJ�XS�DQGUDWKHU�WKDQ�EX\�PRUH�GLVNV��ZH¦YH�GHFLGHG�WR�PRYH�DQ\�ODUJH��XVHOHVV�ILOHV�WR�WKH�EDFNXSWDSHV��6R�OHW¦V�JR�WKURXJK�RXU�OLVW�RI�ILOHV �WR�VHH�ZKLFK�RI�WKHP�DUH�ODUJHU�WKDQ�����.%�%XW�HYHQ�LI�D�ILOH�LV�ODUJH��ZH�VKRXOGQ¦W�PRYH�LW�WR�WKH�EDFNXS�WDSHV�XQOHVV�LW�KDVQ¦W�EHHQDFFHVVHG�LQ�WKH�ODVW����GD\V��VR�ZH�NQRZ�WKDW�LW¦V�QRW�XVHG�WRR�RIWHQ���

my @original_files = qw/ fred barney betty wilma pebbles dino bamm-bamm /;my @big_old_files; # The ones we want to put on backup tapesforeach my $filename (@original_files) { push @big_old_files, $filename if -s $filename > 100_000 and -A $filename > 90;}

7KLV�LV�WKH�ILUVW�WLPH�WKDW�\RX¦YH�VHHQ�LW��VR�PD\EH�\RX�QRWLFHG�WKDW�WKH�FRQWURO�YDULDEOHRI�WKH�foreach�ORRS�LV�D�my�YDULDEOH��7KDW�GHFODUHV�LW�WR�KDYH�WKH�VFRSH�RI�WKH�ORRS�LWVHOI�VR�WKLV�H[DPSOH�VKRXOG�ZRUN�XQGHU�use strict��:LWKRXW�WKH�my�NH\ZRUG��WKLV�ZRXOGEH�XVLQJ�WKH�JOREDO�$filename�

7KH�ILOH�WHVWV�DOO�ORRN�OLNH�D�K\SKHQ�DQG�D�OHWWHU��ZKLFK�LV�WKH�QDPH�RI�WKH�WHVW��IROORZHGE\�HLWKHU�D�ILOHQDPH�RU�D�ILOHKDQGOH�WR�WHVW��0DQ\�RI�WKHP�UHWXUQ�D�WUXH�IDOVH�YDOXH��EXWVHYHUDO�JLYH�VRPHWKLQJ�PRUH�LQWHUHVWLQJ��6HH�7DEOH������IRU�WKH�FRPSOHWH�OLVW��DQG�WKHQUHDG�WKH�IROORZLQJ�GLVFXVVLRQ�WR�OHDUQ�PRUH�DERXW�WKH�VSHFLDO�FDVHV�

7DEOH�������)LOH�WHVWV�DQG�WKHLU�PHDQLQJV

File test Meaning

-r File or directory is readable by this (effective) user or group

-w File or directory is writable by this (effective) user or group

-x File or directory is executable by this (effective) user or group

-o File or directory is owned by this (effective) user

-R File or directory is readable by this real user or group

-W File or directory is writable by this real user or group

-X File or directory is executable by this real user or group

-O File or directory is owned by this real user

-e File or directory name exists

-z File exists and has zero size (always false for directories)

-s File or directory exists and has nonzero size (the value is the size in bytes)

-f Entry is a plain file

-d Entry is a directory

,W¦V�PRUH�OLNHO\�WKDW��LQVWHDG�RI�KDYLQJ�WKH�OLVW�RI�ILOHV�LQ�DQ�DUUD\��DV�RXU�H[DPSOH�VKRZV��\RX¦OO�UHDG�LW�GLUHFWO\IURP�WKH�ILOHV\VWHP�XVLQJ�D�JORE�RU�GLUHFWRU\�KDQGOH��DV�ZH¦OO�VKRZ�LQ�&KDSWHU�����6LQFH�\RX�KDYHQ¦W�VHHQ�WKDW\HW��ZH¦OO�MXVW�VWDUW�ZLWK�WKH�OLVW�DQG�JR�IURP�WKHUH�

� 7KHUH¦V�D�ZD\�WR�PDNH�WKLV�H[DPSOH�PRUH�HIILFLHQW��DV�\RX¦OO�VHH�E\�WKH�HQG�RI�WKH�FKDSWHU�

180 | Chapter 12:ಗFile Tests

File test Meaning

-l Entry is a symbolic link

-S Entry is a socket

-p Entry is a named pipe (a “fifo”)

-b Entry is a block-special file (like a mountable disk)

-c Entry is a character-special file (like an I/O device)

-u File or directory is setuid

-g File or directory is setgid

-k File or directory has the sticky bit set

-t The filehandle is a TTY (as reported by the isatty() system function; filenames can’t be tested by this test)

-T File looks like a “text” file

-B File looks like a “binary” file

-M Modification age (measured in days)

-A Access age (measured in days)

-C Inode-modification age (measured in days)

7KH�WHVWV�-r��-w��-x��DQG�-o�WHOO�ZKHWKHU�WKH�JLYHQ�DWWULEXWH�LV�WUXH�IRU�WKH�HIIHFWLYH�XVHURU�JURXS�,'� �ZKLFK�HVVHQWLDOO\�UHIHUV�WR�WKH�SHUVRQ�ZKR�LV�£LQ�FKDUJH�RI¤�UXQQLQJ�WKHSURJUDP���7KHVH�WHVWV�ORRN�DW�WKH�£SHUPLVVLRQ�ELWV¤�RQ�WKH�ILOH�WR�VHH�ZKDW�LV�SHUPLWWHG�,I�\RXU�V\VWHP�XVHV�$FFHVV�&RQWURO�/LVWV��$&/V���WKH�WHVWV�ZLOO�XVH�WKRVH�DV�ZHOO��7KHVHWHVWV�JHQHUDOO\�WHOO�ZKHWKHU�WKH�V\VWHP�ZRXOG�WU\�WR�SHUPLW�VRPHWKLQJ��EXW�LW�GRHVQ¦WPHDQ�WKDW�LW�UHDOO\�ZRXOG�EH�SRVVLEOH��)RU�H[DPSOH��-w�PD\�EH�WUXH�IRU�D�ILOH�RQ�D�&'�520��HYHQ�WKRXJK�\RX�FDQ¦W�ZULWH�WR�LW��RU�-x�PD\�EH�WUXH�RQ�DQ�HPSW\�ILOH��ZKLFK�FDQ¦WWUXO\�EH�H[HFXWHG�

7KH�-s�WHVW�GRHV�UHWXUQ�WUXH�LI�WKH�ILOH�LV�QRQHPSW\��EXW�LW¦V�D�VSHFLDO�NLQG�RI�WUXH��,W¦VWKH�OHQJWK�RI�WKH�ILOH��PHDVXUHG�LQ�E\WHV��ZKLFK�HYDOXDWHV�DV�WUXH�IRU�D�QRQ]HUR�QXPEHU�

2Q�D�8QL[�ILOHV\VWHP�®�WKHUH�DUH�MXVW�VHYHQ�W\SHV�RI�LWHPV��UHSUHVHQWHG�E\�WKH�VHYHQ�ILOHWHVWV��-f��-d��-l��-S��-p��-b��DQG�-c��$Q\�LWHP�VKRXOG�EH�RQH�RI�WKRVH��%XW�LI�\RX�KDYH�DV\PEROLF�OLQN�SRLQWLQJ�WR�D�ILOH��WKDW�ZLOO�UHSRUW�WUXH�IRU�ERWK�-f�DQG�-l��6R��LI�\RX�ZDQWWR�NQRZ�ZKHWKHU�VRPHWKLQJ� LV�D�V\PEROLF� OLQN��\RX�VKRXOG�JHQHUDOO\� WHVW� WKDW� ILUVW��<RX¦OO�OHDUQ�PRUH�DERXW�V\PEROLF�OLQNV�LQ�&KDSWHU�����

7KH�-o�DQG�-O�WHVWV�UHODWH�RQO\�WR�WKH�XVHU�,'�DQG�QRW�WR�WKH�JURXS�,'�

� 1RWH�IRU�DGYDQFHG�VWXGHQWV��WKH�FRUUHVSRQGLQJ�-R��-W��-X��DQG�-O�WHVWV�XVH�WKH�UHDO�XVHU�RU�JURXS�,'��ZKLFKEHFRPHV�LPSRUWDQW�LI�\RXU�SURJUDP�PD\�EH�UXQQLQJ�VHW�,'��LQ�WKDW�FDVH��LW¦V�JHQHUDOO\�WKH�,'�RI�WKH�SHUVRQZKR�UHTXHVWHG�UXQQLQJ�LW��6HH�DQ\�JRRG�ERRN�DERXW�DGYDQFHG�8QL[�SURJUDPPLQJ�IRU�D�GLVFXVVLRQ�RI�VHW�,'SURJUDPV�

® 7KLV�LV�DOVR�WKH�FDVH�RQ�PDQ\�QRQ�8QL[�ILOHV\VWHPV��EXW�QRW�DOO�RI�WKH�ILOH�WHVWV�DUH�PHDQLQJIXO�HYHU\ZKHUH�)RU�H[DPSOH��\RX�DUHQ¦W�OLNHO\�WR�KDYH�EORFN�VSHFLDO�ILOHV�RQ�\RXU�QRQ�8QL[�V\VWHP�

File Test Operators | 181

7KH�DJH�WHVWV��-M��-A��DQG�-C��\HV��WKH\¦UH�XSSHUFDVH���UHWXUQ�WKH�QXPEHU�RI�GD\V�VLQFHWKH�ILOH�ZDV�ODVW�PRGLILHG��DFFHVVHG��RU�KDG�LWV�LQRGH�FKDQJHG� ��7KH�LQRGH�FRQWDLQV�DOORI�WKH�LQIRUPDWLRQ�DERXW�WKH�ILOH�H[FHSW�IRU�LWV�FRQWHQWV¢VHH�WKH�VWDW�V\VWHP�FDOO�PDQ�SDJH�RU�D�JRRG�ERRN�RQ�8QL[�LQWHUQDOV�IRU�GHWDLOV���7KLV�DJH�YDOXH�LV�D�IXOO�IORDWLQJ�SRLQWQXPEHU��VR�\RX�PLJKW�JHW�D�YDOXH�RI�2.00001�LI�D�ILOH�ZHUH�PRGLILHG�WZR�GD\V�DQG�RQHVHFRQG�DJR���7KHVH�£GD\V¤�DUHQ¦W�QHFHVVDULO\�WKH�VDPH�DV�D�KXPDQ�ZRXOG�FRXQW��IRUH[DPSOH��LI�LW¦V������LQ�WKH�PRUQLQJ�ZKHQ�\RX�FKHFN�D�ILOH�PRGLILHG�DW�DERXW�DQ�KRXUEHIRUH�PLGQLJKW��WKH�YDOXH�RI�-M�IRU�WKLV�ILOH�ZRXOG�EH�DURXQG�0.1��HYHQ�WKRXJK�LW�ZDVPRGLILHG�£\HVWHUGD\�¤�

:KHQ�FKHFNLQJ�WKH�DJH�RI�D�ILOH��\RX�PLJKW�HYHQ�JHW�D�QHJDWLYH�YDOXH�OLNH�!1.2��ZKLFKPHDQV�WKDW�WKH�ILOH¦V�ODVW�DFFHVV�WLPHVWDPS�LV�VHW�DW�DERXW����KRXUV�LQ�WKH�IXWXUH��7KH]HUR�SRLQW�RQ�WKLV�WLPHVFDOH�LV�WKH�PRPHQW�\RXU�SURJUDP�VWDUWHG�UXQQLQJ���VR�WKDW�YDOXHPLJKW�PHDQ�WKDW�D�ORQJ�UXQQLQJ�SURJUDP�ZDV�ORRNLQJ�DW�D�ILOH�WKDW�KDG�MXVW�EHHQ�DF�FHVVHG��2U�D� WLPHVWDPS�FRXOG�EH�VHW� �DFFLGHQWDOO\�RU� LQWHQWLRQDOO\�� WR�D� WLPH� LQ� WKHIXWXUH�

7KH�WHVWV�-T�DQG�-B�WDNH�D�WU\�DW�WHOOLQJ�ZKHWKHU�D�ILOH�LV�WH[W�RU�ELQDU\��%XW�SHRSOH�ZKRNQRZ�D�ORW�DERXW�ILOHV\VWHPV�NQRZ�WKDW�WKHUH¦V�QR�ELW��DW�OHDVW�LQ�8QL[�OLNH�RSHUDWLQJV\VWHPV��WR�LQGLFDWH�WKDW�D�ILOH�LV�D�ELQDU\�RU�WH[W�ILOH¢VR�KRZ�FDQ�3HUO�WHOO"�7KH�DQVZHULV�WKDW�3HUO�FKHDWV��LW�RSHQV�WKH�ILOH��ORRNV�DW�WKH�ILUVW�IHZ�WKRXVDQG�E\WHV��DQG�PDNHV�DQHGXFDWHG�JXHVV��,I�LW�VHHV�D�ORW�RI�QXOO�E\WHV��XQXVXDO�FRQWURO�FKDUDFWHUV��DQG�E\WHV�ZLWKWKH�KLJK�ELW�VHW��WKHQ�WKDW�ORRNV�OLNH�D�ELQDU\�ILOH��,I�WKHUH¦V�QRW�PXFK�ZHLUG�VWXII�WKHQLW�ORRNV�OLNH�WH[W��$V�\RX�PLJKW�JXHVV��LW�VRPHWLPHV�JXHVVHV�ZURQJ��,I�D�WH[W�ILOH�KDV�DORW�RI�6ZHGLVK�RU�)UHQFK�ZRUGV��ZKLFK�PD\�KDYH�FKDUDFWHUV�UHSUHVHQWHG�ZLWK�WKH�KLJKELW�VHW��DV�VRPH�,62������VRPHWKLQJ�YDULDQW��RU�SHUKDSV�HYHQ�D�8QLFRGH�YHUVLRQ���LWPD\�IRRO�3HUO�LQWR�GHFODULQJ�LW�ELQDU\��6R�LW¦V�QRW�SHUIHFW��EXW�LI�\RX�MXVW�QHHG�WR�VHSDUDWH\RXU�VRXUFH�FRGH�IURP�FRPSLOHG�ILOHV��RU�+70/�ILOHV�IURP�31*V��WKHVH�WHVWV�VKRXOG�GRWKH�WULFN�

<RX¦G�WKLQN�WKDW�-T�DQG�-B�ZRXOG�DOZD\V�GLVDJUHH��VLQFH�D�WH[W�ILOH�LVQ¦W�D�ELQDU\�DQGYLFH�YHUVD��EXW�WKHUH�DUH�WZR�VSHFLDO�FDVHV�ZKHUH�WKH\¦UH�LQ�FRPSOHWH�DJUHHPHQW��,I�WKHILOH�GRHVQ¦W�H[LVW��RU�FDQ¦W�EH�UHDG��ERWK�DUH�IDOVH��VLQFH�LW¦V�QHLWKHU�D�WH[W�ILOH�QRU�D�ELQDU\�$OWHUQDWLYHO\��LI�WKH�ILOH�LV�HPSW\��LW¦V�DQ�HPSW\�WH[W�ILOH�DQG�DQ�HPSW\�ELQDU\�ILOH�DW�WKHVDPH�WLPH��VR�WKH\¦UH�ERWK�WUXH�

7KH�-t�ILOH�WHVW�UHWXUQV�WUXH�LI�WKH�JLYHQ�ILOHKDQGOH�LV�D�77<¢LQ�VKRUW��LI�LW¦V�LQWHUDFWLYHEHFDXVH�LW¦V�QRW�D�VLPSOH�ILOH�RU�SLSH��:KHQ�-t STDIN�UHWXUQV�WUXH��LW�JHQHUDOO\�PHDQVWKDW�\RX�FDQ�LQWHUDFWLYHO\�DVN�WKH�XVHU�TXHVWLRQV��,I�LW¦V�IDOVH��\RXU�SURJUDP�LV�SUREDEO\JHWWLQJ�LQSXW�IURP�D�ILOH�RU�SLSH��UDWKHU�WKDQ�D�NH\ERDUG�

7KLV�LQIRUPDWLRQ�ZLOO�EH�VRPHZKDW�GLIIHUHQW�RQ�QRQ�8QL[�V\VWHPV��VLQFH�QRW�DOO�NHHS�WUDFN�RI�WKH�VDPH�WLPHVWKDW�8QL[�GRHV��)RU�H[DPSOH��RQ�VRPH�V\VWHPV��WKH�FWLPH�ILHOG��ZKLFK�WKH�-C�WHVW�ORRNV�DW��LV�WKH�ILOH�FUHDWLRQWLPH��ZKLFK�8QL[�GRHVQ¦W�NHHS�WUDFN�RI���UDWKHU�WKDQ�WKH�LQRGH�FKDQJH�WLPH��VHH�WKH�SHUOSRUW�PDQSDJH�

� $V�UHFRUGHG�LQ�WKH�$^T�YDULDEOH��ZKLFK�\RX�FRXOG�XSGDWH��ZLWK�D�VWDWHPHQW�OLNH�$^T = time;��LI�\RX�QHHGHGWR�JHW�WKH�DJHV�UHODWLYH�WR�D�GLIIHUHQW�VWDUWLQJ�WLPH�

182 | Chapter 12:ಗFile Tests

'RQ¦W�ZRUU\�LI�\RX�GRQ¦W�NQRZ�ZKDW�VRPH�RI�WKH�RWKHU�ILOH�WHVWV�PHDQ¢LI�\RX¦YH�QHYHUKHDUG�RI�WKHP��\RX�ZRQ¦W�EH�QHHGLQJ�WKHP��%XW�LI�\RX¦UH�FXULRXV��JHW�D�JRRG�ERRN�DERXWSURJUDPPLQJ�IRU�8QL[���2Q�QRQ�8QL[�V\VWHPV��WKHVH�WHVWV�DOO�WU\�WR�JLYH�UHVXOWV�DQDO�RJRXV�WR�ZKDW�WKH\�GR�RQ�8QL[��RU�undef�IRU�DQ�XQDYDLODEOH�IHDWXUH��8VXDOO\�\RX¦OO�EHDEOH�WR�JXHVV�FRUUHFWO\�ZKDW�WKH\¦OO�GR��

,I�\RX�RPLW�WKH�ILOHQDPH�RU�ILOHKDQGOH�SDUDPHWHU�WR�D�ILOH�WHVW��WKDW�LV��LI�\RX�KDYH�MXVW-r�RU� MXVW�-s�� VD\��� WKH�GHIDXOW�RSHUDQG� LV� WKH� ILOH�QDPHG� LQ�$_� � 6R�� WR� WHVW�D� OLVW�RIILOHQDPHV�WR�VHH�ZKLFK�RQHV�DUH�UHDGDEOH��\RX�VLPSO\�W\SH�

foreach (@lots_of_filenames) { print "$_ is readable\n" if -r; # same as -r $_}

%XW�LI�\RX�RPLW�WKH�SDUDPHWHU��EH�FDUHIXO�WKDW�ZKDWHYHU�IROORZV�WKH�ILOH�WHVW�GRHVQ¦W�ORRNOLNH�LW�FRXOG�EH�D�SDUDPHWHU��)RU�H[DPSOH��LI�\RX�ZDQWHG�WR�ILQG�RXW�WKH�VL]H�RI�D�ILOH�LQ.%�UDWKHU�WKDQ�LQ�E\WHV��\RX�PLJKW�EH�WHPSWHG�WR�GLYLGH�WKH�UHVXOW�RI�-s�E\�1000��RU1024���OLNH�WKLV�

# The filename is in $_my $size_in_K = -s / 1000; # Oops!

:KHQ�WKH�3HUO�SDUVHU�VHHV�WKH�VODVK��LW�GRHVQ¦W�WKLQN�DERXW�GLYLVLRQ��VLQFH�LW¦V�ORRNLQJIRU�WKH�RSWLRQDO�RSHUDQG�IRU�-s��LW�VHHV�ZKDW�ORRNV�OLNH�WKH�VWDUW�RI�D�UHJXODU�H[SUHVVLRQLQ�IRUZDUG�VODVKHV��2QH�VLPSOH�ZD\�WR�SUHYHQW�WKLV�NLQG�RI�FRQIXVLRQ�LV�WR�SXW�SDUHQ�WKHVHV�DURXQG�WKH�ILOH�WHVW�

my $size_in_k = (-s) / 1024; # Uses $_ by default

2I�FRXUVH��LW¦V�DOZD\V�VDIH�WR�H[SOLFLWO\�JLYH�D�ILOH�WHVW�D�SDUDPHWHU�

Testing Several Attributes of the Same File:H�FDQ�XVH�PRUH�WKDQ�RQH�ILOH�WHVW�RQ�WKH�VDPH�ILOH�WR�FUHDWH�D�FRPSOH[�ORJLFDO�FRQGLWLRQ�6XSSRVH�ZH�ZDQW�WR�RSHUDWH�RQ�RQO\�ILOHV�WKDW�DUH�ERWK�UHDGDEOH�DQG�ZULWDEOH��:H�FKHFNHDFK�DWWULEXWH�DQG�FRPELQH�WKHP�ZLWK�and�

if( -r $file and -w $file ) { ... }

7KLV�LV�DQ�H[SHQVLYH�RSHUDWLRQ��WKRXJK��(DFK�WLPH�\RX�SHUIRUP�D�ILOH�WHVW��3HUO�DVNV�WKHILOHV\VWHP�IRU�DOO�RI�WKH�LQIRUPDWLRQ�DERXW�WKH�ILOH��3HUO¦V�DFWXDOO\�GRLQJ�D�stat�HDFKWLPH��ZKLFK�ZH�WDON�DERXW�LQ�WKH�QH[W�VHFWLRQ���$OWKRXJK�ZH�DOUHDG\�JRW�WKDW�LQIRUPD�WLRQ�ZKHQ�ZH�WHVWHG�-r��3HUO�DVNV�IRU�WKH�VDPH�LQIRUPDWLRQ�DJDLQ�VR�LW�FDQ�WHVW�-w��:KDWD�ZDVWH��7KLV�FDQ�EH�D�VLJQLILFDQW�SHUIRUPDQFH�SUREOHP�LI�\RX¦UH�WHVWLQJ�PDQ\�DWWULEXWHVRQ�PDQ\�ILOHV�

7KH�-t�ILOH�WHVW�LV�DQ�H[FHSWLRQ�VLQFH�WKDW�WHVW�LVQ¦W�XVHIXO�ZLWK�ILOHQDPHV��WKH\¦UH�QHYHU�77<V���%\�GHIDXOW�LWWHVWV�STDIN�

File Test Operators | 183

3HUO�KDV�D�VSHFLDO�VKRUWFXW�WR�KHOS�XV�QRW�GR�VR�PXFK�ZRUN��7KH�YLUWXDO�ILOHKDQGOH�_�MXVW�WKH�XQGHUVFRUH��XVHV�WKH�LQIRUPDWLRQ�IURP�WKH�ODVW�ILOH�ORRNXS�WKDW�D�ILOH�WHVW�RS�HUDWRU�SHUIRUPHG��3HUO�RQO\�KDV�WR�ORRN�XS�WKH�ILOH�LQIRUPDWLRQ�RQFH�QRZ�

if( -r $file and -w _ ) { ... }

:H�GRQ¦W�KDYH�WR�XVH�WKH�ILOH�WHVWV�QH[W�WR�HDFK�RWKHU�WR�XVH�_��+HUH�ZH�KDYH�WKHP�LQVHSDUDWH�if�FRQGLWLRQV�

if( -r $file ) { print "The file is readable!\n"; }

if( -w _ ) { print "The file is writable!\n"; }

:H�KDYH�WR�ZDWFK�RXW�WKDW�ZH�NQRZ�ZKDW�WKH�ODVW�ILOH�ORRNXS�UHDOO\�ZDV��WKRXJK��,I�ZHGR�VRPHWKLQJ�HOVH�EHWZHHQ�WKH�ILOH�WHVWV��VXFK�DV�FDOO�D�VXEURXWLQH��WKH�ODVW�ILOH�ZH�ORRNHGXS�PLJKW�EH�GLIIHUHQW��)RU�LQVWDQFH��WKLV�H[DPSOH�FDOOV�WKH�lookup�VXEURXWLQH��ZKLFKKDV�D�ILOH�WHVW�LQ�LW��:KHQ�ZH�UHWXUQ�IURP�WKDW�VXEURXWLQH�DQG�GR�DQRWKHU�ILOH�WHVW��WKH_�ILOHKDQGOH�LVQ¦W�IRU�$file�OLNH�ZH�H[SHFW��EXW�IRU�$other_file�

if( -r $file ) { print "The file is readable!\n"; }

lookup( $other_file );

if( -w _ ) { print "The file is writable!\n"; }

sub lookup { return -w $_[0]; }

Stacked File Test Operators3UHYLRXV�WR�3HUO�������LI�ZH�ZDQWHG�WR�WHVW�VHYHUDO�ILOH�DWWULEXWHV�DW�WKH�VDPH�WLPH��ZHKDG�WR�WHVW�WKHP�LQGLYLGXDOO\��HYHQ�LI�XVLQJ�WKH�_�ILOHKDQGOH�WR�VDYH�RXUVHOYHV�VRPH�ZRUN�6XSSRVH�ZH�ZDQWHG�WR�WHVW�ZKHWKHU�D�ILOH�ZDV�UHDGDEOH�DQG�ZULWDEOH�DW�WKH�VDPH�WLPH�:H¦G�KDYH�WR�WHVW�ZKHWKHU�LW¦V�UHDGDEOH�DQG�WKHQ�DOVR�WHVW�ZKHWKHU�LW¦V�ZULWDEOH�

if( -r $file and -w _ ) { print "The file is both readable and writable!\n"; }

,W¦V�PXFK�HDVLHU�WR�GR�WKLV�DOO�DW�RQFH��3HUO������OHWV�XV�£VWDFN¤�RXU�ILOH�WHVW�RSHUDWRUV�E\OLQLQJ�WKHP�DOO�XS�EHIRUH�WKH�ILOHQDPH�

184 | Chapter 12:ಗFile Tests

use 5.010;

if( -w -r $file ) { print "The file is both readable and writable!\n"; }

7KLV�VWDFNHG�H[DPSOH�LV�WKH�VDPH�DV�WKH�SUHYLRXV�H[DPSOH�ZLWK�MXVW�D�FKDQJH�LQ�V\QWD[�DOWKRXJK��LW�ORRNV�OLNH�WKH�ILOH�WHVWV�DUH�UHYHUVHG��3HUO�GRHV�WKH�ILOH�WHVW�QHDUHVW�WKH�ILOH�QDPH�ILUVW��1RUPDOO\�WKLV�LVQ¦W�JRLQJ�WR�PDWWHU�

6WDFNHG�ILOH�WHVWV�DUH�HVSHFLDOO\�KDQG\�IRU�FRPSOH[�VLWXDWLRQV��6XSSRVH�ZH�ZDQW�WR�OLVWDOO�RI�WKH�GLUHFWRULHV�WKDW�DUH�UHDGDEOH��ZULWDEOH��H[HFXWDEOH��DQG�RZQHG�E\�RXU�XVHU�:H�MXVW�QHHG�WKH�ULJKW�VHW�RI�ILOH�WHVWV�

use 5.010;

if( -r -w -x -o -d $file ) { print "My directory is readable, writable, and executable!\n"; }

6WDFNHG�ILOH�WHVWV�DUHQ¦W�JRRG�IRU�WKRVH�WKDW�UHWXUQ�YDOXHV�RWKHU�WKDQ�WUXH�RU�IDOVH�WKDWZH�ZRXOG�ZDQW�WR�XVH�LQ�D�FRPSDULVRQ��:H�PLJKW�WKLQN�WKDW�WKLV�QH[W�ELW�RI�FRGH�ILUVWWHVWV�WKDW�LW¦V�D�GLUHFWRU\�DQG�WKHQ�WHVWV�WKDW�LW�LV�OHVV�WKDQ�����E\WHV��EXW�LW�GRHVQ¦W�

use 5.010;

if( -s -d $file < 512) { # WRONG! DON'T DO THIS print "The directory is less than 512 bytes!\n"; }

5HZULWLQJ�WKH�VWDFNHG�ILOH�WHVWV�DV�WKH�SUHYLRXV�QRWDWLRQ�VKRZV�XV�ZKDW�LV�JRLQJ�RQ��7KHUHVXOW�RI�WKH�FRPELQDWLRQ�RI�WKH�ILOH�WHVWV�EHFRPHV�WKH�DUJXPHQW�IRU�WKH�FRPSDULVRQ�

if( ( -d $file and -s _ ) < 512 ) { print "The directory is less than 512 bytes!\n"; }

:KHQ�WKH�-d�UHWXUQV�IDOVH��3HUO�FRPSDUHV�WKDW�IDOVH�YDOXH�WR������7KDW�WXUQV�RXW�WR�EHWUXH�VLQFH�IDOVH�ZLOO�EH����ZKLFK�MXVW�KDSSHQV�WR�EH�OHVV�WKDQ������,QVWHDG�RI�ZRUU\LQJDERXW� WKDW�VRUW�RI�FRQIXVLRQ��ZH� MXVW�ZULWH� LW�DV� VHSDUDWH� ILOH� WHVWV� WR�EH�QLFH� WR� WKHPDLQWHQDQFH�SURJUDPPHUV�ZKR�FRPH�DIWHU�XV�

if( -d $file and -s _ < 512 ) { print "The directory is less than 512 bytes!\n"; }

File Test Operators | 185

The stat and lstat Functions:KLOH�WKHVH�ILOH�WHVWV�DUH�ILQH�IRU�WHVWLQJ�YDULRXV�DWWULEXWHV�UHJDUGLQJ�D�SDUWLFXODU�ILOH�RUILOHKDQGOH��WKH\�GRQ¦W�WHOO�WKH�ZKROH�VWRU\��)RU�H[DPSOH��WKHUH¦V�QR�ILOH�WHVW�WKDW�UHWXUQVWKH�QXPEHU�RI� OLQNV� WR�D� ILOH�RU� WKH�RZQHU¦V�XVHU� ,'� �XLG���7R�JHW�DW� WKH� UHPDLQLQJLQIRUPDWLRQ� DERXW� D� ILOH��PHUHO\� FDOO� WKH�stat� IXQFWLRQ��ZKLFK� UHWXUQV�SUHWW\�PXFKHYHU\WKLQJ�WKDW� WKH�VWDW�8QL[�V\VWHP�FDOO� UHWXUQV��KRSHIXOO\�PRUH�WKDQ�\RX�ZDQW� WRNQRZ�� �7KH�RSHUDQG�WR�stat�LV�D�ILOHKDQGOH��LQFOXGLQJ�WKH�_�YLUWXDO�ILOHKDQGOH���RU�DQH[SUHVVLRQ�WKDW�HYDOXDWHV�WR�D�ILOHQDPH��7KH�UHWXUQ�YDOXH�LV�HLWKHU�WKH�HPSW\�OLVW��LQGL�FDWLQJ�WKDW�WKH�stat�IDLOHG��XVXDOO\�EHFDXVH�WKH�ILOH�GRHVQ¦W�H[LVW���RU�D����HOHPHQW�OLVWRI�QXPEHUV��PRVW�HDVLO\�GHVFULEHG�XVLQJ�WKH�IROORZLQJ�OLVW�RI�VFDODU�YDULDEOHV�

my($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat($filename);

7KH� QDPHV� KHUH� UHIHU� WR� WKH� SDUWV� RI� WKH� stat� VWUXFWXUH�� GHVFULEHG� LQ� GHWDLO� LQ� WKHVWDW����PDQSDJH��<RX�VKRXOG�SUREDEO\�ORRN�WKHUH�IRU�WKH�GHWDLOHG�GHVFULSWLRQV��%XW�LQVKRUW��KHUH¦V�D�TXLFN�VXPPDU\�RI�WKH�LPSRUWDQW�RQHV�

�GHY�DQG��LQR7KH�GHYLFH�QXPEHU�DQG�LQRGH�QXPEHU�RI�WKH�ILOH��7RJHWKHU�WKH\�PDNH�XS�D�£OLFHQVHSODWH¤�IRU�WKH�ILOH��(YHQ�LI�LW�KDV�PRUH�WKDQ�RQH�QDPH��KDUG�OLQN���WKH�FRPELQDWLRQRI�GHYLFH�DQG�LQRGH�QXPEHUV�VKRXOG�DOZD\V�EH�XQLTXH�

�PRGH7KH�VHW�RI�SHUPLVVLRQ�ELWV�IRU�WKH�ILOH��DQG�VRPH�RWKHU�ELWV��,I�\RX¦YH�HYHU�XVHG�WKH8QL[�FRPPDQG�OV��O�WR�JHW�D�GHWDLOHG��ORQJ��ILOH�OLVWLQJ��\RX¦OO�VHH�WKDW�HDFK�OLQH�RIRXWSXW�VWDUWV�ZLWK�VRPHWKLQJ�OLNH�-rwxr-xr-x��7KH�QLQH�OHWWHUV�DQG�K\SKHQV�RI�ILOHSHUPLVVLRQV��FRUUHVSRQG�WR�WKH�QLQH�OHDVW�VLJQLILFDQW�ELWV�RI�$mode��ZKLFK�ZRXOG�LQ�WKLV�FDVH��JLYH�WKH�RFWDO�QXPEHU�0755��7KH�RWKHU�ELWV��EH\RQG�WKH�ORZHVW�QLQH�LQGLFDWH�RWKHU�GHWDLOV�DERXW�WKH�ILOH��6R��LI�\RX�QHHG�WR�ZRUN�ZLWK�WKH�PRGH��\RX¦OOJHQHUDOO\�ZDQW�WR�XVH�WKH�ELWZLVH�RSHUDWRUV�FRYHUHG�ODWHU�LQ�WKLV�FKDSWHU�

�QOLQN7KH�QXPEHU�RI��KDUG��OLQNV�WR�WKH�ILOH�RU�GLUHFWRU\��7KLV�LV�WKH�QXPEHU�RI�WUXH�QDPHVWKDW�WKH�LWHP�KDV��7KLV�QXPEHU�LV�DOZD\V�2�RU�PRUH�IRU�GLUHFWRULHV�DQG��XVXDOO\��1IRU�ILOHV��<RX¦OO�VHH�PRUH�DERXW�WKLV�ZKHQ�ZH�WDON�DERXW�FUHDWLQJ�OLQNV�WR�ILOHV�LQ

2Q�D�QRQ�8QL[�V\VWHP��ERWK�stat�DQG�lstat��DV�ZHOO�DV�WKH�ILOH�WHVWV��VKRXOG�UHWXUQ�£WKH�FORVHVW�WKLQJ�DYDLODEOH�¤)RU�H[DPSOH��D�V\VWHP�WKDW�GRHVQ¦W�KDYH�XVHU�,'V��WKDW�LV��D�V\VWHP�WKDW�KDV�MXVW�RQH�£XVHU�¤�LQ�WKH�8QL[�VHQVH�PLJKW�UHWXUQ�]HUR�IRU�WKH�XVHU�DQG�JURXS�,'V��DV�LI�WKH�RQH�DQG�RQO\�XVHU�LV�WKH�V\VWHP�DGPLQLVWUDWRU��,I�stat�RUlstat�IDLOV��LW�ZLOO�UHWXUQ�DQ�HPSW\�OLVW��,I�WKH�V\VWHP�FDOO�XQGHUO\LQJ�D�ILOH�WHVW�IDLOV��RU�LVQ¦W�DYDLODEOH�RQ�WKHJLYHQ�V\VWHP���WKDW�WHVW�ZLOO�JHQHUDOO\�UHWXUQ�undef��6HH�WKH�SHUOSRUW�PDQSDJH�IRU�WKH�ODWHVW�DERXW�ZKDW�WRH[SHFW�RQ�GLIIHUHQW�V\VWHPV�

� 7KH�ILUVW�FKDUDFWHU�LQ�WKDW�VWULQJ�LVQ¦W�D�SHUPLVVLRQ�ELW��LW�LQGLFDWHV�WKH�W\SH�RI�HQWU\��D�K\SKHQ�IRU�DQ�RUGLQDU\ILOH��d�IRU�GLUHFWRU\��RU�l�IRU�V\PEROLF�OLQN��DPRQJ�RWKHUV��7KH�OV�FRPPDQG�GHWHUPLQHV�WKLV�IURP�WKH�RWKHUELWV�SDVW�WKH�OHDVW�VLJQLILFDQW�QLQH�

186 | Chapter 12:ಗFile Tests

&KDSWHU�����,Q�WKH�OLVWLQJ�IURP�OV��O��WKLV�LV�WKH�QXPEHU�MXVW�DIWHU�WKH�SHUPLVVLRQ�ELWV�VWULQJ�

�XLG�DQG��JLG7KH�QXPHULF�XVHU�,'�DQG�JURXS�,'�VKRZLQJ�WKH�ILOH¦V�RZQHUVKLS�

�VL]H7KH�VL]H�LQ�E\WHV��DV�UHWXUQHG�E\�WKH�-s�ILOH�WHVW�

�DWLPH���PWLPH��DQG��FWLPH7KH�WKUHH�WLPHVWDPSV��EXW�KHUH�WKH\¦UH�UHSUHVHQWHG�LQ�WKH�V\VWHP¦V�WLPHVWDPS�IRU�PDW��D����ELW�QXPEHU�WHOOLQJ�KRZ�PDQ\�VHFRQGV�KDYH�SDVVHG�VLQFH�WKH�(SRFK��DQDUELWUDU\�VWDUWLQJ�SRLQW� IRU�PHDVXULQJ�V\VWHP�WLPH��2Q�8QL[�V\VWHPV�DQG�VRPHRWKHUV��WKH�(SRFK�LV�WKH�EHJLQQLQJ�RI������DW�PLGQLJKW�8QLYHUVDO�7LPH��EXW�WKH(SRFK�LV�GLIIHUHQW�RQ�VRPH�PDFKLQHV��7KHUH¦V�PRUH�LQIRUPDWLRQ�ODWHU�LQ�WKLV�FKDSWHURQ�WXUQLQJ�WKDW�WLPHVWDPS�QXPEHU�LQWR�VRPHWKLQJ�XVHIXO�

,QYRNLQJ�stat�RQ�WKH�QDPH�RI�D�V\PEROLF�OLQN�UHWXUQV�LQIRUPDWLRQ�RQ�ZKDW�WKH�V\PEROLFOLQN�SRLQWV�DW��QRW�LQIRUPDWLRQ�DERXW�WKH�V\PEROLF�OLQN�LWVHOI��XQOHVV�WKH�OLQN�MXVW�KDS�SHQV�WR�EH�SRLQWLQJ�DW�QRWKLQJ�FXUUHQWO\�DFFHVVLEOH���,I�\RX�QHHG�WKH��PRVWO\�XVHOHVV�LQIRUPDWLRQ�DERXW�WKH�V\PEROLF�OLQN�LWVHOI��XVH�lstat�UDWKHU�WKDQ�stat��ZKLFK�UHWXUQVWKH�VDPH�LQIRUPDWLRQ�LQ�WKH�VDPH�RUGHU���,I�WKH�RSHUDQG�LVQ¦W�D�V\PEROLF�OLQN��lstatUHWXUQV�WKH�VDPH�WKLQJV�WKDW�stat�ZRXOG�

/LNH�WKH�ILOH�WHVWV��WKH�RSHUDQG�RI�stat�RU�lstat�GHIDXOWV�WR�$_��PHDQLQJ�WKDW�WKH�XQGHU�O\LQJ�VWDW�V\VWHP�FDOO�ZLOO�EH�SHUIRUPHG�RQ�WKH�ILOH�QDPHG�E\�WKH�VFDODU�YDULDEOH�$_�

The localtime Function:KHQ�\RX�KDYH�D�WLPHVWDPS�QXPEHU��VXFK�DV�WKH�RQHV�IURP�stat���LW�ZLOO�W\SLFDOO\�ORRNVRPHWKLQJ�OLNH�1180630098��7KDW¦V�QRW�YHU\�XVHIXO�IRU�PRVW�KXPDQV��XQOHVV�\RX�QHHGWR�FRPSDUH�WZR�WLPHVWDPSV�E\�VXEWUDFWLQJ��<RX�PD\�QHHG�WR�FRQYHUW�LW�WR�VRPHWKLQJKXPDQ�UHDGDEOH��VXFK�DV�D�VWULQJ�OLNH�Thu May 31 09:48:18 2007��3HUO�FDQ�GR�WKDW�ZLWKWKH�localtime�IXQFWLRQ�LQ�D�VFDODU�FRQWH[W�

my $timestamp = 1180630098;my $date = localtime $timestamp;

,Q�D�OLVW�FRQWH[W��localtime�UHWXUQV�D�OLVW�RI�QXPEHUV��VHYHUDO�RI�ZKLFK�PD\�QRW�EH�TXLWHZKDW�\RX¦G�H[SHFW�

my($sec, $min, $hour, $day, $mon, $year, $wday, $yday, $isdst) = localtime $timestamp;

7KH�$mon�LV�D�PRQWK�QXPEHU��UDQJLQJ�IURP�0�WR�11��ZKLFK�LV�KDQG\�DV�DQ�LQGH[�LQWR�DQDUUD\�RI�PRQWK�QDPHV��7KH�$year�LV�WKH�QXPEHU�RI�\HDUV�VLQFH�������RGGO\�HQRXJK��VRDGG�1900�WR�JHW�WKH�UHDO�\HDU�QXPEHU��7KH�$wday�UDQJHV�IURP�0��IRU�6XQGD\��WKURXJK�6�IRU� 6DWXUGD\��� DQG� WKH� $yday� LV� WKH� GD\�RI�WKH�\HDU� �UDQJLQJ� IURP��� IRU� -DQXDU\� ��WKURXJK�����RU�����IRU�'HFHPEHU�����

The localtime Function | 187

7KHUH�DUH�WZR�UHODWHG�IXQFWLRQV�WKDW�\RX¦OO�DOVR�ILQG�XVHIXO��7KH�gmtime�IXQFWLRQ�LV�MXVWWKH�VDPH�DV�localtime��H[FHSW�WKDW�LW�UHWXUQV�WKH�WLPH�LQ�8QLYHUVDO�7LPH��ZKDW�ZH�RQFHFDOOHG�*UHHQZLFK�0HDQ�7LPH���,I�\RX�QHHG�WKH�FXUUHQW�WLPHVWDPS�QXPEHU�IURP�WKHV\VWHP�FORFN��MXVW�XVH�WKH�time�IXQFWLRQ��%RWK�localtime�DQG�gmtime�GHIDXOW�WR�XVLQJWKH�FXUUHQW�time�YDOXH�LI�\RX�GRQ¦W�VXSSO\�D�SDUDPHWHU�

my $now = gmtime; # Get the current universal timestamp as a string

)RU�PRUH�RQ�PDQLSXODWLQJ�GDWHV�DQG�WLPHV��VHH�WKH�LQIRUPDWLRQ�LQ�$SSHQGL[�%�DERXWXVHIXO�PRGXOHV�

Bitwise Operators:KHQ�\RX�QHHG�WR�ZRUN�ZLWK�QXPEHUV�ELW�E\�ELW��DV�ZKHQ�ZRUNLQJ�ZLWK�WKH�PRGH�ELWVUHWXUQHG�E\�stat��\RX¦OO�QHHG�WR�XVH�WKH�ELWZLVH�RSHUDWRUV��7KHVH�DUH�WKH�RSHUDWRUV�WKDWSHUIRUP�ELQDU\�PDWK�RSHUDWLRQV�RQ�YDOXHV��7KH�ELWZLVH�DQG�RSHUDWRU�\RX¦OO�QHHG�WR�XVHWKH�ELWZLVH�RSHUDWRUV��7KHVH�DUH�WKH�RSHUDWRUV�WKDW�SHUIRUP�ELQDU\�PDWK�RSHUDWLRQV�RQYDOXHV��7KH�ELWZLVH�DQG�RSHUDWRU� �&�� UHSRUWV�ZKLFK�ELWV�DUH�VHW� LQ� WKH� OHIW�DUJXPHQWDQG�LQ�WKH�ULJKW�DUJXPHQW��)RU�H[DPSOH��WKH�H[SUHVVLRQ�10 & 12�KDV�WKH�YDOXH�8��7KHELWZLVH�DQG�QHHGV�WR�KDYH�D���ELW�LQ�ERWK�RSHUDQGV�WR�SURGXFH�D�RQH�ELW�LQ�WKH�UHVXOW�7KDW�PHDQV�WKDW�WKH�ORJLFDO�DQG�RSHUDWLRQ�RQ�����ZKLFK�LV�1010�LQ�ELQDU\��DQG�����ZKLFKLV�1100��JLYHV����ZKLFK� LV�1000��ZLWK�D���ELW�RQO\�ZKHUH� WKH� OHIW�RSHUDQG�KDV�D���ELWDQG�WKH�ULJKW�RSHUDQG�DOVR�KDV�D���ELW���6HH�)LJXUH������

([DPSOHV�RI�WKH�ELW�RSHUDWRUV�DUH�VKRZQ�LQ7DEOH������

7DEOH�������%LWZLVH�RSHUDWRUV

Expression Meaning

10 & 12 Bitwise-and—which bits are true in both operands (this gives 8)

10 | 12 Bitwise-or—which bits are true in one operand or the other (this gives 14)

10 ^ 12 Bitwise-xor—which bits are true in one operand or the other but not both (this gives 6)

6 << 2 Bitwise shift left—shift the left operand the number of bits shown by the right operand, adding zero-bits at theleast-significant places (this gives 24)

25 >> 2 Bitwise shift right—shift the left operand the number of bits shown by the right operand, discarding the least-significant bits (this gives 6)

1010& 1100

1000

1010& 1100

1000

)LJXUH�������%LWZLVH�DQG�DGGLWLRQ

188 | Chapter 12:ಗFile Tests

Expression Meaning

~ 10 Bitwise negation, also called unary bit complement—return the number with the opposite bit for each bit inthe operand (this gives 0xFFFFFFF5, but see the text)

6R��KHUH¦V�DQ�H[DPSOH�RI�VRPH�WKLQJV�\RX�FRXOG�GR�ZLWK�WKH�$mode�UHWXUQHG�E\�stat�7KH�UHVXOWV�RI�WKHVH�ELW�PDQLSXODWLRQV�FRXOG�EH�XVHIXO�ZLWK�chmod��ZKLFK�\RX¦OO�VHH�LQ&KDSWHU�����

# $mode is the mode value returned from a stat of CONFIGwarn "Hey, the configuration file is world-writable!\n" if $mode & 0002; # configuration security problemmy $classical_mode = 0777 & $mode; # mask off extra high-bitsmy $u_plus_x = $classical_mode | 0100; # turn one bit onmy $go_minus_r = $classical_mode & (~ 0044); # turn two bits off

Using Bitstrings$OO�RI�WKH�ELWZLVH�RSHUDWRUV�FDQ�ZRUN�ZLWK�ELWVWULQJV��DV�ZHOO�DV�ZLWK�LQWHJHUV��,I�WKHRSHUDQGV�DUH�LQWHJHUV��WKH�UHVXOW�ZLOO�EH�DQ�LQWHJHU���7KH�LQWHJHU�ZLOO�EH�DW�OHDVW�D����ELWLQWHJHU��EXW�PD\�EH�ODUJHU�LI�\RXU�PDFKLQH�VXSSRUWV�WKDW��7KDW�LV��LI�\RX�KDYH�D����ELWPDFKLQH��~10�PD\�JLYH�WKH����ELW�UHVXOW�0xFFFFFFFFFFFFFFF5��UDWKHU�WKDQ�WKH����ELW�UHVXOW0xFFFFFFF5��

%XW�LI�DQ\�RSHUDQG�RI�D�ELWZLVH�RSHUDWRU�LV�D�VWULQJ��3HUO�ZLOO�SHUIRUP�WKH�RSHUDWLRQ�RQWKDW�ELWVWULQJ��7KDW�LV��"\xAA" | "\x55"�ZLOO�JLYH�WKH�VWULQJ�"\xFF"��1RWH�WKDW�WKHVH�YDOXHVDUH� VLQJOH�E\WH� VWULQJV�� WKH� UHVXOW� LV� D�E\WH�ZLWK� DOO� HLJKW�ELWV� VHW��%LWVWULQJV�PD\�EHDUELWUDULO\�ORQJ�

7KLV�LV�RQH�RI�WKH�YHU\�IHZ�SODFHV�ZKHUH�3HUO�GLVWLQJXLVKHV�EHWZHHQ�VWULQJV�DQG�QXPEHUV�6HH�WKH�SHUORS�PDQSDJH�IRU�PRUH�LQIRUPDWLRQ�RQ�XVLQJ�ELWZLVH�RSHUDWRUV�RQ�VWULQJV�

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >��@�0DNH�D�SURJUDP�WKDW�WDNHV�D� OLVW�RI� ILOHV�QDPHG�RQ�WKH�FRPPDQG�OLQH�DQGUHSRUWV�IRU�HDFK�RQH�ZKHWKHU�LW¦V�UHDGDEOH��ZULWDEOH��H[HFXWDEOH��RU�GRHVQ¦W�H[LVW��+LQW��LW�PD\�EH�KHOSIXO�WR�KDYH�D�IXQFWLRQ�WKDW�ZLOO�GR�DOO�RI�WKH�ILOH�WHVWV�IRU�RQHILOH�DW�D�WLPH���:KDW�GRHV�LW�UHSRUW�DERXW�D�ILOH�WKDW�KDV�EHHQ�FKPRG¦HG�WR�0"��7KDWLV��LI�\RX¦UH�RQ�D�8QL[�V\VWHP��XVH�WKH�FRPPDQG�FKPRG���VRPHBILOH�WR�PDUN�WKDWILOH�DV�QRW�EHLQJ�UHDGDEOH��ZULWDEOH��QRU�H[HFXWDEOH���,Q�PRVW�VKHOOV��XVH�D�VWDU�DVWKH�DUJXPHQW�WR�PHDQ�DOO�RI�WKH�QRUPDO�ILOHV�LQ�WKH�FXUUHQW�GLUHFWRU\��7KDW�LV��\RXFRXOG�W\SH�VRPHWKLQJ�OLNH�./ex12-2 *�WR�DVN�WKH�SURJUDP�IRU�WKH�DWWULEXWHV�RI�PDQ\ILOHV�DW�RQFH�

Exercises | 189

�� >��@�0DNH�D�SURJUDP�WR�LGHQWLI\�WKH�ROGHVW�ILOH�QDPHG�RQ�WKH�FRPPDQG�OLQH�DQGUHSRUW�LWV�DJH�LQ�GD\V��:KDW�GRHV�LW�GR�LI�WKH�OLVW�LV�HPSW\��WKDW�LV��LI�QR�ILOHV�DUHPHQWLRQHG�RQ�WKH�FRPPDQG�OLQH�"

�� >��@�0DNH�D�SURJUDP�WKDW�XVHV�VWDFNHG�ILOH�WHVW�RSHUDWRUV�WR�OLVW�DOO�ILOHV�QDPHG�RQWKH�FRPPDQG�OLQH�WKDW�DUH�RZQHG�E\�\RX��UHDGDEOH��DQG�ZULWDEOH�

190 | Chapter 12:ಗFile Tests

CHAPTER 13

Directory Operations

7KH�ILOHV�ZH�FUHDWHG�LQ�WKH�SUHYLRXV�FKDSWHU�ZHUH�JHQHUDOO\�LQ�WKH�VDPH�SODFH�DV�RXUSURJUDP��%XW�PRGHUQ�RSHUDWLQJ�V\VWHPV�OHW�XV�RUJDQL]H�ILOHV�LQWR�GLUHFWRULHV��DOORZLQJXV�WR�NHHS�RXU�%HDWOHV�03�V�DZD\�IURP�RXU�LPSRUWDQW�/ODPD�ERRN�FKDSWHU�VRXUFHV�VRWKDW�ZH�GRQ¦W�DFFLGHQWDOO\�VHQG�DQ�03��ILOH�WR�WKH�SXEOLVKHU��3HUO�OHWV�\RX�PDQLSXODWHWKHVH�GLUHFWRULHV�GLUHFWO\��LQ�ZD\V�WKDW�DUH�HYHQ�IDLUO\�SRUWDEOH�IURP�RQH�RSHUDWLQJ�V\V�WHP�WR�DQRWKHU�

Moving Around the Directory Tree<RXU�SURJUDP�UXQV�ZLWK�D�£ZRUNLQJ�GLUHFWRU\�¤�ZKLFK�LV�WKH�VWDUWLQJ�SRLQW�IRU�UHODWLYHSDWKQDPHV��7KDW�LV��LI�\RX�UHIHU�WR�WKH�ILOH�fred��WKDW�PHDQV�fred�LQ�WKH�FXUUHQW�ZRUNLQJGLUHFWRU\�

7KH�chdir�RSHUDWRU�FKDQJHV� WKH�ZRUNLQJ�GLUHFWRU\�� ,W¦V� MXVW� OLNH� WKH�8QL[� VKHOO¦V�FGFRPPDQG�

chdir "/etc" or die "cannot chdir to /etc: $!";

%HFDXVH�WKLV�LV�D�V\VWHP�UHTXHVW��WKH�YDOXH�RI�$!�ZLOO�EH�VHW�LI�DQ�HUURU�RFFXUV��<RX�VKRXOGQRUPDOO\�FKHFN�$!�ZKHQ�D�IDOVH�YDOXH�LV�UHWXUQHG�IURP�chdir��VLQFH�WKDW�LQGLFDWHV�WKDWVRPHWKLQJ�KDV�QRW�JRQH�DV�UHTXHVWHG�

7KH�ZRUNLQJ�GLUHFWRU\�LV�LQKHULWHG�E\�DOO�SURFHVVHV�WKDW�3HUO�VWDUWV��ZH¦OO�WDON�PRUH�DERXWWKDW�LQ�&KDSWHU������+RZHYHU��WKH�FKDQJH�LQ�ZRUNLQJ�GLUHFWRU\�FDQQRW�DIIHFW�WKH�SURFHVVWKDW�LQYRNHG�3HUO��VXFK�DV�WKH�VKHOO� �6R�\RX�FDQ¦W�PDNH�D�3HUO�SURJUDP�WR�UHSODFH�\RXUVKHOO¦V�FG�FRPPDQG�

,I�\RX�RPLW�WKH�SDUDPHWHU��3HUO�GHWHUPLQHV�\RXU�KRPH�GLUHFWRU\�DV�EHVW�DV�LW�FDQ�DQGDWWHPSWV�WR�VHW�WKH�ZRUNLQJ�GLUHFWRU\�WR�\RXU�KRPH�GLUHFWRU\��VLPLODU�WR�XVLQJ�WKH�FGFRPPDQG�DW�WKH�VKHOO�ZLWKRXW�D�SDUDPHWHU��7KLV�LV�RQH�RI�WKH�IHZ�SODFHV�ZKHUH�RPLWWLQJWKH�SDUDPHWHU�GRHVQ¦W�XVH�$_�

7KLV�LVQ¦W�D�OLPLWDWLRQ�RQ�3HUO¦V�SDUW��LW¦V�DFWXDOO\�D�IHDWXUH�RI�8QL[��:LQGRZV��DQG�RWKHU�V\VWHPV��,I�\RX�UHDOO\QHHG�WR�FKDQJH�WKH�VKHOO¦V�ZRUNLQJ�GLUHFWRU\��VHH�WKH�GRFXPHQWDWLRQ�RI�\RXU�VKHOO�

191

6RPH�VKHOOV�SHUPLW�\RX�WR�XVH�D�WLOGH�SUHIL[HG�SDWK�ZLWK�FG�WR�XVH�DQRWKHU�XVHU¦V�KRPHGLUHFWRU\�DV�D�VWDUWLQJ�SRLQW��OLNH�cd ~merlyn���7KLV�LV�D�IXQFWLRQ�RI�WKH�VKHOO��QRW�WKHRSHUDWLQJ�V\VWHP��DQG�3HUO�LV�FDOOLQJ�WKH�RSHUDWLQJ�V\VWHP�GLUHFWO\��7KXV��D�WLOGH�SUHIL[ZLOO�QRW�ZRUN�ZLWK�chdir�

Globbing1RUPDOO\�� WKH� VKHOO� H[SDQGV�DQ\� ILOHQDPH�SDWWHUQV�RQ�HDFK�FRPPDQG� OLQH� LQWR� WKHPDWFKLQJ�ILOHQDPHV��7KLV�LV�FDOOHG�JOREELQJ��)RU�H[DPSOH��LI�\RX�JLYH�D�ILOHQDPH�SDWWHUQRI�*.pm�WR�WKH�HFKR�FRPPDQG��WKH�VKHOO�H[SDQGV�WKLV�OLVW�WR�D�OLVW�RI�QDPHV�WKDW�PDWFK�

$ echo *.pmbarney.pm dino.pm fred.pm wilma.pm$

7KH�HFKR�FRPPDQG�GRHVQ¦W�KDYH�WR�NQRZ�DQ\WKLQJ�DERXW�H[SDQGLQJ�*.pm�EHFDXVH�WKHVKHOO�KDV�DOUHDG\�H[SDQGHG�LW��7KLV�ZRUNV�HYHQ�IRU�\RXU�3HUO�SURJUDPV�

$ cat >show-argsforeach $arg (@ARGV) { print "one arg is $arg\n";}^D$ perl show-args *.pmone arg is barney.pmone arg is dino.pmone arg is fred.pmone arg is wilma.pm$

1RWH�WKDW�VKRZ�DUJV�GLGQ¦W�QHHG�WR�NQRZ�DQ\WKLQJ�DERXW�JOREELQJ¢WKH�QDPHV�ZHUHDOUHDG\�H[SDQGHG�LQ�@ARGV�

%XW�VRPHWLPHV�ZH�HQG�XS�ZLWK�D�SDWWHUQ�OLNH�*.pm�LQVLGH�RXU�3HUO�SURJUDP��&DQ�ZHH[SDQG�WKLV�SDWWHUQ�LQWR�WKH�PDWFKLQJ�ILOHQDPHV�ZLWKRXW�ZRUNLQJ�YHU\�KDUG"�6XUH¢MXVW�XVH�WKH�glob�RSHUDWRU�

my @all_files = glob "*";my @pm_files = glob "*.pm";

+HUH��@all_files�JHWV�DOO�WKH�ILOHV�LQ�WKH�FXUUHQW�GLUHFWRU\��DOSKDEHWLFDOO\�VRUWHG��DQGQRW�LQFOXGLQJ�WKH�ILOHV�EHJLQQLQJ�ZLWK�D�SHULRG��MXVW�OLNH�WKH�VKHOO��$QG�@pm_files�JHWVWKH�VDPH�OLVW�WKDW�ZH�JRW�EHIRUH�E\�XVLQJ�*.pm�RQ�WKH�FRPPDQG�OLQH�

,Q�IDFW��DQ\WKLQJ�\RX�FDQ�VD\�RQ�WKH�FRPPDQG�OLQH��\RX�FDQ�DOVR�SXW�DV�WKH��VLQJOH�DUJXPHQW�WR�glob��LQFOXGLQJ�PXOWLSOH�SDWWHUQV�VHSDUDWHG�E\�VSDFHV�

my @all_files_including_dot = glob ".* *";

+HUH��ZH¦YH�LQFOXGHG�DQ�DGGLWLRQDO�£GRW�VWDU¤�SDUDPHWHU�WR�JHW�WKH�ILOHQDPHV�WKDW�EHJLQZLWK�D�GRW�DV�ZHOO�DV�WKH�RQHV�WKDW�GRQ¦W��3OHDVH�QRWH�WKDW�WKH�VSDFH�EHWZHHQ�WKHVH�WZRLWHPV�LQVLGH�WKH�TXRWHG�VWULQJ�LV�VLJQLILFDQW��DV�LW�VHSDUDWHV�WZR�GLIIHUHQW�LWHPV�\RX�ZDQW

192 | Chapter 13:ಗDirectory Operations

WR�JORE� �7KH�UHDVRQ�WKLV�ZRUNV�H[DFWO\�DV�WKH�VKHOO�ZRUNV�LV�WKDW�SULRU�WR�3HUO�YHUVLRQ�����WKH�glob�RSHUDWRU�VLPSO\�FDOOHG��ELQ�FVK��EHKLQG�WKH�VFHQHV�WR�SHUIRUP�WKH�H[SDQ�VLRQ��%HFDXVH�RI�WKLV��JOREV�ZHUH�WLPH�FRQVXPLQJ�DQG�FRXOG�EUHDN�LQ�ODUJH�GLUHFWRULHV�RU�LQ�VRPH�RWKHU�FDVHV��&RQVFLHQWLRXV�3HUO�KDFNHUV�DYRLGHG�JOREELQJ�LQ�IDYRU�RI�GLUHF�WRU\�KDQGOHV��ZKLFK�ZH�ZLOO�GLVFXVV�ODWHU�LQ�WKLV�FKDSWHU��+RZHYHU��LI�\RX¦UH�XVLQJ�DPRGHUQ�YHUVLRQ�RI�3HUO��\RX�VKRXOG�QR�ORQJHU�EH�FRQFHUQHG�DERXW�VXFK�WKLQJV�

An Alternate Syntax for Globbing$OWKRXJK�ZH�XVH�WKH�WHUP�JOREELQJ�IUHHO\��DQG�ZH�WDON�DERXW�WKH�glob�RSHUDWRU��\RXPLJKW�QRW�VHH�WKH�ZRUG�glob�LQ�YHU\�PDQ\�RI�WKH�SURJUDPV�WKDW�XVH�JOREELQJ��:K\�QRW":HOO��PRVW�OHJDF\�FRGH�ZDV�ZULWWHQ�EHIRUH�WKH�glob�RSHUDWRU�ZDV�JLYHQ�D�QDPH��,QVWHDG�LW�ZDV�FDOOHG�XS�E\�WKH�DQJOH�EUDFNHW�V\QWD[��VLPLODU�WR�UHDGLQJ�IURP�D�ILOHKDQGOH�

my @all_files = <*>; ## exactly the same as my @all_files = glob "*";

7KH� YDOXH� EHWZHHQ� WKH� DQJOH� EUDFNHWV� LV� LQWHUSRODWHG� VLPLODUO\� WR� D� GRXEOH�TXRWHGVWULQJ��ZKLFK�PHDQV�WKDW�3HUO�YDULDEOHV�DUH�H[SDQGHG�WR�WKHLU�FXUUHQW�3HUO�YDOXHV�EHIRUHEHLQJ�JOREEHG�

my $dir = "/etc";my @dir_files = <$dir/* $dir/.*>;

+HUH��ZH¦YH�IHWFKHG�DOO�WKH�QRQGRW�DQG�GRW�ILOHV�IURP�WKH�GHVLJQDWHG�GLUHFWRU\�EHFDXVH$dir�KDV�EHHQ�H[SDQGHG�WR�LWV�FXUUHQW�YDOXH�

6R��LI�XVLQJ�DQJOH�EUDFNHWV�PHDQV�ERWK�ILOHKDQGOH�UHDGLQJ�DQG�JOREELQJ��KRZ�GRHV�3HUOGHFLGH�ZKLFK�RI�WKH�WZR�RSHUDWRUV�WR�XVH"�:HOO��D�ILOHKDQGOH�KDV�WR�EH�D�3HUO�LGHQWLILHU�6R��LI�WKH�LWHP�EHWZHHQ�WKH�DQJOH�EUDFNHWV�LV�VWULFWO\�D�3HUO�LGHQWLILHU��LW¦V�D�ILOHKDQGOHUHDG��RWKHUZLVH��LW¦V�D�JOREELQJ�RSHUDWLRQ��)RU�H[DPSOH�

my @files = <FRED/*>; ## a globmy @lines = <FRED>; ## a filehandle readmy $name = "FRED";my @files = <$name/*>; ## a glob

7KH�RQH�H[FHSWLRQ�LV�LI�WKH�FRQWHQWV�DUH�D�VLPSOH�VFDODU�YDULDEOH��QRW�DQ�HOHPHQW�RI�DKDVK�RU�DUUD\���WKHQ�LW¦V�DQ�LQGLUHFW�ILOHKDQGOH�UHDG�®�ZKHUH�WKH�YDULDEOH�FRQWHQWV�JLYHWKH�QDPH�RI�WKH�ILOHKDQGOH�\RX�ZDQW�WR�UHDG�

my $name = "FRED";my @lines = <$name>; ## an indirect filehandle read of FRED handle

:LQGRZV�XVHUV�PD\�EH�DFFXVWRPHG�WR�XVLQJ�D�JORE�RI� � �WR�PHDQ�£DOO�ILOHV�¤�%XW�WKDW�DFWXDOO\�PHDQV�£DOO�ILOHVZLWK�D�GRW�LQ�WKHLU�QDPHV�¤�HYHQ�LQ�3HUO�RQ�:LQGRZV�

� 2U�LW�ZLOO�FDOO�D�YDOLG�VXEVWLWXWH�LI�D�&�VKHOO�ZDVQ¦W�DYDLODEOH�

® ,I�WKH�LQGLUHFW�KDQGOH�LV�D�WH[W�VWULQJ��WKHQ�LW¦V�VXEMHFW�WR�WKH�£V\PEROLF�UHIHUHQFH¤�WHVW�WKDW�LV�IRUELGGHQ�XQGHUuse strict��+RZHYHU��WKH�LQGLUHFW�KDQGOH�PLJKW�DOVR�EH�D�W\SHJORE�RU�UHIHUHQFH�WR�DQ�,�2�REMHFW��DQG�WKHQ�LWZRXOG�ZRUN�HYHQ�XQGHU�use strict�

An Alternate Syntax for Globbing | 193

'HWHUPLQLQJ�ZKHWKHU�LW¦V�D�JORE�RU�D�ILOHKDQGOH�UHDG�LV�GRQH�DW�FRPSLOH�WLPH��DQG�WKXVLW�LV�LQGHSHQGHQW�RI�WKH�FRQWHQW�RI�WKH�YDULDEOHV�

,I�\RX�ZDQW��\RX�FDQ�JHW�WKH�RSHUDWLRQ�RI�DQ�LQGLUHFW�ILOHKDQGOH�UHDG�XVLQJ�WKH�readline�RSHUDWRU� �ZKLFK�DOVR�PDNHV�LW�FOHDUHU�

my $name = "FRED";my @lines = readline FRED; ## read from FREDmy @lines = readline $name; ## read from FRED

%XW�WKH�readline�RSHUDWRU�LV�UDUHO\�XVHG��DV�LQGLUHFW�ILOHKDQGOH�UHDGV�DUH�XQFRPPRQDQG�DUH�JHQHUDOO\�SHUIRUPHG�DJDLQVW�D�VLPSOH�VFDODU�YDULDEOH�DQ\ZD\�

Directory Handles$QRWKHU�ZD\�WR�JHW�D�OLVW�RI�QDPHV�IURP�D�JLYHQ�GLUHFWRU\�LV�ZLWK�D�GLUHFWRU\�KDQGOH��$GLUHFWRU\�KDQGOH�ORRNV�DQG�DFWV�OLNH�D�ILOHKDQGOH��<RX�RSHQ�LW��ZLWK�opendir�LQVWHDG�RIopen���\RX�UHDG�IURP�LW��ZLWK�readdir�LQVWHDG�RI�readline���DQG�\RX�FORVH�LW��ZLWK�closedir�LQVWHDG�RI�close���%XW�LQVWHDG�RI�UHDGLQJ�WKH�FRQWHQWV�RI�D�ILOH��\RX¦UH�UHDGLQJ�WKHQDPHV�RI�ILOHV��DQG�RWKHU�WKLQJV��LQ�D�GLUHFWRU\��)RU�H[DPSOH�

my $dir_to_process = "/etc";opendir DH, $dir_to_process or die "Cannot open $dir_to_process: $!";foreach $file (readdir DH) { print "one file in $dir_to_process is $file\n";}closedir DH;

/LNH�ILOHKDQGOHV��GLUHFWRU\�KDQGOHV�DUH�DXWRPDWLFDOO\�FORVHG�DW�WKH�HQG�RI�WKH�SURJUDPRU�LI�WKH�GLUHFWRU\�KDQGOH�LV�UHRSHQHG�RQWR�DQRWKHU�GLUHFWRU\�

8QOLNH�JOREELQJ��ZKLFK�LQ�ROGHU�YHUVLRQV�RI�3HUO�ILUHG�RII�D�VHSDUDWH�SURFHVV��D�GLUHFWRU\KDQGOH�QHYHU�ILUHV�RII�DQRWKHU�SURFHVV��6R�LW�PDNHV�WKHP�PRUH�HIILFLHQW�IRU�DSSOLFDWLRQVWKDW�GHPDQG�HYHU\�RXQFH�RI�SRZHU�IURP�WKH�PDFKLQH��+RZHYHU��LW¦V�DOVR�D�ORZHU�OHYHORSHUDWLRQ��PHDQLQJ�WKDW�ZH�KDYH�WR�GR�PRUH�RI�WKH�ZRUN�RXUVHOYHV�

)RU�H[DPSOH��WKH�QDPHV�DUH�UHWXUQHG�LQ�QR�SDUWLFXODU�RUGHU���$QG�WKH�OLVW�LQFOXGHV�DOOILOHV��QRW�MXVW�WKRVH�PDWFKLQJ�D�SDUWLFXODU�SDWWHUQ��OLNH�*.pm�IURP�RXU�JOREELQJ�H[DP�SOHV���,W�LV�DOVR�LQFOXGHV�WKH�GRW�ILOHV��DQG�SDUWLFXODUO\�WKH�GRW�DQG�GRW�GRW�HQWULHV�®�6R�LI�ZH�ZDQWHG�RQO\�WKH�SP�HQGLQJ�ILOHV��ZH�FRXOG�XVH�D�VNLS�RYHU�IXQFWLRQ�LQVLGH�WKH�ORRS�

while ($name = readdir DIR) { next unless $name =~ /\.pm$/;

,I�\RX¦UH�XVLQJ�3HUO�������RU�ODWHU�

� ,W¦V�DFWXDOO\�WKH�XQVRUWHG�RUGHU�RI�WKH�GLUHFWRU\�HQWULHV��VLPLODU�WR�WKH�RUGHU�\RX�JHW�IURP�OV��I�RU�ILQG�

® 'R�QRW�PDNH�WKH�PLVWDNH�RI�PDQ\�ROG�8QL[�SURJUDPV�DQG�SUHVXPH�WKDW�GRW�DQG�GRW�GRW�DUH�DOZD\V�UHWXUQHGDV�WKH�ILUVW�WZR�HQWULHV��VRUWHG�RU�QRW���,I�WKDW�KDGQ¦W�HYHQ�RFFXUUHG�WR�\RX��SUHWHQG�ZH�QHYHU�VDLG�LW�EHFDXVHLW¦V�D�IDOVH�SUHVXPSWLRQ��,Q�IDFW��ZH¦UH�QRZ�VRUU\�IRU�HYHQ�EULQJLQJ�LW�XS�

194 | Chapter 13:ಗDirectory Operations

... more processing ...}

1RWH�KHUH�WKDW�WKH�V\QWD[�LV�WKDW�RI�D�UHJXODU�H[SUHVVLRQ��QRW�D�JORE��$QG�LI�ZH�ZDQWHGDOO�WKH�QRQGRW�ILOHV��ZH�FRXOG�VD\�WKDW�

next if $name =~ /^\./;

2U�LI�ZH�ZDQWHG�HYHU\WKLQJ�EXW�WKH�FRPPRQ�GRW��FXUUHQW�GLUHFWRU\��DQG�GRW�GRW��SDUHQWGLUHFWRU\��HQWULHV��ZH�FRXOG�H[SOLFLWO\�VD\�WKDW�

next if $name eq "." or $name eq "..";

1RZ�ZH¦OO�ORRN�DW�WKH�SDUW�WKDW�JHWV�PRVW�SHRSOH�PL[HG�XS��VR�SD\�FORVH�DWWHQWLRQ��7KHILOHQDPHV�UHWXUQHG�E\�WKH�readdir�RSHUDWRU�KDYH�QR�SDWKQDPH�FRPSRQHQW��,W¦V�MXVW�WKHQDPH�ZLWKLQ�WKH�GLUHFWRU\��6R��ZH¦UH�QRW�ORRNLQJ�DW��HWF�SDVVZG��ZH¦UH�MXVW�ORRNLQJ�DWSDVVZG���$QG�EHFDXVH�WKLV�LV�DQRWKHU�GLIIHUHQFH�IURP�WKH�JOREELQJ�RSHUDWLRQ��LW¦V�HDV\WR�VHH�KRZ�SHRSOH�JHW�FRQIXVHG��

6R�\RX¦OO�QHHG�WR�SDWFK�XS�WKH�QDPH�WR�JHW�WKH�IXOO�QDPH�

opendir SOMEDIR, $dirname or die "Cannot open $dirname: $!";while (my $name = readdir SOMEDIR) { next if $name =~ /^\./; # skip over dot files $name = "$dirname/$name"; # patch up the path next unless -f $name and -r $name; # only readable files ...}

:LWKRXW�WKH�SDWFK��WKH�ILOH�WHVWV�ZRXOG�KDYH�EHHQ�FKHFNLQJ�ILOHV�LQ�WKH�FXUUHQW�GLUHFWRU\�UDWKHU�WKDQ�LQ�WKH�GLUHFWRU\�QDPHG�LQ�$dirname��7KLV�LV�WKH�VLQJOH�PRVW�FRPPRQ�PLVWDNHZKHQ�XVLQJ�GLUHFWRU\�KDQGOHV�

Recursive Directory Listing<RX�SUREDEO\�ZRQ¦W�QHHG�UHFXUVLYH�GLUHFWRU\�DFFHVV�IRU�WKH�ILUVW�IHZ�GR]HQ�KRXUV�RI\RXU�3HUO�SURJUDPPLQJ�FDUHHU��6R�UDWKHU�WKDQ�GLVWUDFW�\RX�ZLWK�WKH�SRVVLELOLW\�RI�UH�SODFLQJ�DOO�WKRVH�XJO\�ILQG�VFULSWV�ZLWK�3HUO�ULJKW�QRZ��ZH¦OO�VLPSO\�HQWLFH�\RX�E\�VD\LQJWKDW�3HUO�FRPHV�ZLWK�D�QLFH�OLEUDU\�FDOOHG�File::Find��ZKLFK�\RX�FDQ�XVH�IRU�QLIW\�UH�FXUVLYH�GLUHFWRU\�SURFHVVLQJ��:H¦UH�DOVR�VD\LQJ�WKLV�WR�NHHS�\RX�IURP�ZULWLQJ�\RXU�RZQURXWLQHV¢ZKLFK�HYHU\RQH�VHHPV�WR�ZDQW�WR�GR�DIWHU�WKRVH�ILUVW� IHZ�GR]HQ�KRXUV�RISURJUDPPLQJ¢DQG�WKHQ�JHWWLQJ�SX]]OHG�DERXW�WKLQJV�OLNH�£ORFDO�GLUHFWRU\�KDQGOHV¤DQG�£KRZ�GR�,�FKDQJH�P\�GLUHFWRU\�EDFN"¤

Manipulating Files and Directories3HUO�LV�FRPPRQO\�XVHG�WR�ZUDQJOH�ILOHV�DQG�GLUHFWRULHV��%HFDXVH�3HUO�JUHZ�XS�LQ�D�8QL[HQYLURQPHQW�DQG�VWLOO� VSHQGV�PRVW�RI� LWV� WLPH�WKHUH��PRVW�RI� WKH�GHVFULSWLRQ� LQ�WKLVFKDSWHU�PD\�VHHP�8QL[�FHQWULF��%XW�WKH�QLFH�WKLQJ�LV�WKDW�WR�ZKDWHYHU�GHJUHH�SRVVLEOH�3HUO�ZRUNV�H[DFWO\�WKH�VDPH�ZD\�RQ�QRQ�8QL[�V\VWHPV�

Recursive Directory Listing | 195

Removing Files0RVW�RI�WKH�WLPH��ZH�PDNH�ILOHV�VR�WKDW�WKH�GDWD�FDQ�VWD\�DURXQG�IRU�D�ZKLOH��%XW�ZKHQWKH�GDWD�KDV�RXWOLYHG�LWV�OLIH��LW¦V�WLPH�WR�PDNH�WKH�ILOH�JR�DZD\��$W�WKH�8QL[�VKHOO�OHYHO�ZH¦G�W\SH�DQ�UP�FRPPDQG�WR�UHPRYH�D�ILOH�RU�ILOHV�

$ rm slate bedrock lava

,Q�3HUO��ZH�XVH�WKH�unlink�RSHUDWRU�

unlink "slate", "bedrock", "lava";

7KLV�VHQGV�WKH�WKUHH�QDPHG�ILOHV�DZD\�WR�ELW�KHDYHQ��QHYHU�WR�EH�VHHQ�DJDLQ�

1RZ��VLQFH�unlink�WDNHV�D�OLVW��DQG�WKH�glob�IXQFWLRQ�UHWXUQV�D�OLVW��ZH�FDQ�FRPELQH�WKHWZR�WR�GHOHWH�PDQ\�ILOHV�DW�RQFH�

unlink glob "*.o";

7KLV�LV�VLPLODU�WR�rm *.o�DW�WKH�VKHOO��H[FHSW�WKDW�ZH�GLGQ¦W�KDYH�WR�ILUH�RII�D�VHSDUDWHUP�SURFHVV��6R�ZH�FDQ�PDNH�WKRVH�LPSRUWDQW�ILOHV�JR�DZD\�WKDW�PXFK�IDVWHU�

7KH�UHWXUQ�YDOXH�IURP�unlink�WHOOV�XV�KRZ�PDQ\�ILOHV�KDYH�EHHQ�VXFFHVVIXOO\�GHOHWHG�6R��JRLQJ�EDFN�WR�WKH�ILUVW�H[DPSOH��ZH�FDQ�FKHFN�LWV�VXFFHVV�

my $successful = unlink "slate", "bedrock", "lava";print "I deleted $successful file(s) just now\n";

6XUH��LI�WKLV�QXPEHU�LV�3��ZH�NQRZ�LW�UHPRYHG�DOO�RI�WKH�ILOHV��DQG�LI�LW¦V�0��WKHQ�ZH�UHPRYHGQRQH�RI� WKHP��%XW�ZKDW� LI� LW¦V�1� RU�2"�:HOO�� WKHUH¦V�QR� FOXH� DV� WR�ZKLFK�RQHV�ZHUHUHPRYHG��,I�\RX�QHHG�WR�NQRZ��GR�WKHP�RQH�DW�D�WLPH�LQ�D�ORRS�

foreach my $file (qw(slate bedrock lava)) { unlink $file or warn "failed on $file: $!\n";}

+HUH��HDFK�ILOH�EHLQJ�GHOHWHG�RQH�DW�D�WLPH�PHDQV�WKH�UHWXUQ�YDOXH�ZLOO�EH�0��IDLOHG��RU1��VXFFHHGHG���ZKLFK�KDSSHQV�WR�ORRN�OLNH�D�QLFH�%RROHDQ�YDOXH��FRQWUROOLQJ�WKH�H[HFX�WLRQ�RI�warn��8VLQJ�or warn�LV�VLPLODU�WR�or die��H[FHSW�WKDW�LW¦V�QRW�IDWDO��RI�FRXUVH��DVZH�VDLG�EDFN�LQ�&KDSWHU�����,Q�WKLV�FDVH��ZH�SXW�WKH�QHZOLQH�RQ�WKH�HQG�RI�WKH�PHVVDJHWR�ZDUQ�EHFDXVH�LW¦V�QRW�D�EXJ�LQ�RXU�SURJUDP�WKDW�FDXVHV�WKH�PHVVDJH�

:KHQ�D�SDUWLFXODU�unlink�IDLOV��WKH�$!�YDULDEOH�LV�VHW�WR�VRPHWKLQJ�UHODWHG�WR�WKH�RSHUDWLQJV\VWHP�HUURU��ZKLFK�ZH¦YH�LQFOXGHG�LQ�WKH�PHVVDJH��7KLV�PDNHV�VHQVH�WR�XVH�RQO\�ZKHQGRLQJ�RQH�ILOHQDPH�DW�D�WLPH�EHFDXVH�WKH�QH[W�RSHUDWLQJ�V\VWHP�IDLOHG�UHTXHVW�UHVHWVWKH�YDULDEOH��<RX�FDQ¦W�UHPRYH�D�GLUHFWRU\�ZLWK�unlink��MXVW�OLNH�\RX�FDQ¦W�UHPRYH�DGLUHFWRU\�ZLWK�WKH�VLPSOH�UP�LQYRFDWLRQ�HLWKHU���/RRN�IRU�WKH�rmdir�IXQFWLRQ�FRPLQJ�XSVKRUWO\�IRU�WKDW�

1RZ��KHUH¦V�D�OLWWOH�NQRZQ�8QL[�IDFW��,W�WXUQV�RXW�WKDW�\RX�FDQ�KDYH�D�ILOH�WKDW�\RX�FDQ¦WUHDG��\RX�FDQ¦W�ZULWH��\RX�FDQ¦W�H[HFXWH��PD\EH�\RX�GRQ¦W�HYHQ�RZQ�WKH�ILOH¢WKDW�LV�LW¦V� VRPHERG\� HOVH¦V� ILOH� DOWRJHWKHU¢EXW� \RX� FDQ� VWLOO� GHOHWH� LW�� 7KDW¦V� EHFDXVH� WKH

196 | Chapter 13:ಗDirectory Operations

SHUPLVVLRQ�WR�XQOLQN�D�ILOH�GRHVQ¦W�GHSHQG�XSRQ�WKH�SHUPLVVLRQ�ELWV�RQ�WKH�ILOH�LWVHOI�LW¦V�WKH�SHUPLVVLRQ�ELWV�RQ�WKH�GLUHFWRU\�WKDW�FRQWDLQV�WKH�ILOH�WKDW�PDWWHUV�

:H�PHQWLRQ�WKLV�EHFDXVH�LW¦V�QRUPDO�IRU�D�EHJLQQLQJ�3HUO�SURJUDPPHU��LQ�WKH�FRXUVHRI�WU\LQJ�RXW�unlink��WR�PDNH�D�ILOH��WR�FKPRG�LW�WR�0��VR�WKDW�LW¦V�QRW�UHDGDEOH�RU�ZULWDEOH��DQG�WKHQ�WR�VHH�ZKHWKHU�WKLV�PDNHV�unlink�IDLO��%XW�LQVWHDG�LW�YDQLVKHV�ZLWKRXW�VR�PXFKDV�D�ZKLPSHU� �,I�\RX�UHDOO\�ZDQW�WR�VHH�D�IDLOHG�unlink��WKRXJK��MXVW�WU\�WR�UHPRYH��HWF�SDVVZG�RU�D�VLPLODU�V\VWHP�ILOH��6LQFH�WKDW¦V�D�ILOH�FRQWUROOHG�E\�WKH�V\VWHP�DGPLQLVWUDWRU�\RX�ZRQ¦W�EH�DEOH�WR�UHPRYH�LW��

Renaming Files*LYLQJ�DQ�H[LVWLQJ�ILOH�D�QHZ�QDPH�LV�VLPSOH�ZLWK�WKH�rename�IXQFWLRQ�

rename "old", "new";

7KLV�LV�VLPLODU�WR�WKH�8QL[�PY�FRPPDQG��WDNLQJ�D�ILOH�QDPHG�ROG�DQG�JLYLQJ�LW�WKH�QDPHQHZ�LQ�WKH�VDPH�GLUHFWRU\��<RX�FDQ�HYHQ�PRYH�WKLQJV�DURXQG�

rename "over_there/some/place/some_file", "some_file";

7KLV�PRYHV�D�ILOH�FDOOHG�some_file�IURP�DQRWKHU�GLUHFWRU\�LQWR�WKH�FXUUHQW�GLUHFWRU\�SURYLGHG�WKH�XVHU�UXQQLQJ�WKH�SURJUDP�KDV�WKH�DSSURSULDWH�SHUPLVVLRQV�®�/LNH�PRVWIXQFWLRQV�WKDW�UHTXHVW�VRPHWKLQJ�RI�WKH�RSHUDWLQJ�V\VWHP��rename�UHWXUQV�IDOVH�LI�LW�IDLOV�DQG�VHWV�$!�ZLWK�WKH�RSHUDWLQJ�V\VWHP�HUURU��VR�\RX�FDQ��DQG�RIWHQ�VKRXOG��XVH�or die�RU�or warn��WR�UHSRUW�WKLV�WR�WKH�XVHU�

2QH�IUHTXHQW�TXHVWLRQ�LQ�WKH�8QL[�VKHOO�XVDJH�QHZVJURXSV�FRQFHUQV�KRZ�WR�UHQDPHHYHU\WKLQJ�WKDW�HQGV�ZLWK��ROG�WR�WKH�VDPH�QDPH�ZLWK��QHZ��+HUH¦V�KRZ�WR�GR�LW�LQ�3HUOQLFHO\�

foreach my $file (glob "*.old") { my $newfile = $file; $newfile =~ s/\.old$/.new/; if (-e $newfile) { warn "can't rename $file to $newfile: $newfile exists\n"; } elsif (rename $file, $newfile) { ## success, do nothing } else { warn "rename $file to $newfile failed: $!\n";

6RPH�RI�WKHVH�IRONV�NQRZ�WKDW�UP�ZRXOG�JHQHUDOO\�DVN�EHIRUH�GHOHWLQJ�VXFK�D�ILOH��%XW�UP�LV�D�FRPPDQG��DQGunlink�LV�D�V\VWHP�FDOO��6\VWHP�FDOOV�QHYHU�DVN�SHUPLVVLRQ��DQG�WKH\�QHYHU�VD\�WKH\¦UH�VRUU\�

� 2I�FRXUVH��LI�\RX¦UH�VLOO\�HQRXJK�WR�WU\�WKLV�NLQG�RI�WKLQJ�ZKHQ�\RX�DUH�ORJJHG�LQ�DV�WKH�V\VWHP�DGPLQLVWUDWRU�\RX�GHVHUYH�ZKDW�\RX�JHW�

® $QG�WKH�ILOHV�PXVW�UHVLGH�RQ�WKH�VDPH�ILOHV\VWHP��<RX¦OO�VHH�ZK\�WKLV�UXOH�H[LVWV�D�OLWWOH�ODWHU�LQ�WKLV�FKDSWHU�

7KLV�LVQ¦W�MXVW�DQ\�ROG�IUHTXHQW�TXHVWLRQ��WKH�TXHVWLRQ�RI�UHQDPLQJ�D�EDWFK�RI�ILOHV�DW�RQFH�LV�WKH�PRVW�IUHTXHQWTXHVWLRQ�DVNHG�LQ�WKHVH�QHZVJURXSV��$QG�WKDW¦V�ZK\�LW¦V�WKH�ILUVW�TXHVWLRQ�DQVZHUHG�LQ�WKH�)$4V�IRU�WKRVHQHZVJURXSV��$QG�\HW��LW�VWD\V�LQ�ILUVW�SODFH��+PPP�

Renaming Files | 197

}}

7KH�FKHFN�IRU�WKH�H[LVWHQFH�RI�$newfile�LV�QHHGHG�EHFDXVH�rename�ZLOO�KDSSLO\�UHQDPHD�ILOH�ULJKW�RYHU�WKH�WRS�RI�DQ�H[LVWLQJ�ILOH��SUHVXPLQJ�WKH�XVHU�KDV�SHUPLVVLRQ�WR�UHPRYHWKH�GHVWLQDWLRQ� ILOHQDPH��:H�SXW� WKH�FKHFN� LQ� VR� WKDW� LW¦V� OHVV� OLNHO\� WKDW�ZH¦OO� ORVHLQIRUPDWLRQ� WKLV� ZD\�� 2I� FRXUVH�� LI� \RX� ZDQWHG� WR� UHSODFH� H[LVWLQJ� ILOHV� OLNHZLOPD�QHZ��\RX�ZRXOGQ¦W�ERWKHU�WHVWLQJ�ZLWK�-e�ILUVW�

7KRVH�ILUVW�WZR�OLQHV�LQVLGH�WKH�ORRS�FDQ�EH�FRPELQHG��DQG�RIWHQ�DUH��WR�VLPSO\�

(my $newfile = $file) =~ s/\.old$/.new/;

7KLV� ZRUNV� WR� GHFODUH� $newfile�� FRS\� LWV� LQLWLDO� YDOXH� IURP� $file�� WKHQ� PRGLI\$newfile�ZLWK�WKH�VXEVWLWXWLRQ��<RX�FDQ�UHDG�WKLV�DV�£WUDQVIRUP�$file�WR�$newfile�XVLQJWKLV�UHSODFHPHQW�RQ�WKH�ULJKW�¤�$QG�\HV��EHFDXVH�RI�SUHFHGHQFH��WKRVH�SDUHQWKHVHV�DUHUHTXLUHG�

$OVR��VRPH�SURJUDPPHUV�VHHLQJ� WKLV�VXEVWLWXWLRQ� IRU� WKH� ILUVW� WLPH�ZRQGHU�ZK\�WKHEDFNVODVK�LV�QHHGHG�RQ�WKH�OHIW��EXW�QRW�RQ�WKH�ULJKW��7KH�WZR�VLGHV�DUHQ¦W�V\PPHWULFDO�WKH�OHIW�SDUW�RI�D�VXEVWLWXWLRQ�LV�D�UHJXODU�H[SUHVVLRQ��DQG�WKH�ULJKW�SDUW�LV�D�GRXEOH�TXRWHG�VWULQJ��6R�ZH�XVH�WKH�SDWWHUQ�/\.old$/�WR�PHDQ�£.old�DQFKRUHG�DW�WKH�HQG�RI�WKHVWULQJ¤��DQFKRUHG�DW� WKH�HQG�EHFDXVH�ZH�GRQ¦W�ZDQW� WR�UHQDPH�WKH� ILUVW�RFFXUUHQFHRI�.old�LQ�D�ILOH�FDOOHG�EHWW\�ROG�ROG���EXW�RQ�WKH�ULJKW�ZH�FDQ�VLPSO\�ZULWH�.new�WR�PDNHWKH�UHSODFHPHQW�

Links and Files7R� XQGHUVWDQG�PRUH� DERXW� ZKDW¦V� JRLQJ� RQ� ZLWK� ILOHV� DQG� GLUHFWRULHV�� LW� KHOSV� WRXQGHUVWDQG� WKH�8QL[�PRGHO� RI� ILOHV� DQG� GLUHFWRULHV�� HYHQ� LI� \RXU� QRQ�8QL[� V\VWHPGRHVQ¦W�ZRUN�LQ�H[DFWO\�WKLV�ZD\��$V�XVXDO��WKHUH¦V�PRUH�WR�WKH�VWRU\�WKDQ�ZH¦UH�DEOH�WRH[SODLQ�KHUH��VR�FKHFN�DQ\�JRRG�ERRN�RQ�8QL[�LQWHUQDO�GHWDLOV�LI�\RX�QHHG�WKH�IXOO�VWRU\�

$�PRXQWHG�YROXPH�LV�D�KDUG�GLVN�GULYH��RU�VRPHWKLQJ�HOVH�WKDW�ZRUNV�PRUH�RU�OHVV�OLNHWKDW�� VXFK�DV�D�GLVN�SDUWLWLRQ��D� IORSS\�GLVN��D�&'�520��RU�D�'9'�520��� ,W�PD\FRQWDLQ�DQ\�QXPEHU�RI�ILOHV�DQG�GLUHFWRULHV��(DFK�ILOH�LV�VWRUHG�LQ�D�QXPEHUHG�LQRGH�ZKLFK�ZH�FDQ�WKLQN�RI�DV�D�SDUWLFXODU�SLHFH�RI�GLVN�UHDO�HVWDWH��2QH�ILOH�PLJKW�EH�VWRUHGLQ�LQRGH������ZKLOH�DQRWKHU�LV�LQ�LQRGH������

198 | Chapter 13:ಗDirectory Operations

7R�ORFDWH�D�SDUWLFXODU�ILOH��WKRXJK��ZH¦OO�KDYH�WR�ORRN�LW�XS�LQ�D�GLUHFWRU\��$�GLUHFWRU\�LVD�VSHFLDO�NLQG�RI�ILOH��PDLQWDLQHG�E\�WKH�V\VWHP��(VVHQWLDOO\��LW�LV�D�WDEOH�RI�ILOHQDPHVDQG�WKHLU�LQRGH�QXPEHUV� �$ORQJ�ZLWK�WKH�RWKHU�WKLQJV�LQ�WKH�GLUHFWRU\��WKHUH�DUH�DOZD\VWZR�VSHFLDO�GLUHFWRU\�HQWULHV��2QH�LV�.��FDOOHG�£GRW¤���ZKLFK�LV�WKH�QDPH�RI�WKDW�YHU\GLUHFWRU\�� WKH�RWKHU� LV�..� �£GRW�GRW¤���ZKLFK� LV� WKH�GLUHFWRU\�RQH� VWHS�KLJKHU� LQ� WKHKLHUDUFK\��L�H���WKH�GLUHFWRU\¦V�SDUHQW�GLUHFWRU\����)LJXUH������SURYLGHV�DQ�LOOXVWUDWLRQRI�WZR�LQRGHV��2QH�LV�IRU�D�ILOH�FDOOHG�FKLFNHQ��DQG�WKH�RWKHU�LV�%DUQH\¦V�GLUHFWRU\�RISRHPV���KRPH�EDUQH\�SRHPV��ZKLFK�FRQWDLQV�WKDW�ILOH��7KH�ILOH�LV�VWRUHG�LQ�LQRGH�����ZKLOH�WKH�GLUHFWRU\�LV�VWRUHG�LQ�LQRGH�������7KH�GLUHFWRU\¦V�RZQ�QDPH��SRHPV��GRHVQ¦WDSSHDU�LQ�WKH�LOOXVWUDWLRQ�EHFDXVH�LW¦V�VWRUHG�LQ�DQRWKHU�GLUHFWRU\���7KH�GLUHFWRU\�FRQ�WDLQV�HQWULHV�IRU�WKUHH�ILOHV��LQFOXGLQJ�FKLFNHQ��DQG�WZR�GLUHFWRULHV��RQH�RI�ZKLFK�LV�WKHUHIHUHQFH� EDFN� WR� WKH� GLUHFWRU\� LWVHOI�� LQ� LQRGH� ������ DORQJ�ZLWK� HDFK� LWHP¦V� LQRGHQXPEHU�

A Jurassic chicken named MegWith two beaks, three wings, and one leg, As her third eye she winked, Quoth “I’ll soon go extinct,But I’ll lay first a cubical egg.”

inode 6131

inode 9192

.

. .dodgsonchickenabacus

9198002703361311320

)LJXUH�������7KH�FKLFNHQ�EHIRUH�WKH�HJJ

:KHQ�LW¦V�WLPH�WR�PDNH�D�QHZ�ILOH�LQ�D�JLYHQ�GLUHFWRU\��WKH�V\VWHP�DGGV�DQ�HQWU\�ZLWKWKH�ILOH¦V�QDPH�DQG�WKH�QXPEHU�RI�D�QHZ�LQRGH��+RZ�FDQ�WKH�V\VWHP�WHOO�WKDW�D�SDUWLFXODULQRGH�LV�DYDLODEOH�WKRXJK"�(DFK�LQRGH�KROGV�D�QXPEHU�FDOOHG�LWV�OLQN�FRXQW��7KH�OLQNFRXQW�LV�DOZD\V�]HUR�LI�WKH�LQRGH�LVQ¦W�OLVWHG�LQ�DQ\�GLUHFWRU\��VR�DQ\�LQRGH�ZLWK�D�OLQNFRXQW�RI�]HUR�LV�DYDLODEOH�IRU�QHZ�ILOH�VWRUDJH��:KHQ�WKH�LQRGH�LV�DGGHG�WR�D�GLUHFWRU\�WKH�OLQN�FRXQW�LV�LQFUHPHQWHG��ZKHQ�WKH�OLVWLQJ�LV�UHPRYHG��WKH�OLQN�FRXQW�LV�GHFUHPHQ�WHG��)RU�WKH�ILOH�FKLFNHQ�DV�LOOXVWUDWHG�DERYH��WKH�LQRGH�FRXQW�RI���LV�VKRZQ�LQ�WKH�ER[DERYH�WKH�LQRGH¦V�GDWD�

2Q�8QL[�V\VWHPV��RWKHUV�GRQ¦W�JHQHUDOO\�KDYH�LQRGHV��KDUG�OLQNV��DQG�VXFK���\RX�FDQ�XVH�WKH�OV�FRPPDQG¦V-i�RSWLRQ�WR�VHH�ILOHV¦�LQRGH�QXPEHUV��7U\�D�FRPPDQG�OLNH�OV��DLO��:KHQ�WZR�RU�PRUH�LQRGH�QXPEHUV�DUH�WKHVDPH�IRU�PXOWLSOH�LWHPV�RQ�D�JLYHQ�ILOHV\VWHP��WKHUH¦V�UHDOO\�MXVW�RQH�ILOH�LQYROYHG��RQH�SLHFH�RI�WKH�GLVN�

� 7KH�8QL[�V\VWHP�URRW�GLUHFWRU\�KDV�QR�SDUHQW��,Q�WKDW�GLUHFWRU\��..�LV�WKH�VDPH�GLUHFWRU\�DV�.��ZKLFK�LV�WKHV\VWHP�URRW�GLUHFWRU\�LWVHOI�

Links and Files | 199

%XW�VRPH�LQRGHV�KDYH�PRUH�WKDQ�RQH�OLVWLQJ��)RU�H[DPSOH��ZH¦YH�DOUHDG\�VHHQ�WKDW�HDFKGLUHFWRU\�HQWU\�LQFOXGHV�.��ZKLFK�SRLQWV�EDFN�WR�WKDW�GLUHFWRU\¦V�RZQ�LQRGH��6R�WKH�OLQNFRXQW�IRU�D�GLUHFWRU\�VKRXOG�DOZD\V�EH�DW�OHDVW�WZR��LWV�OLVWLQJ�LQ�LWV�SDUHQW�GLUHFWRU\�DQGLWV�OLVWLQJ�LQ�LWVHOI��,Q�DGGLWLRQ��LI�LW�KDV�VXEGLUHFWRULHV��HDFK�RI�WKRVH�ZLOO�DGG�D�OLQN�VLQFH�HDFK�ZLOO�FRQWDLQ�..� �,Q�)LJXUH�������WKH�GLUHFWRU\¦V�LQRGH�FRXQW�RI�2�LV�VKRZQ�LQWKH�ER[�DERYH�LWV�GDWD��$�OLQN�FRXQW�LV�WKH�QXPEHU�RI�WUXH�QDPHV�IRU�WKH�LQRGH���&RXOGDQ�RUGLQDU\�ILOH�LQRGH�KDYH�PRUH�WKDQ�RQH�OLVWLQJ�LQ�WKH�GLUHFWRU\"�,W�FHUWDLQO\�FRXOG�6XSSRVH�WKDW��ZRUNLQJ�LQ�WKH�GLUHFWRU\�VKRZQ�DERYH��%DUQH\�XVHV�WKH�3HUO�link�IXQFWLRQWR�FUHDWH�D�QHZ�OLQN�

link "chicken", "egg" or warn "can't link chicken to egg: $!";

7KLV�LV�VLPLODU�WR�W\SLQJ�"ln chicken egg" DW�WKH�8QL[�VKHOO�SURPSW��,I�link�VXFFHHGV�LW�UHWXUQV�WUXH��,I�LW�IDLOV��LW�UHWXUQV�IDOVH�DQG�VHWV�$!��ZKLFK�%DUQH\�LV�FKHFNLQJ�LQ�WKHHUURU�PHVVDJH��$IWHU�WKLV�UXQV��WKH�QDPH�HJJ�LV�DQRWKHU�QDPH�IRU�WKH�ILOH�FKLFNHQ��DQGYLFH�YHUVD��QHLWKHU�QDPH�LV�£PRUH�UHDO¤�WKDQ�WKH�RWKHU��DQG��DV�\RX�PD\�KDYH�JXHVVHG�LW�ZRXOG�WDNH�VRPH�GHWHFWLYH�ZRUN�WR�ILQG�RXW�ZKLFK�FDPH�ILUVW��)LJXUH������VKRZV�DSLFWXUH�RI�WKH�QHZ�VLWXDWLRQ��ZKHUH�WKHUH�DUH�WZR�OLQNV�WR�LQRGH�����

7KHVH� WZR� ILOHQDPHV� DUH� WKXV� WDONLQJ� DERXW� WKH� VDPH� SODFH� RQ� WKH� GLVN�� ,I� WKH� ILOHFKLFNHQ�KROGV�����E\WHV�RI�GDWD��HJJ�KROGV�WKH�VDPH�����E\WHV��IRU�D�WRWDO�RI�����E\WHV�VLQFH�LW¦V�UHDOO\�MXVW�RQH�ILOH�ZLWK�WZR�QDPHV���,I�%DUQH\�DSSHQGV�D�QHZ�OLQH�RI�WH[W�WRILOH�HJJ��WKDW�OLQH�ZLOO�DOVR�DSSHDU�DW�WKH�HQG�RI�FKLFNHQ�®�1RZ��LI�%DUQH\�ZHUH�WR�DFFL�GHQWDOO\��RU�LQWHQWLRQDOO\��GHOHWH�FKLFNHQ��WKDW�GDWD�ZLOO�QRW�EH�ORVW¢LW¦V�VWLOO�DYDLODEOH

7KLV�LPSOLHV�WKDW�WKH�OLQN�FRXQW�RI�D�GLUHFWRU\�LV�DOZD\V�HTXDO�WR�WZR�SOXV�WKH�QXPEHU�RI�GLUHFWRULHV�LW�FRQWDLQV�2Q�VRPH�V\VWHPV�WKDW¦V�WUXH��LQ�IDFW��EXW�VRPH�RWKHU�V\VWHPV�ZRUN�GLIIHUHQWO\�

� ,Q�WKH�WUDGLWLRQDO�RXWSXW�RI�OV��O��WKH�QXPEHU�RI�KDUG�OLQNV�WR�WKH�LWHP�DSSHDUV�MXVW�WR�WKH�ULJKW�RI�WKH�SHUPLVVLRQIODJV��OLNH�-rwxr-xr-x���1RZ�\RX�NQRZ�ZK\�WKLV�QXPEHU�LV�PRUH�WKDQ�RQH�IRU�GLUHFWRULHV�DQG�QHDUO\�DOZD\V1�IRU�RUGLQDU\�ILOHV�

® ,I�\RX�H[SHULPHQW�ZLWK�PDNLQJ�OLQNV�DQG�FKDQJLQJ�WH[W�ILOHV��EH�DZDUH�WKDW�PRVW�WH[W�HGLWRUV�GRQ¦W�HGLW�WKHILOH�£LQ�SODFH¤�EXW�LQVWHDG�VDYH�D�PRGLILHG�FRS\��,I�%DUQH\�ZHUH�WR�HGLW�HJJ�ZLWK�D�WH[W�HGLWRU��KH¦G�PRVW�OLNHO\HQG�XS�ZLWK�D�QHZ�ILOH�FDOOHG�HJJ�DQG�WKH�ROG�ILOH�FDOOHG�FKLFNHQ¢WZR�VHSDUDWH�ILOHV��UDWKHU�WKDQ�WZR�OLQNV�WRWKH�VDPH�ILOH�

A Jurassic chicken named MegWith two beaks, three wings, and one leg, As her third eye she winked, Quoth “I’ll soon go extinct,But I’ll lay first a cubical egg.”

inode 6132

inode 9192

.

. .dodgsonchickenabacusegg

9198002703361311320613

)LJXUH�������7KH�HJJ�LV�OLQNHG�WR�WKH�FKLFNHQ

200 | Chapter 13:ಗDirectory Operations

XQGHU�WKH�QDPH�HJJ��$QG�YLFH�YHUVD��LI�KH�ZHUH�WR�GHOHWH�HJJ��KH¦G�VWLOO�KDYH�FKLFNHQ��2IFRXUVH��LI�KH�GHOHWHV�ERWK�RI�WKHP��WKH�GDWD�ZLOO�EH�ORVW� �7KHUH¦V�DQRWKHU�UXOH�DERXW�WKHOLQNV� LQ�GLUHFWRU\� OLVWLQJV�� WKH� LQRGH�QXPEHUV� LQ�D�JLYHQ�GLUHFWRU\� OLVWLQJ�DOO� UHIHU� WRLQRGHV�RQ�WKDW�VDPH�PRXQWHG�YROXPH���7KLV�UXOH�HQVXUHV�WKDW�LI�WKH�SK\VLFDO�PHGLXP�WKH�GLVNHWWH��SHUKDSV��LV�PRYHG�WR�DQRWKHU�PDFKLQH��DOO�RI�WKH�GLUHFWRULHV�VWLFN�WRJHWKHUZLWK�WKHLU�ILOHV��7KDW¦V�ZK\�\RX�FDQ�XVH�rename�WR�PRYH�D�ILOH�IURP�RQH�GLUHFWRU\�WRDQRWKHU��EXW�RQO\�LI�ERWK�GLUHFWRULHV�DUH�RQ�WKH�VDPH�ILOHV\VWHP��PRXQWHG�YROXPH���,IWKH\�ZHUH�RQ�GLIIHUHQW�GLVNV��WKH�V\VWHP�ZRXOG�KDYH�WR�UHORFDWH�WKH�LQRGH¦V�GDWD��ZKLFKLV�WRR�FRPSOH[�DQ�RSHUDWLRQ�IRU�D�VLPSOH�V\VWHP�FDOO�

$QG�\HW�DQRWKHU�UHVWULFWLRQ�RQ�OLQNV�LV�WKDW�WKH\�FDQ¦W�PDNH�QHZ�QDPHV�IRU�GLUHFWRULHV�7KDW¦V�EHFDXVH�WKH�GLUHFWRULHV�DUH�DUUDQJHG�LQ�D�KLHUDUFK\��,I�\RX�ZHUH�DEOH�WR�FKDQJHWKDW��XWLOLW\�SURJUDPV�OLNH�ILQG�DQG�SZG�FRXOG�HDVLO\�EHFRPH�ORVW�WU\LQJ�WR�ILQG�WKHLU�ZD\DURXQG�WKH�ILOHV\VWHP�

6R��OLQNV�FDQ¦W�EH�DGGHG�WR�GLUHFWRULHV��DQG�WKH\�FDQ¦W�FURVV�IURP�RQH�PRXQWHG�YROXPHWR�DQRWKHU��)RUWXQDWHO\��WKHUH¦V�D�ZD\�WR�JHW�DURXQG�WKHVH�UHVWULFWLRQV�RQ�OLQNV��E\�XVLQJD�QHZ�DQG�GLIIHUHQW�NLQG�RI�OLQN��D�V\PEROLF�OLQN�®�$�V\PEROLF�OLQN��DOVR�FDOOHG�D�VRIWOLQN�WR�GLVWLQJXLVK�LW�IURP�WKH�WUXH�RU�KDUG�OLQNV�WKDW�ZH¦YH�EHHQ�WDONLQJ�DERXW�XS�WRQRZ��LV�D�VSHFLDO�HQWU\�LQ�D�GLUHFWRU\�WKDW�WHOOV�WKH�V\VWHP�WR�ORRN�HOVHZKHUH��/HW¦V�VD\WKDW�%DUQH\��ZRUNLQJ�LQ�WKH�VDPH�GLUHFWRU\�RI�SRHPV�DV�EHIRUH��FUHDWHV�D�V\PEROLF�OLQNZLWK�3HUO¦V�symlink�IXQFWLRQ��OLNH�WKLV�

symlink "dodgson", "carroll" or warn "can't symlink dodgson to carroll: $!";

7KLV�LV�VLPLODU�WR�ZKDW�ZRXOG�KDSSHQ�LI�%DUQH\�XVHG�WKH�FRPPDQG�OQ�V�GRGJVRQ�FDU�UROO�IURP�WKH�VKHOO��)LJXUH������VKRZV�D�SLFWXUH�RI�WKH�UHVXOW��LQFOXGLQJ�WKH�SRHP�LQLQRGH������

1RZ�LI�%DUQH\�FKRRVHV�WR�UHDG��KRPH�EDUQH\�SRHPV�FDUUROO��KH�JHWV�WKH�VDPH�GDWD�DV�LIKH�KDG�RSHQHG��KRPH�EDUQH\�SRHPV�GRGJVRQ�EHFDXVH�WKH�V\VWHP�IROORZV�WKH�V\PEROLFOLQN�DXWRPDWLFDOO\��%XW�WKDW�QHZ�QDPH�LVQ¦W�WKH�£UHDO¤�QDPH�RI�WKH�ILOH�EHFDXVH��DV�\RXFDQ�VHH�LQ�WKH�GLDJUDP��WKH�OLQN�FRXQW�RQ�LQRGH������LV�VWLOO�MXVW�RQH��7KDW¦V�EHFDXVHWKH�V\PEROLF�OLQN�VLPSO\�WHOOV�WKH�V\VWHP��£,I�\RX�JRW�KHUH�ORRNLQJ�IRU�FDUUROO��QRZ�\RXZDQW�WR�JR�RII�WR�ILQG�VRPHWKLQJ�FDOOHG�GRGJVRQ�LQVWHDG�¤

$� V\PEROLF� OLQN�FDQ� IUHHO\� FURVV�PRXQWHG� ILOHV\VWHPV�RU�SURYLGH�D�QHZ�QDPH� IRU� DGLUHFWRU\��XQOLNH�D�KDUG�OLQN��,Q�IDFW��D�V\PEROLF�OLQN�FRXOG�SRLQW�WR�DQ\�ILOHQDPH��RQHLQ�WKLV�GLUHFWRU\�RU�LQ�DQRWKHU�RQH¢RU�HYHQ�WR�D�ILOH�WKDW�GRHVQ¦W�H[LVW��%XW�WKDW�DOVRPHDQV�WKDW�D�VRIW� OLQN�FDQ¦W�NHHS�GDWD� IURP�EHLQJ� ORVW�DV�D�KDUG� OLQN�FDQ��VLQFH�WKH

$OWKRXJK�WKH�V\VWHP�ZRQ¦W�QHFHVVDULO\�RYHUZULWH�WKLV�LQRGH�ULJKW�DZD\��WKHUH¦V�QR�HDV\�ZD\�LQ�JHQHUDO�WR�JHWWKH�GDWD�EDFN�RQFH�WKH�OLQN�FRXQW�KDV�JRQH�WR�]HUR��+DYH�\RX�PDGH�D�EDFNXS�UHFHQWO\"

� 7KH�RQH�H[FHSWLRQ�LV�WKH�VSHFLDO�..�HQWU\�LQ�WKH�YROXPH¦V�URRW�GLUHFWRU\��ZKLFK�UHIHUV�WR�WKH�GLUHFWRU\�LQ�ZKLFKWKDW�YROXPH�LV�PRXQWHG�

® 6RPH�YHU\�ROG�8QL[�V\VWHPV�GRQ¦W�VXSSRUW�V\POLQNV��EXW�WKRVH�DUH�SUHWW\�UDUH�QRZDGD\V�

Links and Files | 201

V\POLQN�GRHVQ¦W�FRQWULEXWH� WR� WKH� OLQN�FRXQW�� ,I�%DUQH\�ZHUH� WR�GHOHWH�GRGJVRQ�� WKHV\VWHP�ZRXOG�QR�ORQJHU�EH�DEOH�WR�IROORZ�WKH�VRIW�OLQN� �(YHQ�WKRXJK�WKHUH�ZRXOG�VWLOOEH� DQ� HQWU\� FDOOHG� FDUUROO�� WU\LQJ� WR� UHDG� IURP� LW�ZRXOG� JLYH� DQ� HUURU� OLNH�file notfound��7KH�ILOH�WHVW�-l 'carroll'�ZRXOG�UHSRUW�WUXH��EXW�-e 'carroll'�ZRXOG�EH�IDOVH�LW¦V�D�V\POLQN��EXW�LW�GRHVQ¦W�H[LVW�

6LQFH�D�VRIW�OLQN�FRXOG�SRLQW�WR�D�ILOH�WKDW�GRHVQ¦W�\HW�H[LVW��LW�FRXOG�EH�XVHG�ZKHQ�FUHDWLQJD�ILOH�DV�ZHOO��%DUQH\�KDV�PRVW�RI�KLV�ILOHV�LQ�KLV�KRPH�GLUHFWRU\���KRPH�EDUQH\��EXW�KHDOVR�QHHGV�IUHTXHQW�DFFHVV�WR�D�GLUHFWRU\�ZLWK�D�ORQJ�QDPH�WKDW�LV�GLIILFXOW�WR�W\SH���XVU�ORFDO�RSW�V\VWHP�KWWSG�URRW�GHY�XVHUV�VWDJLQJ�EDUQH\�FJL�ELQ�� 6R� KH� VHWV� XS� D� V\POLQNQDPHG��KRPH�EDUQH\�P\BVWXII��ZKLFK�SRLQWV�WR�WKDW�ORQJ�QDPH��DQG�QRZ�LW¦V�HDV\�IRUKLP�WR�JHW�WR�LW��,I�KH�FUHDWHV�D�ILOH��IURP�KLV�KRPH�GLUHFWRU\��FDOOHG�P\BVWXII�ERZOLQJ�WKDW�ILOH¦V�UHDO�QDPH�LV��XVU�ORFDO�RSW�V\VWHP�KWWSG�URRW�GHY�XVHUV�VWDJLQJ�EDUQH\�FJL�ELQ�ERZOLQJ�� 1H[W� ZHHN�� ZKHQ� WKH� V\VWHP� DGPLQLVWUDWRU�PRYHV� WKHVH� ILOHV� RI� %DUQH\¦VWR� �XVU�ORFDO�RSW�LQWHUQDO�KWWSG�ZZZ�GHY�XVHUV�VWDJLQJ�EDUQH\�FJL�ELQ�� %DUQH\� MXVW� UH�SRLQWV�WKH�RQH�V\POLQN��DQG�QRZ�KH�DQG�DOO�RI�KLV�SURJUDPV�FDQ�VWLOO�ILQG�KLV�ILOHV�ZLWKHDVH�

,W¦V�QRUPDO�IRU�HLWKHU��XVU�ELQ�SHUO�RU��XVU�ORFDO�ELQ�SHUO��RU�ERWK��WR�EH�V\PEROLF�OLQNVWR�WKH�WUXH�3HUO�ELQDU\�RQ�\RXU�V\VWHP��7KLV�PDNHV�LW�HDV\�WR�VZLWFK�WR�D�QHZ�YHUVLRQ�RI3HUO��6D\�\RX¦UH�WKH�V\VWHP�DGPLQLVWUDWRU��DQG�\RX¦YH�EXLOW�WKH�QHZ�3HUO��2I�FRXUVH�\RXU�ROGHU�YHUVLRQ�LV�VWLOO�UXQQLQJ��DQG�\RX�GRQ¦W�ZDQW�WR�GLVUXSW�DQ\WKLQJ��:KHQ�\RX¦UHUHDG\�IRU�WKH�VZLWFK��\RX�VLPSO\�PRYH�D�V\POLQN�RU�WZR��DQG�QRZ�HYHU\�SURJUDP�WKDWEHJLQV�ZLWK�#!/usr/bin/perl�ZLOO�DXWRPDWLFDOO\�XVH�WKH�QHZ�YHUVLRQ��,Q�WKH�XQOLNHO\FDVH�WKDW�WKHUH¦V�VRPH�SUREOHP��LW¦V�D�VLPSOH�WKLQJ�WR�UHSODFH�WKH�ROG�V\POLQNV�DQG�KDYHWKH�ROGHU�3HUO�UXQQLQJ�WKH�VKRZ�DJDLQ���%XW��OLNH�DQ\�JRRG�DGPLQ��\RX�QRWLILHG�\RXUXVHUV�WR�WHVW�WKHLU�FRGH�ZLWK�WKH�QHZ��XVU�ELQ�SHUO�����ZHOO�LQ�DGYDQFH�RI�WKH�VZLWFK��DQG\RX�WROG�WKHP�WKDW�WKH\�FDQ�NHHS�XVLQJ�WKH�ROGHU�RQH�GXULQJ�WKH�QH[W�PRQWK¦V�JUDFHSHULRG�E\�FKDQJLQJ�WKHLU�SURJUDPV¦�ILUVW�OLQHV�WR�#!/usr/bin/perl-6.1��LI�WKH\�QHHG�WR��

Yet what are all such gaieties to meWhose thoughts are full of indicesand surds?

x2 + 7x + 53

= 11/3

inode 70331

inode 9192

.

. .dodgsonchickenabacuseggcarroll -> dodgson

9198002703361311320613

)LJXUH�������$�V\POLQN�WR�LQRGH�����

'HOHWLQJ�FDUUROO�ZRXOG�PHUHO\�UHPRYH�WKH�V\POLQN��RI�FRXUVH�

202 | Chapter 13:ಗDirectory Operations

3HUKDSV�VXUSULVLQJO\��ERWK�KDUG�DQG�VRIW�OLQNV�DUH�YHU\�XVHIXO��0DQ\�QRQ�8QL[�RSHUDWLQJV\VWHPV�KDYH�QHLWKHU��DQG�WKH�ODFN�LV�VRUHO\�IHOW��2Q�VRPH�QRQ�8QL[�V\VWHPV��V\PEROLFOLQNV�PD\�EH�LPSOHPHQWHG�DV�D�£VKRUWFXW¤�RU�DQ�£DOLDV¤¢FKHFN�WKH�SHUOSRUW�PDQSDJHIRU�WKH�ODWHVW�GHWDLOV�

7R�ILQG�RXW�ZKHUH�D�V\PEROLF�OLQN�LV�SRLQWLQJ��XVH�WKH�readlink�IXQFWLRQ��7KLV�ZLOO�WHOO\RX�ZKHUH�WKH�V\POLQN�OHDGV��RU�LW�ZLOO�UHWXUQ�undef�LI�LWV�DUJXPHQW�ZDVQ¦W�D�V\POLQN�

my $where = readlink "carroll"; # Gives "dodgson"

my $perl = readlink "/usr/local/bin/perl"; # Maybe tells where perl is

<RX�FDQ�UHPRYH�HLWKHU�NLQG�RI�OLQN��ZLWK�unlink¢DQG�QRZ�\RX�VHH�ZKHUH�WKDW�RSHUDWLRQJHWV� LWV�QDPH��unlink� VLPSO\� UHPRYHV� WKH�GLUHFWRU\� HQWU\� DVVRFLDWHG�ZLWK� WKH� JLYHQILOHQDPH��GHFUHPHQWLQJ�WKH�OLQN�FRXQW�DQG�WKXV�SRVVLEO\�IUHHLQJ�WKH�LQRGH�

Making and Removing Directories0DNLQJ�D�GLUHFWRU\�LQVLGH�DQ�H[LVWLQJ�GLUHFWRU\�LV�HDV\��-XVW�LQYRNH�WKH�mkdir�IXQFWLRQ�

mkdir "fred", 0755 or warn "Cannot make fred directory: $!";

$JDLQ��WUXH�PHDQV�VXFFHVV��DQG�$!�LV�VHW�RQ�IDLOXUH�

%XW�ZKDW¦V�WKDW�VHFRQG�SDUDPHWHU��0755"�7KDW¦V�WKH�LQLWLDO�SHUPLVVLRQ�VHWWLQJ �RQ�WKHQHZO\�FUHDWHG�GLUHFWRU\��\RX�FDQ�DOZD\V�FKDQJH�LW�ODWHU���7KH�YDOXH�KHUH�LV�VSHFLILHG�DVDQ�RFWDO�YDOXH�EHFDXVH�WKH�YDOXH�ZLOO�EH�LQWHUSUHWHG�DV�D�8QL[�SHUPLVVLRQ�YDOXH��ZKLFKKDV�D�PHDQLQJ�EDVHG�RQ�JURXSV�RI�WKUHH�ELWV�HDFK��DQG�RFWDO�YDOXHV�UHSUHVHQW�WKDW�QLFHO\�<HV��HYHQ�RQ�:LQGRZV�RU�0DF3HUO��\RX�VWLOO�QHHG�WR�NQRZ�D�OLWWOH�DERXW�8QL[�SHUPLV�VLRQV�YDOXHV�WR�XVH�WKH�mkdir�IXQFWLRQ��0RGH�0755�LV�D�JRRG�RQH�WR�XVH�EHFDXVH�LW�JLYHV\RX�IXOO�SHUPLVVLRQ��EXW�OHWV�HYHU\RQH�HOVH�KDYH�UHDG�DFFHVV�EXW�QR�SHUPLVVLRQ�WR�FKDQJHDQ\WKLQJ�

7KH�mkdir�IXQFWLRQ�GRHVQ¦W�UHTXLUH�\RX�WR�VSHFLI\�WKLV�YDOXH�LQ�RFWDO¢LW¦V�MXVW�ORRNLQJIRU�D�QXPHULF�YDOXH��HLWKHU�D�OLWHUDO�RU�D�FDOFXODWLRQ���%XW�XQOHVV�\RX�FDQ�TXLFNO\�FDQILJXUH�WKDW�0755�RFWDO�LV�493�GHFLPDO�LQ�\RXU�KHDG��LW¦V�SUREDEO\�HDVLHU�WR�OHW�3HUO�FDOFXODWHWKDW��$QG�LI�\RX�DFFLGHQWDOO\�OHDYH�RII�WKH�OHDGLQJ�]HUR��\RX�JHW�755�GHFLPDO��ZKLFK�LV1363�RFWDO��D�VWUDQJH�SHUPLVVLRQ�FRPELQDWLRQ�LQGHHG�

$V�\RX�VDZ�HDUOLHU��LQ�&KDSWHU�����D�VWULQJ�YDOXH�EHLQJ�XVHG�DV�D�QXPEHU�LV�QHYHU�LQWHU�SUHWHG�DV�RFWDO��HYHQ�LI�LW�VWDUWV�ZLWK�D�OHDGLQJ����6R�WKLV�GRHVQ¦W�ZRUN�

my $name = "fred";my $permissions = "0755"; # danger... this isn't workingmkdir $name, $permissions;

7KH�SHUPLVVLRQ�YDOXH�LV�PRGLILHG�E\�WKH�XPDVN�YDOXH�LQ�WKH�XVXDO�ZD\��6HH�umask(2)�IRU�IXUWKHU�LQIRUPDWLRQ�

Making and Removing Directories | 203

2RSV��ZH�MXVW�FUHDWHG�D�GLUHFWRU\�ZLWK�WKDW�EL]DUUH�01363�SHUPLVVLRQV�EHFDXVH�0755�ZDVWUHDWHG�DV�GHFLPDO��7R�IL[�WKDW��XVH�WKH�oct�IXQFWLRQ��ZKLFK�IRUFHV�RFWDO�LQWHUSUHWDWLRQRI�D�VWULQJ�ZKHWKHU�RU�QRW�WKHUH¦V�D�OHDGLQJ�]HUR�

mkdir $name, oct($permissions);

2I�FRXUVH��LI�\RX�DUH�VSHFLI\LQJ�WKH�SHUPLVVLRQ�YDOXH�GLUHFWO\�ZLWKLQ�WKH�SURJUDP��MXVWXVH�D�QXPEHU�LQVWHDG�RI�D�VWULQJ��7KH�QHHG�IRU�WKH�H[WUD�oct�IXQFWLRQ�VKRZV�XS�PRVWRIWHQ�ZKHQ�WKH�YDOXH�FRPHV�IURP�XVHU�LQSXW��)RU�H[DPSOH��VXSSRVH�ZH�WDNH�WKH�DUJX�PHQWV�IURP�WKH�FRPPDQG�OLQH�

my ($name, $perm) = @ARGV; # first two args are name, permissionsmkdir $name, oct($perm) or die "cannot create $name: $!";

7KH�YDOXH�KHUH�IRU�$perm�LV�LQWHUSUHWHG�DV�D�VWULQJ�LQLWLDOO\��DQG�WKXV�WKH�oct�IXQFWLRQLQWHUSUHWV�WKH�FRPPRQ�RFWDO�UHSUHVHQWDWLRQ�SURSHUO\�

7R� UHPRYH� HPSW\� GLUHFWRULHV�� XVH� WKH� rmdir� IXQFWLRQ� LQ� D� PDQQHU� VLPLODU� WR� WKHunlink�IXQFWLRQ��DOWKRXJK�LW�FDQ�RQO\�UHPRYH�RQ�GLUHFWRU\�SHU�FDOO�

foreach my $dir (qw(fred barney betty)) { rmdir $dir or warn "cannot rmdir $dir: $!\n";}

7KH�rmdir�RSHUDWRU�IDLOV�IRU�QRQHPSW\�GLUHFWRULHV��$V�D�ILUVW�SDVV��\RX�FDQ�DWWHPSW�WRGHOHWH�WKH�FRQWHQWV�RI�WKH�GLUHFWRU\�ZLWK�unlink��WKHQ�WU\�WR�UHPRYH�ZKDW�VKRXOG�QRZEH�DQ�HPSW\�GLUHFWRU\��)RU�H[DPSOH��VXSSRVH�ZH�QHHG�D�SODFH�WR�ZULWH�PDQ\�WHPSRUDU\ILOHV�GXULQJ�WKH�H[HFXWLRQ�RI�D�SURJUDP�

my $temp_dir = "/tmp/scratch_$$"; # based on process ID; see the textmkdir $temp_dir, 0700 or die "cannot create $temp_dir: $!";...# use $temp_dir as location of all temporary files...unlink glob "$temp_dir/* $temp_dir/.*"; # delete contents of $temp_dirrmdir $temp_dir; # delete now-empty directory

7KH�LQLWLDO�WHPSRUDU\�GLUHFWRU\�QDPH�LQFOXGHV�WKH�FXUUHQW�SURFHVV�,'��ZKLFK�LV�XQLTXHIRU�HYHU\�UXQQLQJ�SURFHVV�DQG�LV�DFFHVVHG�ZLWK�WKH�$$�YDULDEOH��VLPLODU�WR�WKH�VKHOO���:HGR�WKLV�WR�DYRLG�FROOLGLQJ�ZLWK�DQ\�RWKHU�SURFHVVHV��DV�ORQJ�DV�WKH\�DOVR�LQFOXGH�WKHLUSURFHVV�,'�DV�SDUW�RI�WKHLU�SDWKQDPH�DV�ZHOO���,Q�IDFW��LW¦V�FRPPRQ�WR�XVH�WKH�SURJUDP¦VQDPH�DV�ZHOO�DV�WKH�SURFHVV�,'��VR�LI�WKH�SURJUDP�LV�FDOOHG�quarry��WKH�GLUHFWRU\�ZRXOGSUREDEO\�EH�VRPHWKLQJ�OLNH�/tmp/quarry_$$��

$W�WKH�HQG�RI�WKH�SURJUDP��WKDW�ODVW�unlink�VKRXOG�UHPRYH�DOO�WKH�ILOHV�LQ�WKLV�WHPSRUDU\GLUHFWRU\��DQG�WKHQ�WKH�rmdir�IXQFWLRQ�FDQ�GHOHWH�WKH�WKHQ�HPSW\�GLUHFWRU\��+RZHYHU�LI�ZH¦YH�FUHDWHG�VXEGLUHFWRULHV�XQGHU�WKDW�GLUHFWRU\��WKH�unlink�RSHUDWRU�IDLOV�RQ�WKRVH�DQG�WKH�rmdir�DOVR� IDLOV��)RU�D�PRUH�UREXVW�VROXWLRQ��FKHFN�RXW� WKH�rmtree� IXQFWLRQSURYLGHG�E\�WKH�File::Path�PRGXOH�RI�WKH�VWDQGDUG�GLVWULEXWLRQ�

204 | Chapter 13:ಗDirectory Operations

Modifying Permissions7KH�8QL[�FKPRG�FRPPDQG�FKDQJHV�WKH�SHUPLVVLRQV�RQ�D�ILOH�RU�GLUHFWRU\��6LPLODUO\�3HUO�KDV�WKH�chmod�IXQFWLRQ�WR�SHUIRUP�WKLV�WDVN�

chmod 0755, "fred", "barney";

$V�ZLWK�PDQ\�RI�WKH�RSHUDWLQJ�V\VWHP�LQWHUIDFH�IXQFWLRQV��chmod�UHWXUQV�WKH�QXPEHU�RILWHPV�VXFFHVVIXOO\�DOWHUHG��DQG�ZKHQ�XVHG�ZLWK�D�VLQJOH�DUJXPHQW��VHWV�$!�LQ�D�VHQVLEOHZD\�IRU�HUURU�PHVVDJHV�ZKHQ�LW�IDLOV��7KH�ILUVW�SDUDPHWHU�LV�WKH�8QL[�SHUPLVVLRQ�YDOXH�HYHQ�IRU�QRQ�8QL[�YHUVLRQV�RI�3HUO���)RU�WKH�VDPH�UHDVRQV�ZH�SUHVHQWHG�HDUOLHU�ZKHQGHVFULELQJ�mkdir��WKLV�YDOXH�LV�XVXDOO\�VSHFLILHG�LQ�RFWDO�

6\PEROLF�SHUPLVVLRQV��OLNH�+x�RU�go=u-w��DFFHSWHG�E\�WKH�8QL[�FKPRG�FRPPDQG�DUHQRW�YDOLG�IRU�WKH�chmod�IXQFWLRQ�

Changing Ownership,I�WKH�RSHUDWLQJ�V\VWHP�SHUPLWV�LW��\RX�PD\�FKDQJH�WKH�RZQHUVKLS�DQG�JURXS�PHPEHU�VKLS�RI�D�OLVW�RI�ILOHV��RU�ILOHKDQGOHV��ZLWK�WKH�chown�IXQFWLRQ��7KH�XVHU�DQG�JURXS�DUHERWK�FKDQJHG�DW�RQFH��DQG�ERWK�KDYH�WR�EH�WKH�QXPHULF�XVHU�,'�DQG�JURXS�,'�YDOXHV�)RU�H[DPSOH�

my $user = 1004;my $group = 100;chown $user, $group, glob "*.o";

:KDW�LI�\RX�KDYH�D�XVHUQDPH�OLNH�merlyn�LQVWHDG�RI�WKH�QXPEHU"�6LPSOH��-XVW�FDOO�WKHgetpwnam� IXQFWLRQ� WR� WUDQVODWH� WKH� QDPH� LQWR� D� QXPEHU�� DQG� WKH� FRUUHVSRQGLQJgetgrnam��WR�WUDQVODWH�WKH�JURXS�QDPH�LQWR�LWV�QXPEHU�

defined(my $user = getpwnam "merlyn") or die "bad user";defined(my $group = getgrnam "users") or die "bad group";chown $user, $group, glob "/home/merlyn/*";

7KH�defined�IXQFWLRQ�YHULILHV�WKDW�WKH�UHWXUQ�YDOXH�LV�QRW�undef��ZKLFK�ZLOO�EH�UHWXUQHGLI�WKH�UHTXHVWHG�XVHU�RU�JURXS�LV�QRW�YDOLG�

7KH�chown�IXQFWLRQ�UHWXUQV�WKH�QXPEHU�RI�ILOHV�DIIHFWHG��DQG�LW�VHWV�$!�RQ�HUURU�

8QOHVV�\RX¦YH�LQVWDOOHG�DQG�LQYRNHG�WKH�File::chmod�PRGXOH�IURP�&3$1��ZKLFK�FDQ�DSSDUHQWO\�XSJUDGH�WKHchmod�RSHUDWRU�WR�XQGHUVWDQG�V\PEROLF�PRGH�YDOXHV�

� 7KHVH�WZR�DUH�DPRQJ�WKH�XJOLHVW�IXQFWLRQ�QDPHV�NQRZQ�WR�PDQNLQG��%XW�GRQ¦W�EODPH�/DUU\�IRU�WKHP��KH¦VMXVW�JLYLQJ�WKHP�WKH�VDPH�QDPHV�WKDW�WKH�IRONV�DW�%HUNHOH\�GLG�

Modifying Permissions | 205

Changing Timestamps,Q�WKRVH�UDUH��FDVHV�ZKHQ�\RX�ZDQW�WR�OLH�WR�RWKHU�SURJUDPV�DERXW�ZKHQ�D�ILOH�ZDV�PRVWUHFHQWO\�PRGLILHG�RU�DFFHVVHG��\RX�FDQ�XVH�WKH�utime�IXQFWLRQ�WR�IXGJH�WKH�ERRNV�D�ELW�7KH�ILUVW� WZR�DUJXPHQWV�JLYH�WKH�QHZ�DFFHVV� WLPH�DQG�PRGLILFDWLRQ�WLPH��ZKLOH� WKHUHPDLQLQJ�DUJXPHQWV�DUH�WKH�OLVW�RI�ILOHQDPHV�WR�DOWHU�WR�WKRVH�WLPHVWDPSV��7KH�WLPHVDUH�VSHFLILHG�LQ�LQWHUQDO�WLPHVWDPS�IRUPDW��WKH�VDPH�W\SH�RI�YDOXHV�UHWXUQHG�IURP�WKHmoreinfo="none">stat �IXQFWLRQ�WKDW�ZH�PHQWLRQHG�LQ�&KDSWHU�����

2QH�FRQYHQLHQW�YDOXH�WR�XVH�IRU�WKH�WLPHVWDPSV�LV�£ULJKW�QRZ�¤�UHWXUQHG�LQ�WKH�SURSHUIRUPDW�E\�WKH�time�IXQFWLRQ��6R�WR�XSGDWH�DOO�WKH�ILOHV�LQ�WKH�FXUUHQW�GLUHFWRU\�WR�ORRNOLNH�WKH\�ZHUH�PRGLILHG�D�GD\�DJR��EXW�DFFHVVHG�MXVW�QRZ��ZH�FRXOG�VLPSO\�GR�WKLV�

my $now = time;my $ago = $now ! 24 * 60 * 60; # seconds per dayutime $now, $ago, glob "*"; # set access to now, mod to a day ago

2I�FRXUVH��QRWKLQJ�VWRSV�\RX�IURP�FUHDWLQJ�D�ILOH�WKDW�LV�DUELWUDULO\�VWDPSHG�IDU�LQ�WKHIXWXUH�RU�SDVW� �ZLWKLQ� WKH� OLPLWV�RI� WKH�8QL[� WLPHVWDPS�YDOXHV�RI������ WR�������RUZKDWHYHU�\RXU�QRQ�8QL[�V\VWHP�XVHV��XQOHVV�\RX�KDYH����ELW�WLPHVWDPSV���0D\EH�\RXFRXOG�XVH�WKLV�WR�FUHDWH�D�GLUHFWRU\�ZKHUH�\RX�NHHS�\RXU�QRWHV�IRU�WKDW�WLPH�WUDYHO�QRYHO\RX¦UH�ZULWLQJ�

7KH�WKLUG�WLPHVWDPS��WKH�FWLPH�YDOXH��LV�DOZD\V�VHW�WR�£QRZ¤�ZKHQHYHU�DQ\WKLQJ�DOWHUVD�ILOH��VR�WKHUH¦V�QR�ZD\�WR�VHW�LW��LW�ZRXOG�KDYH�WR�EH�UHVHW�WR�£QRZ¤�DIWHU�\RX�VHW�LW�ZLWK�WKH�utime�IXQFWLRQ��7KDW¦V�EHFDXVH�LWV�SULPDU\�SXUSRVH�LV�IRU�LQFUHPHQWDO�EDFNXSV�LI�WKH�ILOH¦V�FWLPH�LV�QHZHU�WKDQ�WKH�GDWH�RQ�WKH�EDFNXS�WDSH��LW¦V�WLPH�WR�EDFN�LW�XS�DJDLQ�

Exercises7KH�SURJUDPV�KHUH�DUH�SRWHQWLDOO\�GDQJHURXV��%H�FDUHIXO�WR�WHVW�WKHP�LQ�D�PRVWO\�HPSW\GLUHFWRU\�WR�PDNH�LW�GLIILFXOW�WR�DFFLGHQWDOO\�GHOHWH�VRPHWKLQJ�XVHIXO�

6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >��@�:ULWH�D�SURJUDP�WR�DVN�WKH�XVHU�IRU�D�GLUHFWRU\�QDPH��WKHQ�FKDQJH�WR�WKDWGLUHFWRU\��,I�WKH�XVHU�HQWHUV�D�OLQH�ZLWK�QRWKLQJ�EXW�ZKLWHVSDFH��FKDQJH�WR�KLV�RUKHU�KRPH�GLUHFWRU\�DV�D�GHIDXOW��$IWHU�FKDQJLQJ��OLVW�WKH�RUGLQDU\�GLUHFWRU\�FRQWHQWV�QRW�WKH�LWHPV�ZKRVH�QDPHV�EHJLQ�ZLWK�D�GRW��LQ�DOSKDEHWLFDO�RUGHU���+LQW��ZLOO�WKDWEH�HDVLHU�WR�GR�ZLWK�D�GLUHFWRU\�KDQGOH�RU�ZLWK�D�JORE"��,I� WKH�GLUHFWRU\�FKDQJHGRHVQ¦W�VXFFHHG��MXVW�DOHUW�WKH�XVHU¢EXW�GRQ¦W�WU\�VKRZ�WKH�FRQWHQWV�

�� >�@�0RGLI\�WKH�SURJUDP�WR�LQFOXGH�DOO�ILOHV��QRW�MXVW�WKH�RQHV�WKDW�GRQ¦W�EHJLQ�ZLWKD�GRW�

�� >�@�,I�\RX�XVHG�D�GLUHFWRU\�KDQGOH�IRU�WKH�SUHYLRXV�H[HUFLVH��UHZULWH�LW�WR�XVH�D�JORE�2U�LI�\RX�XVHG�D�JORE��WU\�LW�QRZ�ZLWK�D�GLUHFWRU\�KDQGOH�

206 | Chapter 13:ಗDirectory Operations

�� >�@�:ULWH�D�SURJUDP�WKDW�ZRUNV�OLNH�UP��GHOHWLQJ�DQ\�ILOHV�QDPHG�RQ�WKH�FRPPDQGOLQH���<RX�GRQ¦W�QHHG�WR�KDQGOH�DQ\�RI�WKH�RSWLRQV�RI�UP��

�� >��@�:ULWH�D�SURJUDP�WKDW�ZRUNV�OLNH�PY��UHQDPLQJ�WKH�ILUVW�FRPPDQG�OLQH�DUJX�PHQW�WR�WKH�VHFRQG�FRPPDQG�OLQH�DUJXPHQW���<RX�GRQ¦W�QHHG�WR�KDQGOH�DQ\�RI�WKHRSWLRQV�RI�PY�RU�DGGLWLRQDO�DUJXPHQWV���5HPHPEHU�WR�DOORZ�IRU�WKH�GHVWLQDWLRQ�WREH�D�GLUHFWRU\��LI�LW�LV��XVH�WKH�VDPH�RULJLQDO�EDVHQDPH�LQ�WKH�QHZ�GLUHFWRU\�

�� >�@�,I�\RXU�RSHUDWLQJ�V\VWHP�VXSSRUWV�LW��ZULWH�D�SURJUDP�WKDW�ZRUNV�OLNH�OQ��PDNLQJD�KDUG�OLQN�IURP�WKH�ILUVW�FRPPDQG�OLQH�DUJXPHQW�WR�WKH�VHFRQG���<RX�GRQ¦W�QHHGWR�KDQGOH�RSWLRQV�RI�OQ�RU�PRUH�DUJXPHQWV���,I�\RXU�V\VWHP�GRHVQ¦W�KDYH�KDUG�OLQNV�MXVW�SULQW�RXW�D�PHVVDJH�WHOOLQJ�ZKDW�RSHUDWLRQ�\RX�ZRXOG�SHUIRUP�LI�LW�ZHUH�DYDLO�DEOH�� �+LQW�� WKLV� SURJUDP� KDV� VRPHWKLQJ� LQ� FRPPRQ�ZLWK� WKH� SUHYLRXV� RQH¢UHFRJQL]LQJ�WKDW�FRXOG�VDYH�\RX�WLPH�LQ�FRGLQJ��

�� >�@� ,I� \RXU�RSHUDWLQJ� V\VWHP�VXSSRUWV� LW�� IL[�XS� WKH�SURJUDP� IURP�WKH�SUHYLRXVH[HUFLVH�WR�DOORZ�DQ�RSWLRQDO��V�VZLWFK�EHIRUH�WKH�RWKHU�DUJXPHQWV�WR�LQGLFDWH�WKDW\RX�ZDQW�WR�PDNH�D�VRIW�OLQN�LQVWHDG�RI�D�KDUG�OLQN���(YHQ�LI�\RX�GRQ¦W�KDYH�KDUGOLQNV��VHH�ZKHWKHU�\RX�FDQ�DW�OHDVW�PDNH�VRIW�OLQNV�ZLWK�WKLV�SURJUDP��

�� >�@�,I�\RXU�RSHUDWLQJ�V\VWHP�VXSSRUWV�LW��ZULWH�D�SURJUDP�WR�ILQG�DQ\�V\PEROLF�OLQNVLQ�WKH�FXUUHQW�GLUHFWRU\�DQG�SULQW�RXW�WKHLU�YDOXHV��OLNH�OV��O�ZRXOG��name -> value��

Exercises | 207

CHAPTER 14

Strings and Sorting

$V��ZH�PHQWLRQHG�QHDU�WKH�EHJLQQLQJ�RI�WKLV�ERRN��3HUO�LV�GHVLJQHG�WR�EH�JRRG�DW�VROYLQJSURJUDPPLQJ�SUREOHPV�WKDW�DUH�DERXW�����ZRUNLQJ�ZLWK�WH[W�DQG�����HYHU\WKLQJ�HOVH�6R�LW¦V�QR�VXUSULVH�WKDW�3HUO�KDV�VWURQJ�WH[W�SURFHVVLQJ�DELOLWLHV��LQFOXGLQJ�DOO�WKDW�ZH¦YHGRQH�ZLWK� UHJXODU� H[SUHVVLRQV��%XW� VRPHWLPHV� WKH� UHJXODU� H[SUHVVLRQ� HQJLQH� LV� WRRIDQF\��DQG�\RX¦OO�QHHG�D� VLPSOHU�ZD\�RI�ZRUNLQJ�ZLWK�D� VWULQJ��DV�\RX¦OO� VHH� LQ� WKLVFKDSWHU�

Finding a Substring with index)LQGLQJ�D�VXEVWULQJ�GHSHQGV�RQ�ZKHUH�\RX�KDYH�ORVW�LW��,I�\RX�KDSSHQ�WR�KDYH�ORVW�LWZLWKLQ�D�ELJJHU�VWULQJ��\RX¦UH�LQ�OXFN�EHFDXVH�WKH�index�IXQFWLRQ�FDQ�KHOS�\RX�RXW��+HUH¦VKRZ�LW�ORRNV�

$where = index($big, $small);

3HUO�ORFDWHV�WKH�ILUVW�RFFXUUHQFH�RI�WKH�VPDOO�VWULQJ�ZLWKLQ�WKH�ELJ�VWULQJ��UHWXUQLQJ�DQLQWHJHU�ORFDWLRQ�RI�WKH�ILUVW�FKDUDFWHU��7KH�FKDUDFWHU�SRVLWLRQ�UHWXUQHG�LV�D�]HUR�EDVHGYDOXH¢LI�WKH�VXEVWULQJ�LV�IRXQG�DW�WKH�YHU\�EHJLQQLQJ�RI�WKH�VWULQJ��index�UHWXUQV�0��,ILW¦V�RQH�FKDUDFWHU�ODWHU��WKH�UHWXUQ�YDOXH�LV�1��DQG�VR�RQ��,I�WKH�VXEVWULQJ�FDQ¦W�EH�IRXQGDW�DOO��WKH�UHWXUQ�YDOXH�LV�!1�WR�LQGLFDWH�WKDW� �,Q�WKLV�H[DPSOH��$where�JHWV�6�

my $stuff = "Howdy world!";my $where = index($stuff, "wor");

$QRWKHU�ZD\�\RX�FRXOG�WKLQN�RI�WKH�SRVLWLRQ�QXPEHU�LV�WKH�QXPEHU�RI�FKDUDFWHUV�WRVNLS�RYHU�EHIRUH�JHWWLQJ�WR�WKH�VXEVWULQJ��6LQFH�$where�LV�6��ZH�NQRZ�WKDW�ZH�KDYH�WRVNLS�RYHU�WKH�ILUVW�VL[�FKDUDFWHUV�RI�$stuff�EHIRUH�ZH�ILQG�wor�

7KH�index�IXQFWLRQ�ZLOO�DOZD\V�UHSRUW�WKH�ORFDWLRQ�RI�WKH�ILUVW�IRXQG�RFFXUUHQFH�RI�WKHVXEVWULQJ��%XW�\RX�FDQ�WHOO�LW�WR�VWDUW�VHDUFKLQJ�DW�D�ODWHU�SRLQW�WKDQ�WKH�VWDUW�RI�WKH�VWULQJE\�XVLQJ�WKH�RSWLRQDO�WKLUG�SDUDPHWHU��ZKLFK�WHOOV�index�WR�VWDUW�DW�WKDW�SRVLWLRQ�

)RUPHU�&�SURJUDPPHUV�ZLOO�UHFRJQL]H�WKLV�DV�EHLQJ�OLNH�&¦V�LQGH[�IXQFWLRQ��&XUUHQW�&�SURJUDPPHUV�RXJKWWR�UHFRJQL]H�LW�DV�ZHOO¢EXW�E\�WKLV�SRLQW�LQ�WKH�ERRN��\RX�VKRXOG�UHDOO\�EH�D�IRUPHU�&�SURJUDPPHU�

209

my $stuff = "Howdy world!";my $where1 = index($stuff, "w"); # $where1 gets 2my $where2 = index($stuff, "w", $where1 + 1); # $where2 gets 6my $where3 = index($stuff, "w", $where2 + 1); # $where3 gets !1 (not found)

�2I�FRXUVH��\RX�ZRXOGQ¦W�QRUPDOO\�VHDUFK�UHSHDWHGO\�IRU�D�VXEVWULQJ�ZLWKRXW�XVLQJ�DORRS���7KDW�WKLUG�SDUDPHWHU�LV�HIIHFWLYHO\�JLYLQJ�D�PLQLPXP�YDOXH�IRU�WKH�UHWXUQ�YDOXH�LI�WKH�VXEVWULQJ�FDQ¦W�EH�IRXQG�DW�WKDW�SRVLWLRQ�RU�ODWHU��WKH�UHWXUQ�YDOXH�ZLOO�EH�!1�

2QFH�LQ�D�ZKLOH��\RX�PLJKW�SUHIHU�WR�KDYH�WKH�ODVW�IRXQG�RFFXUUHQFH�RI�WKH�VXEVWULQJ�

<RX�FDQ�JHW�WKDW�ZLWK�WKH�rindex�IXQFWLRQ��,Q�WKLV�H[DPSOH��ZH�FDQ�ILQG�WKH�ODVW�VODVK�ZKLFK�WXUQV�RXW�WR�EH�DW�SRVLWLRQ�4�LQ�D�VWULQJ�

my $last_slash = rindex("/etc/passwd", "/"); # value is 4

7KH�rindex�IXQFWLRQ�DOVR�KDV�DQ�RSWLRQDO�WKLUG�SDUDPHWHU��EXW��LQ�WKLV�FDVH��LW�HIIHFWLYHO\JLYHV�WKH�PD[LPXP�SHUPLWWHG�UHWXUQ�YDOXH�

my $fred = "Yabba dabba doo!";my $where1 = rindex($fred, "abba"); # $where1 gets 7my $where2 = rindex($fred, "abba", $where1 ! 1); # $where2 gets 1my $where3 = rindex($fred, "abba", $where2 ! 1); # $where3 gets !1

Manipulating a Substring with substr7KH�substr�RSHUDWRU�ZRUNV�ZLWK�RQO\�D�SDUW�RI�D�ODUJHU�VWULQJ��,W�ORRNV�OLNH�WKLV�

$part = substr($string, $initial_position, $length);

,W�WDNHV�WKUHH�DUJXPHQWV��D�VWULQJ�YDOXH��D�]HUR�EDVHG�LQLWLDO�SRVLWLRQ��OLNH�WKH�UHWXUQYDOXH�RI�index���DQG�D�OHQJWK�IRU�WKH�VXEVWULQJ��7KH�UHWXUQ�YDOXH�LV�WKH�VXEVWULQJ�

my $mineral = substr("Fred J. Flintstone", 8, 5); # gets "Flint"my $rock = substr "Fred J. Flintstone", 13, 1000; # gets "stone"

$V�\RX�PD\�KDYH�QRWLFHG�LQ�WKH�SUHYLRXV�H[DPSOH��LI�WKH�UHTXHVWHG�OHQJWK��1000�FKDU�DFWHUV��LQ�WKLV�FDVH��ZRXOG�JR�SDVW�WKH�HQG�RI�WKH�VWULQJ��WKHUH¦V�QR�FRPSODLQW�IURP�3HUO�EXW�\RX�VLPSO\�JHW�D�VKRUWHU�VWULQJ�WKDQ�\RX�PLJKW�KDYH��%XW�LI�\RX�ZDQW�WR�EH�VXUH�WRJR�WR�WKH�HQG�RI�WKH�VWULQJ��KRZHYHU�ORQJ�RU�VKRUW�LW�PD\�EH��MXVW�RPLW�WKDW�WKLUG�SD�UDPHWHU��WKH�OHQJWK���OLNH�WKLV�

my $pebble = substr "Fred J. Flintstone", 13; # gets "stone"

:HOO��LW¦V�QRW�UHDOO\�WKH�ODVW�RQH�IRXQG¢3HUO�FOHYHUO\�VWDUWV�VHDUFKLQJ�IURP�WKH�RWKHU�HQG�RI�WKH�VWULQJ��DQGWKHQ�UHWXUQV�WKH�ILUVW�ORFDWLRQ�LW�ILQGV��ZKLFK�DPRXQWV�WR�WKH�VDPH�UHVXOW��2I�FRXUVH��WKH�UHWXUQ�YDOXH�LV�WKHVDPH�]HUR�EDVHG�QXPEHU�DV�ZH�DOZD\V�XVH�IRU�GHVFULELQJ�ORFDWLRQV�RI�VXEVWULQJV�

210 | Chapter 14:ಗStrings and Sorting

7KH�LQLWLDO�SRVLWLRQ�RI�WKH�VXEVWULQJ�LQ�WKH�ODUJHU�VWULQJ�FDQ�EH�QHJDWLYH��FRXQWLQJ�IURPWKH�HQG�RI�WKH�VWULQJ��WKDW�LV��SRVLWLRQ�!1�LV�WKH�ODVW�FKDUDFWHU�� �,Q�WKLV�H[DPSOH��SRVLWLRQ-3�LV�WKUHH�FKDUDFWHUV�IURP�WKH�HQG�RI�WKH�VWULQJ��ZKLFK�LV�WKH�ORFDWLRQ�RI�WKH�OHWWHU�i�

my $out = substr("some very long string", !3, 2); # $out gets "in"

$V�\RX�PLJKW�H[SHFW��index�DQG�substr�ZRUN�ZHOO�WRJHWKHU��,Q�WKLV�H[DPSOH��ZH�FDQH[WUDFW�D�VXEVWULQJ�WKDW�VWDUWV�DW�WKH�ORFDWLRQ�RI�WKH�OHWWHU�l�

my $long = "some very very long string";my $right = substr($long, index($long, "l") );

1RZ�KHUH¦V�VRPHWKLQJ�UHDOO\�FRRO��7KH�VHOHFWHG�SRUWLRQ�RI�WKH�VWULQJ�FDQ�EH�FKDQJHG�LIWKH�VWULQJ�LV�D�YDULDEOH��

my $string = "Hello, world!";substr($string, 0, 5) = "Goodbye"; # $string is now "Goodbye, world!"

$V�\RX�VHH��WKH�DVVLJQHG��VXE�VWULQJ�GRHVQ¦W�KDYH�WR�EH�WKH�VDPH�OHQJWK�DV�WKH�VXEVWULQJLW¦V�UHSODFLQJ��7KH�VWULQJ¦V�OHQJWK�LV�DGMXVWHG�WR�ILW��2U�LI�WKDW�ZDVQ¦W�FRRO�HQRXJK�WRLPSUHVV�\RX��\RX�FRXOG�XVH�WKH�ELQGLQJ�RSHUDWRU��=~��WR�UHVWULFW�DQ�RSHUDWLRQ�WR�ZRUNZLWK�MXVW�SDUW�RI�D�VWULQJ��7KLV�H[DPSOH�UHSODFHV�fred�ZLWK�barney�ZKHUHYHU�SRVVLEOHZLWKLQ�MXVW�WKH�ODVW����FKDUDFWHUV�RI�D�VWULQJ�

substr($string, !20) =~ s/fred/barney/g;

7R�EH�FRPSOHWHO\�KRQHVW��ZH¦YH�QHYHU�DFWXDOO\�QHHGHG�WKDW�IXQFWLRQDOLW\�LQ�DQ\�RI�RXURZQ�FRGH��DQG�FKDQFHV�DUH�WKDW�\RX¦OO�QHYHU�QHHG�LW�HLWKHU��%XW�LW¦V�QLFH�WR�NQRZ�WKDW3HUO�FDQ�GR�PRUH�WKDQ�\RX¦OO�HYHU�QHHG��LVQ¦W�LW"

0XFK�RI�WKH�ZRUN�WKDW�substr�DQG�index�GR�FRXOG�EH�GRQH�ZLWK�UHJXODU�H[SUHVVLRQV�8VH�WKRVH�ZKHUH�WKH\¦UH�DSSURSULDWH��%XW�substr�DQG�index�FDQ�RIWHQ�EH�IDVWHU��VLQFHWKH\� GRQ¦W� KDYH� WKH� RYHUKHDG� RI� WKH� UHJXODU� H[SUHVVLRQ� HQJLQH�� WKH\¦UH� QHYHU� FDVH�LQVHQVLWLYH��WKH\�KDYH�QR�PHWDFKDUDFWHUV�WR�ZRUU\�DERXW��DQG�WKH\�GRQ¦W�VHW�DQ\�RI�WKHPHPRU\�YDULDEOHV�

%HVLGHV�DVVLJQLQJ�WR�WKH�substr�IXQFWLRQ��ZKLFK�ORRNV�D�OLWWOH�ZHLUG�DW�ILUVW�JODQFH��SHU�KDSV���\RX�FDQ�DOVR�XVH�substr�LQ�D�VOLJKWO\�PRUH�WUDGLWLRQDO�PDQQHU®�ZLWK�WKH�IRXU�DUJXPHQW�YHUVLRQ��LQ�ZKLFK�WKH�IRXUWK�DUJXPHQW�LV�WKH�UHSODFHPHQW�VXEVWULQJ�

my $previous_value = substr($string, 0, 5, "Goodbye");

7KLV�LV�DQDORJRXV�WR�ZKDW�\RX�VDZ�ZLWK�DUUD\�LQGLFHV�LQ�&KDSWHU����-XVW�DV�DUUD\V�PD\�EH�LQGH[HG�HLWKHU�IURP0��WKH�ILUVW�HOHPHQW��XSZDUG�RU�IURP�!1��WKH�ODVW�HOHPHQW��GRZQZDUG��VXEVWULQJ�ORFDWLRQV�PD\�EH�LQGH[HGIURP�SRVLWLRQ�0��DW�WKH�ILUVW�FKDUDFWHU��XSZDUG�RU�IURP�SRVLWLRQ�!1��DW�WKH�ODVW�FKDUDFWHU��GRZQZDUG�

� :HOO��WHFKQLFDOO\��LW�FDQ�EH�DQ\�OYDOXH��:KDW�WKDW�WHUP�PHDQV�SUHFLVHO\�LV�EH\RQG�WKH�VFRSH�RI�WKLV�ERRN��EXW\RX�FDQ�WKLQN�RI�LW�DV�DQ\WKLQJ�WKDW�FDQ�EH�SXW�RQ�WKH�OHIW�VLGH�RI�WKH�HTXDOV�VLJQ��=��LQ�D�VFDODU�DVVLJQPHQW�7KDW¦V�XVXDOO\�D�YDULDEOH��EXW�LW�FDQ��DV�\RX�VHH�KHUH��HYHQ�EH�DQ�LQYRFDWLRQ�RI�WKH�substr�RSHUDWRU�

® %\�WUDGLWLRQDO�ZH�PHDQ�LQ�WKH�£IXQFWLRQ�LQYRFDWLRQ¤�VHQVH��EXW�QRW�WKH�£3HUO¤�VHQVH��VLQFH�WKLV�IHDWXUH�ZDVLQWURGXFHG�WR�3HUO�UHODWLYHO\�UHFHQWO\�

Manipulating a Substring with substr | 211

7KH�SUHYLRXV�YDOXH�FRPHV�EDFN�DV�WKH�UHWXUQ�YDOXH��DOWKRXJK��DV�DOZD\V��\RX�FDQ�XVHWKLV�IXQFWLRQ�LQ�D�YRLG�FRQWH[W�WR�VLPSO\�GLVFDUG�LW�

Formatting Data with sprintf7KH�sprintf� IXQFWLRQ� WDNHV� WKH� VDPH� DUJXPHQWV� DV�printf� �H[FHSW� IRU� WKH� RSWLRQDOILOHKDQGOH��RI�FRXUVH���EXW�LW�UHWXUQV�WKH�UHTXHVWHG�VWULQJ�LQVWHDG�RI�SULQWLQJ�LW��7KLV�LVKDQG\�LI�\RX�ZDQW�WR�VWRUH�D�IRUPDWWHG�VWULQJ�LQWR�D�YDULDEOH�IRU�ODWHU�XVH��RU�LI�\RX�ZDQWPRUH�FRQWURO�RYHU�WKH�UHVXOW�WKDQ�printf�DORQH�ZRXOG�SURYLGH�

my $date_tag = sprintf "%4d/%02d/%02d %2d:%02d:%02d", $yr, $mo, $da, $h, $m, $s;

,Q�WKDW�H[DPSOH��$date_tag�JHWV�VRPHWKLQJ�OLNH�"2038/01/19 3:00:08"��7KH�IRUPDW�VWULQJ�WKH�ILUVW�DUJXPHQW�WR�sprintf��XVHG�D�OHDGLQJ�]HUR�RQ�VRPH�RI�WKH�IRUPDW�QXPEHU��ZKLFKZH�GLGQ¦W�PHQWLRQ�ZKHQ�ZH�WDONHG�DERXW�printf�IRUPDWV�LQ�&KDSWHU����7KH�OHDGLQJ�]HURRQ�WKH�IRUPDW�QXPEHU�PHDQV�WR�XVH�OHDGLQJ�]HURV�DV�QHHGHG�WR�PDNH�WKH�QXPEHU�DVZLGH�DV�UHTXHVWHG��:LWKRXW�D�OHDGLQJ�]HUR�LQ�WKH�IRUPDWV��WKH�UHVXOWLQJ�GDWH�DQG�WLPHVWULQJ�ZRXOG�KDYH�XQZDQWHG�OHDGLQJ�VSDFHV�LQVWHDG�RI�]HURV��OLNH�"2038/ 1/19 3: 0: 8"�

Using sprintf with “Money Numbers”2QH�SRSXODU�XVH� IRU�sprintf� LV�ZKHQ�\RX�ZDQW� WR� IRUPDW�D�QXPEHU�ZLWK�D� FHUWDLQQXPEHU�RI�SODFHV�DIWHU�WKH�GHFLPDO�SRLQW��VXFK�DV�ZKHQ�\RX�ZDQW�WR�VKRZ�DQ�DPRXQWRI�PRQH\�DV�2.50�DQG�QRW�2.5¢DQG�FHUWDLQO\�QRW�DV�2.49997��7KDW¦V�HDV\�WR�DFFRPSOLVKZLWK�WKH�"%.2f"�IRUPDW�

my $money = sprintf "%.2f", 2.49997;

7KH�IXOO�LPSOLFDWLRQV�RI�URXQGLQJ�DUH�QXPHURXV�DQG�VXEWOH��EXW��LQ�PRVW�FDVHV��\RXVKRXOG�NHHS�QXPEHUV�LQ�PHPRU\�ZLWK�DOO�RI�WKH�DYDLODEOH�DFFXUDF\��URXQGLQJ�RII�RQO\IRU�RXWSXW�

,I�\RX�KDYH�D�£PRQH\�QXPEHU¤�WKDW�PD\�EH�ODUJH�HQRXJK�WR�QHHG�FRPPDV�WR�VKRZ�LWVVL]H��\RX�PLJKW�ILQG�LW�KDQG\�WR�XVH�D�VXEURXWLQH�OLNH�WKLV�RQH�

sub big_money { my $number = sprintf "%.2f", shift @_; # Add one comma each time through the do-nothing loop 1 while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/; # Put the dollar sign in the right place $number =~ s/^(-?)/$1\$/; $number;}

<HV��ZH�NQRZ�WKDW�QRW�HYHU\ZKHUH�LQ�WKH�ZRUOG�DUH�FRPPDV�XVHG�WR�VHSDUDWH�JURXSV�RI�GLJLWV��QRW�HYHU\ZKHUHDUH�WKH�GLJLWV�JURXSHG�E\�WKUHHV��DQG�QRW�HYHU\ZKHUH�GRHV�WKH�FXUUHQF\�V\PERO�DSSHDUV�DV�LW�GRHV�IRU�8�6�GROODUV��%XW�WKLV�LV�D�JRRG�H[DPSOH�DQ\ZD\��VR�WKHUH�

212 | Chapter 14:ಗStrings and Sorting

7KLV�VXEURXWLQH�XVHV�VRPH�WHFKQLTXHV�\RX�KDYHQ¦W�VHHQ�\HW��EXW�WKH\�ORJLFDOO\�IROORZIURP�ZKDW�ZH¦YH�VKRZQ�\RX��7KH�ILUVW�OLQH�RI�WKH�VXEURXWLQH�IRUPDWV�WKH�ILUVW��DQG�RQO\�SDUDPHWHU�WR�KDYH�H[DFWO\�WZR�GLJLWV�DIWHU�WKH�GHFLPDO�SRLQW��7KDW�LV��LI�WKH�SDUDPHWHUZHUH�WKH�QXPEHU�12345678.9��QRZ�RXU�$number�LV�WKH�VWULQJ�"12345678.90"�

7KH�QH[W�OLQH�RI�FRGH�XVHV�D�while�PRGLILHU��$V�ZH�PHQWLRQHG�ZKHQ�ZH�FRYHUHG�WKDWPRGLILHU�LQ�&KDSWHU�����WKDW�FDQ�DOZD\V�EH�UHZULWWHQ�DV�D�WUDGLWLRQDO�while�ORRS�

while ($number =~ s/^(-?\d+)(\d\d\d)/$1,$2/) { 1;}

:KDW�GRHV�WKDW�VD\�WR�GR"�,W�VD\V�WKDW�DV�ORQJ�DV�WKH�VXEVWLWXWLRQ�UHWXUQV�D�WUXH�YDOXH�VLJQLI\LQJ�VXFFHVV���WKH�ORRS�ERG\�VKRXOG�UXQ��%XW�WKH�ORRS�ERG\�GRHV�QRWKLQJ��7KDW¦VRND\�ZLWK�3HUO��EXW�LW�WHOOV�XV�WKDW�WKH�SXUSRVH�RI�WKDW�VWDWHPHQW�LV�WR�GR�WKH�FRQGLWLRQDOH[SUHVVLRQ��WKH�VXEVWLWXWLRQ���UDWKHU�WKDQ�WKH�XVHOHVV�ORRS�ERG\��7KH�YDOXH�1�LV�WUDGL�WLRQDOO\�XVHG�DV�WKLV�NLQG�RI�D�SODFHKROGHU��DOWKRXJK�DQ\�RWKHU�YDOXH�ZRXOG�EH�HTXDOO\XVHIXO� �7KLV�ZRUNV�MXVW�DV�ZHOO�DV�WKH�ORRS�DERYH�

'keep looping' while $number =~ s/^(-?\d+)(\d\d\d)/$1,$2/;

6R��QRZ�ZH�NQRZ�WKDW�WKH�VXEVWLWXWLRQ�LV�WKH�UHDO�SXUSRVH�RI�WKH�ORRS��%XW�ZKDW�LV�WKHVXEVWLWXWLRQ�GRLQJ"�5HPHPEHU�WKDW�$number�ZLOO�EH�VRPH�VWULQJ�OLNH�"12345678.90"�DWWKLV�SRLQW��7KH�SDWWHUQ�ZLOO�PDWFK�WKH�ILUVW�SDUW�RI�WKH�VWULQJ��EXW�LW�FDQ¦W�JHW�SDVW�WKHGHFLPDO�SRLQW���'R�\RX�VHH�ZK\�LW�FDQ¦W"��0HPRU\�$1�ZLOO�JHW�"12345"��DQG�$2�ZLOO�JHW"678"��VR�WKH�VXEVWLWXWLRQ�ZLOO�PDNH�$number�LQWR�"12345,678.90"��UHPHPEHU��LW�FRXOGQ¦WPDWFK�WKH�GHFLPDO�SRLQW��VR�WKH�ODVW�SDUW�RI�WKH�VWULQJ�LV�OHIW�XQWRXFKHG��

'R�\RX�VHH�ZKDW�WKH�GDVK�LV�GRLQJ�QHDU�WKH�VWDUW�RI�WKDW�SDWWHUQ"��+LQW��WKH�GDVK�LVDOORZHG�DW�RQO\�RQH�SODFH�LQ�WKH�VWULQJ���:H¦OO�WHOO�\RX�DW�WKH�HQG�RI�WKLV�VHFWLRQ��LQ�FDVH\RX�KDYHQ¦W�ILJXUHG�LW�RXW�

:H¦UH�QRW�GRQH�ZLWK�WKDW�VXEVWLWXWLRQ�VWDWHPHQW�\HW��6LQFH�WKH�VXEVWLWXWLRQ�VXFFHHGHG�WKH�GR�QRWKLQJ�ORRS�JRHV�EDFN�WR�WU\�DJDLQ��7KLV�WLPH��WKH�SDWWHUQ�FDQ¦W�PDWFK�DQ\WKLQJIURP�WKH�FRPPD�RQZDUG��VR�$number�EHFRPHV�"12,345,678.90"��7KH�VXEVWLWXWLRQ�WKXVDGGV�D�FRPPD�WR�WKH�QXPEHU�HDFK�WLPH�WKURXJK�WKH�ORRS�

6SHDNLQJ�RI�WKH�ORRS��LW¦V�VWLOO�QRW�GRQH��6LQFH�WKH�SUHYLRXV�VXEVWLWXWLRQ�ZDV�D�VXFFHVV�ZH¦UH�EDFN�DURXQG�WKH�ORRS�WR�WU\�DJDLQ��%XW�WKLV�WLPH��WKH�SDWWHUQ�FDQ¦W�PDWFK�DW�DOO�VLQFH�LW�KDV�WR�PDWFK�DW�OHDVW�IRXU�GLJLWV�DW�WKH�VWDUW�RI�WKH�VWULQJ��VR�QRZ�WKDW�LV�WKH�HQGRI�WKH�ORRS�

:K\�FRXOGQ¦W�ZH�KDYH�VLPSO\�XVHG�WKH�/g�PRGLILHU�WR�GR�D�£JOREDO¤�VHDUFK�DQG�UHSODFH�WR�VDYH�WKH�WURXEOH�DQG�FRQIXVLRQ�RI�WKH�1 while"�:H�FRXOGQ¦W�XVH�WKDW�EHFDXVH�ZH¦UHZRUNLQJ�EDFNZDUG�IURP�WKH�GHFLPDO�SRLQW��UDWKHU�WKDQ�IRUZDUG�IURP�WKH�VWDUW�RI�WKHVWULQJ��3XWWLQJ�WKH�FRPPDV�LQ�D�QXPEHU�OLNH�WKLV�FDQ¦W�EH�GRQH�VLPSO\�ZLWK�WKH�s///g

:KLFK�LV�WR�VD\��XVHOHVV��%\�WKH�ZD\��LQ�FDVH�\RX¦UH�ZRQGHULQJ��3HUO�RSWLPL]HV�DZD\�WKH�FRQVWDQW�H[SUHVVLRQ�VR�LW�GRHVQ¦W�HYHQ�WDNH�XS�DQ\�UXQWLPH�

Formatting Data with sprintf | 213

VXEVWLWXWLRQ�DORQH� �6R��GLG�\RX�ILJXUH�RXW�WKH�GDVK"�,W¦V�DOORZLQJ�IRU�D�SRVVLEOH�PLQXVVLJQ�DW�WKH�VWDUW�RI�WKH�VWULQJ��7KH�QH[W�OLQH�RI�FRGH�PDNHV�WKH�VDPH�DOORZDQFH��SXWWLQJWKH�GROODU�VLJQ�LQ�WKH�ULJKW�SODFH�VR�WKDW�$number�LV�VRPHWKLQJ�OLNH�"$12,345,678.90"��RUSHUKDSV�"-$12,345,678.90"�LI�LW¦V�QHJDWLYH��1RWH�WKDW�WKH�GROODU�VLJQ�LVQ¦W�QHFHVVDULO\WKH�ILUVW�FKDUDFWHU�LQ�WKH�VWULQJ��RU�WKDW�OLQH�ZRXOG�EH�D�ORW�VLPSOHU��)LQDOO\��WKH�ODVW�OLQHRI�FRGH� UHWXUQV�RXU�QLFHO\� IRUPDWWHG�£PRQH\�QXPEHU�¤�ZKLFK�\RX�FDQ�SULQW� LQ� WKHDQQXDO�UHSRUW�

Advanced Sorting(DUOLHU��LQ�&KDSWHU����ZH�VKRZHG�WKDW�\RX�FRXOG�VRUW�D�OLVW�LQ�DVFHQGLQJ�$6&,,EHWLFDORUGHU�E\�XVLQJ�WKH�EXLOW�LQ�sort�RSHUDWRU��:KDW�LI�\RX�ZDQW�D�QXPHULF�VRUW"�2U�D�FDVH�LQVHQVLWLYH�VRUW"�2U�PD\EH�\RX�ZDQW�WR�VRUW�LWHPV�DFFRUGLQJ�WR�LQIRUPDWLRQ�VWRUHG�LQD�KDVK��:HOO��3HUO�OHWV�\RX�VRUW�D�OLVW�LQ�ZKDWHYHU�RUGHU�\RX¦G�QHHG��\RX¦OO�VHH�DOO�RI�WKRVHH[DPSOHV�E\�WKH�HQG�RI�WKH�FKDSWHU�

<RX¦OO� WHOO�3HUO�ZKDW�RUGHU�\RX�ZDQW�E\�PDNLQJ�D� VRUW�GHILQLWLRQ� VXEURXWLQH��RU� VRUWVXEURXWLQH�IRU�VKRUW��1RZ��ZKHQ�\RX�ILUVW�KHDU�WKH�WHUP�£VRUW�VXEURXWLQH�¤�LI�\RX¦YHEHHQ�WKURXJK�DQ\�FRPSXWHU�VFLHQFH�FRXUVHV��YLVLRQV�RI�EXEEOH�VRUW�DQG�VKHOO�VRUW�DQGTXLFN�VRUW�UDFH�WKURXJK�\RXU�KHDG��DQG�\RX�VD\��£1R��QHYHU�DJDLQ�¤�'RQ¦W�ZRUU\��LW¦VQRW�WKDW�EDG��,Q�IDFW��LW¦V�SUHWW\�VLPSOH��3HUO�DOUHDG\�NQRZV�KRZ�WR�VRUW�D�OLVW�RI�LWHPV�LW�PHUHO\�GRHVQ¦W�NQRZ�ZKLFK�RUGHU�\RX�ZDQW��6R��WKH�VRUW�GHILQLWLRQ�VXEURXWLQH�VLPSO\WHOOV�LW�WKH�RUGHU�

:K\�LV�WKLV�QHFHVVDU\"�:HOO��LI�\RX�WKLQN�DERXW�LW��VRUWLQJ�LV�SXWWLQJ�D�EXQFK�RI�WKLQJVLQ�RUGHU�E\�FRPSDULQJ�WKHP�DOO��6LQFH�\RX�FDQ¦W�FRPSDUH�WKHP�DOO�DW�RQFH��\RX�QHHG�WRFRPSDUH�WZR�DW�D�WLPH��HYHQWXDOO\�XVLQJ�ZKDW�\RX�ILQG�RXW�DERXW�HDFK�SDLU¦V�RUGHU�WRSXW� WKH�ZKROH�NLW� DQG� FDERRGOH� LQ� OLQH��3HUO� DOUHDG\�XQGHUVWDQGV� DOO� RI� WKRVH� VWHSVH[FHSW�IRU�WKH�SDUW�DERXW�KRZ�\RX¦G�OLNH�WR�FRPSDUH�WKH�LWHPV��VR�WKDW¦V�DOO�\RX�KDYH�WRZULWH�

7KLV�PHDQV�WKDW�WKH�VRUW�VXEURXWLQH�GRHVQ¦W�QHHG�WR�VRUW�PDQ\�LWHPV�DIWHU�DOO��,W�PHUHO\KDV�WR�EH�DEOH�WR�FRPSDUH�WZR�LWHPV��,I�LW�FDQ�SXW�WZR�LWHPV�LQ�WKH�SURSHU�RUGHU��3HUOZLOO�EH�DEOH�WR�WHOO��E\�UHSHDWHGO\�FRQVXOWLQJ�WKH�VRUW�VXEURXWLQH��ZKDW�RUGHU�\RX�ZDQWIRU�\RXU�GDWD�

7KH�VRUW�VXEURXWLQH�LV�GHILQHG�OLNH�DQ�RUGLQDU\�VXEURXWLQH��ZHOO��DOPRVW���7KLV�URXWLQHZLOO�EH�FDOOHG�UHSHDWHGO\��HDFK�WLPH�FKHFNLQJ�RQ�D�SDLU�RI�HOHPHQWV�IURP�WKH�OLVW�\RX¦UHVRUWLQJ�

1RZ��LI�\RX�ZHUH�ZULWLQJ�D�VXEURXWLQH�WKDW¦V�H[SHFWLQJ�WR�JHW�WZR�SDUDPHWHUV�WKDW�QHHGVRUWLQJ��\RX�PLJKW�ZULWH�VRPHWKLQJ�OLNH�WKLV�WR�VWDUW�

$W�OHDVW��LW�FDQ¦W�EH�GRQH�ZLWKRXW�VRPH�PRUH�DGYDQFHG�UHJXODU�H[SUHVVLRQ�WHFKQLTXHV�WKDQ�ZH¦YH�VKRZQ�\RXVR�IDU��7KRVH�GDUQ�3HUO�GHYHORSHUV�NHHS�PDNLQJ�LW�KDUGHU�DQG�KDUGHU�WR�ZULWH�3HUO�ERRNV�WKDW�XVH�WKH�ZRUG£FDQ¦W�¤

214 | Chapter 14:ಗStrings and Sorting

sub any_sort_sub { # It doesn't really work this way my($a, $b) = @_; # Get and name the two parameters # start comparing $a and $b here ...}

%XW�WKH�VRUW�VXEURXWLQH�ZLOO�EH�FDOOHG�DJDLQ�DQG�DJDLQ��RIWHQ�KXQGUHGV�RU�WKRXVDQGV�RIWLPHV��'HFODULQJ�WKH�YDULDEOHV�$a�DQG�$b�DQG�DVVLJQLQJ�WKHP�YDOXHV�DW�WKH�WRS�RI�WKHVXEURXWLQH�ZLOO�WDNH�MXVW�D�OLWWOH�WLPH��EXW�PXOWLSO\�WKDW�E\�WKH�WKRXVDQGV�RI�WLPHV�WKDWWKH�URXWLQH�ZLOO�EH�FDOOHG��DQG�\RX�FDQ�VHH�WKDW�LW�FRQWULEXWHV�VLJQLILFDQWO\�WR�WKH�RYHUDOOH[HFXWLRQ�VSHHG�

:H�GRQ¦W�GR�LW�OLNH�WKDW���,Q�IDFW��LI�\RX�GLG�LW�WKDW�ZD\��LW�ZRXOGQ¦W�ZRUN���,QVWHDG��LW�LVDV�LI�3HUO�KDV�GRQH�WKLV�IRU�XV��EHIRUH�RXU�VXEURXWLQH¦V�FRGH�KDV�HYHQ�VWDUWHG��<RX¦OOUHDOO\�ZULWH�D�VRUW�VXEURXWLQH�ZLWKRXW�WKDW�ILUVW�OLQH��ERWK�$a�DQG�$b�KDYH�EHHQ�DVVLJQHGIRU�\RX��:KHQ�WKH�VRUW�VXEURXWLQH�VWDUWV�UXQQLQJ��$a�DQG�$b�DUH�WZR�HOHPHQWV�IURP�WKHRULJLQDO�OLVW�

7KH�VXEURXWLQH�UHWXUQV�D�FRGHG�YDOXH�GHVFULELQJ�KRZ�WKH�HOHPHQWV�FRPSDUH��OLNH�&¦Vqsort(3)�GRHV��EXW�LW¦V�3HUO¦V�RZQ�LQWHUQDO�VRUW�LPSOHPHQWDWLRQ���,I�$a�VKRXOG�DSSHDUEHIRUH�$b�LQ�WKH�ILQDO�OLVW��WKH�VRUW�VXEURXWLQH�UHWXUQV�!1�WR�VD\�VR��,I�$b�VKRXOG�DSSHDUEHIRUH�$a��LW�UHWXUQV�1�

,I�WKH�RUGHU�RI�$a�DQG�$b�GRHVQ¦W�PDWWHU��WKH�VXEURXWLQH�UHWXUQV�0��:K\�ZRXOG�LW�QRWPDWWHU"�3HUKDSV�\RX¦UH�GRLQJ�D�FDVH�LQVHQVLWLYH�VRUW�DQG�WKH�WZR�VWULQJV�DUH�fred�DQGFred��2U�SHUKDSV�\RX¦UH�GRLQJ�D�QXPHULF�VRUW�DQG�WKH�WZR�QXPEHUV�DUH�HTXDO�

<RX�FRXOG�QRZ�ZULWH�D�QXPHULF�VRUW�VXEURXWLQH�OLNH�WKLV�

sub by_number { # a sort subroutine, expect $a and $b if ($a < $b) { !1 } elsif ($a > $b) { 1 } else { 0 }}

7R�XVH� WKH�VRUW� VXEURXWLQH�� MXVW�SXW� LWV�QDPH��ZLWKRXW�DQ�DPSHUVDQG��EHWZHHQ� WKHNH\ZRUG�sort�DQG�WKH�OLVW�\RX¦UH�VRUWLQJ��7KLV�H[DPSOH�SXWV�D�QXPHULFDOO\�VRUWHG�OLVWRI�QXPEHUV�LQWR�@result�

my @result = sort by_number @some_numbers;

:H�FDOOHG�WKH�VXEURXWLQH�by_number�EHFDXVH�WKDW�GHVFULEHV�KRZ�LW¦V�VRUWLQJ��%XW�PRUHLPSRUWDQWO\��\RX�FDQ� UHDG� WKH� OLQH�RI�FRGH� WKDW�XVHV� LW�ZLWK�VRUW�DV� VD\LQJ�£VRUW�E\QXPEHU�¤�DV�\RX�ZRXOG� LQ�(QJOLVK��0DQ\�VRUW�VXEURXWLQH�QDPHV�EHJLQ�ZLWK�by_� WRGHVFULEH�KRZ�WKH\�VRUW��2U�ZH�FRXOG�KDYH�FDOOHG�WKLV�RQH�numerically�� IRU�D�VLPLODUUHDVRQ��EXW�WKDW¦V�PRUH�W\SLQJ�DQG�PRUH�FKDQFH�WR�PHVV�XS�VRPHWKLQJ�

1RWLFH�WKDW�ZH�GRQ¦W�KDYH�WR�GR�DQ\WKLQJ�LQ�WKH�VRUW�VXEURXWLQH�WR�GHFODUH�$a�DQG�$b�DQG�WR�VHW�WKHLU�YDOXHV¢DQG�LI�ZH�GLG��WKH�VXEURXWLQH�ZRXOGQ¦W�ZRUN�ULJKW��:H�MXVW�OHW3HUO�VHW�XS�$a�DQG�$b�IRU�XV��DQG�VR�DOO�ZH�QHHG�WR�ZULWH�LV�WKH�FRPSDULVRQ�

,Q�IDFW��ZH�FDQ�PDNH�LW�HYHQ�VLPSOHU��DQG�PRUH�HIILFLHQW���6LQFH�WKLV�NLQG�RI�WKUHH�ZD\FRPSDULVRQ�LV�IUHTXHQW��3HUO�KDV�D�FRQYHQLHQW�VKRUWFXW�WR�XVH�WR�ZULWH�LW��,Q�WKLV�FDVH�

Advanced Sorting | 215

ZH�XVH�WKH�VSDFHVKLS�RSHUDWRU��<=>�� �7KLV�RSHUDWRU�FRPSDUHV�WZR�QXPEHUV�DQG�UHWXUQV!1��0�� RU�1� DV�QHHGHG� WR� VRUW� WKHP�QXPHULFDOO\�� 6R�ZH�FRXOG�KDYH�ZULWWHQ� WKDW� VRUWVXEURXWLQH�EHWWHU��OLNH�WKLV�

sub by_number { $a <=> $b }

6LQFH�WKH�VSDFHVKLS�FRPSDUHV�QXPEHUV��\RX�PD\�KDYH�JXHVVHG�WKDW� WKHUH¦V�D�FRUUH�VSRQGLQJ�WKUHH�ZD\�VWULQJ�FRPSDULVRQ�RSHUDWRU��cmp��7KHVH�WZR�DUH�HDV\�WR�UHPHPEHUDQG�NHHS�VWUDLJKW��7KH�VSDFHVKLS�KDV�D�IDPLO\�UHVHPEODQFH�WR�WKH�QXPHULF�FRPSDULVRQRSHUDWRUV� OLNH�>=�� EXW� LW¦V� WKUHH� FKDUDFWHUV� ORQJ� LQVWHDG�RI� WZR�EHFDXVH� LW�KDV� WKUHHSRVVLEOH�UHWXUQ�YDOXHV�LQVWHDG�RI�WZR��$QG�cmp�KDV�D�IDPLO\�UHVHPEODQFH�WR�WKH�VWULQJFRPSDULVRQ�RSHUDWRUV�OLNH�ge��EXW�LW¦V�WKUHH�FKDUDFWHUV�ORQJ�LQVWHDG�RI�WZR�EHFDXVH�LWDOVR�KDV�WKUHH�SRVVLEOH�UHWXUQ�YDOXHV�LQVWHDG�RI�WZR���2I�FRXUVH��cmp�E\�LWVHOI�SURYLGHVWKH�VDPH�RUGHU�DV�WKH�GHIDXOW�VRUW��<RX¦G�QHYHU�QHHG�WR�ZULWH�WKLV�VXEURXWLQH��ZKLFK\LHOGV�PHUHO\�WKH�GHIDXOW�VRUW�RUGHU�®

sub ASCIIbetically { $a cmp $b }

my @strings = sort ASCIIbetically @any_strings;

%XW�\RX�FDQ�XVH�cmp�WR�EXLOG�D�PRUH�FRPSOH[�VRUW�RUGHU��OLNH�D�FDVH�LQVHQVLWLYH�VRUW�

sub case_insensitive { "\L$a" cmp "\L$b" }

,Q�WKLV�FDVH��ZH¦UH�FRPSDULQJ�WKH�VWULQJ�IURP�$a��IRUFHG�WR�ORZHUFDVH��DJDLQVW�WKH�VWULQJIURP�$b��IRUFHG�WR�ORZHUFDVH���JLYLQJ�D�FDVH�LQVHQVLWLYH�VRUW�RUGHU�

1RWH�WKDW�ZH¦UH�QRW�PRGLI\LQJ�WKH�HOHPHQWV�WKHPVHOYHV��ZH¦UH�PHUHO\�XVLQJ�WKHLU�YDOXHV�7KDW¦V�DFWXDOO\�LPSRUWDQW��IRU�HIILFLHQF\�UHDVRQV��$a�DQG�$b�DUHQ¦W�FRSLHV�RI�WKH�GDWDLWHPV��7KH\¦UH�DFWXDOO\�QHZ��WHPSRUDU\�DOLDVHV�IRU�HOHPHQWV�RI�WKH�RULJLQDO�OLVW��VR�LI�ZHFKDQJHG�WKHP��ZH¦G�EH�PDQJOLQJ�WKH�RULJLQDO�GDWD��'RQ¦W�GR�WKDW¢LW¦V�QHLWKHU�VXS�SRUWHG�QRU�UHFRPPHQGHG�

:KHQ�\RXU�VRUW�VXEURXWLQH�LV�DV�VLPSOH�DV�WKH�RQHV�ZH�VKRZ�KHUH��DQG�PRVW�RI�WKH�WLPH�LW�LV���\RX�FDQ�PDNH�WKH�FRGH�HYHQ�VLPSOHU�\HW��E\�UHSODFLQJ�WKH�QDPH�RI�WKH�VRUW�URXWLQHZLWK�WKH�HQWLUH�VRUW�URXWLQH�£LQOLQH�¤�OLNH�VR�

my @numbers = sort { $a <=> $b } @some_numbers;

,Q�IDFW�� LQ�PRGHUQ�3HUO��\RX¦OO�KDUGO\�HYHU�VHH�D�VHSDUDWH�VRUW�VXEURXWLQH��\RX¦OO� IUH�TXHQWO\�ILQG�VRUW�URXWLQHV�ZULWWHQ�LQOLQH�DV�ZH¦YH�GRQH�KHUH�

6XSSRVH�\RX�ZDQW�WR�VRUW�LQ�GHVFHQGLQJ�QXPHULF�RUGHU��7KDW¦V�HDV\�HQRXJK�WR�GR�ZLWKWKH�KHOS�RI�reverse�

:H�FDOO�LW�WKDW�EHFDXVH�LW�ORRNV�OLNH�RQH�RI�WKH�7,(�ILJKWHUV�IURP�6WDU�:DUV��:HOO��LW�ORRNV�OLNH�WKDW�WR�XV��DQ\ZD\�

� 7KLV� LV�QR�DFFLGHQW��/DUU\�GRHV� WKLQJV� OLNH� WKLV�RQ�SXUSRVH�� WR�PDNH�3HUO� HDVLHU� WR� OHDUQ�DQG� UHPHPEHU�5HPHPEHU��KH¦V�D�OLQJXLVW�DW�KHDUW��VR�KH¦V�VWXGLHG�KRZ�SHRSOH�WKLQN�RI�ODQJXDJHV�

® <RX¦G�QHYHU�QHHG�WR�ZULWH�WKLV�XQOHVV��RI�FRXUVH��\RX�ZHUH�ZULWLQJ�DQ�LQWURGXFWRU\�3HUO�ERRN�DQG�QHHGHG�LWIRU�DQ�H[DPSOH�

216 | Chapter 14:ಗStrings and Sorting

my @descending = reverse sort { $a <=> $b } @some_numbers;

%XW�KHUH¦V�D�QHDW�WULFN��7KH�FRPSDULVRQ�RSHUDWRUV��<=>�DQG�cmp��DUH�YHU\�QHDUVLJKWHG�WKDW�LV��WKH\�FDQ¦W�VHH�ZKLFK�RSHUDQG�LV�$a�DQG�ZKLFK�LV�$b��EXW�RQO\�ZKLFK�YDOXH�LV�RQWKH�OHIW�DQG�ZKLFK�LV�RQ�WKH�ULJKW��6R�LI�$a�DQG�$b�ZHUH�WR�VZDS�SODFHV��WKH�FRPSDULVRQRSHUDWRU�ZRXOG�JHW�WKH�UHVXOWV�EDFNZDUG�HYHU\�WLPH��7KDW�PHDQV�WKDW�WKLV�LV�DQRWKHUZD\�WR�JHW�D�UHYHUVHG�QXPHULF�VRUW�

my @descending = sort { $b <=> $a } @some_numbers;

<RX�FDQ��ZLWK�D�OLWWOH�SUDFWLFH��UHDG�WKLV�DW�D�JODQFH��,W¦V�D�GHVFHQGLQJ�RUGHU�FRPSDULVRQ�EHFDXVH�$b�FRPHV�EHIRUH�$a��ZKLFK�LV�GHVFHQGLQJ�RUGHU���DQG�LW¦V�D�QXPHULF�FRPSDULVRQ�EHFDXVH�LW�XVHV�WKH�VSDFHVKLS�LQVWHDG�RI�cmp���6R��LW¦V�VRUWLQJ�QXPEHUV�LQ�UHYHUVH�RUGHU��,Q�PRGHUQ�3HUO�YHUVLRQV��LW�GRHVQ¦W�PDWWHU�PXFK�ZKLFK�RQH�RI�WKRVH�\RX�GR�EHFDXVHreverse�LV�UHFRJQL]HG�DV�D�PRGLILHU�WR�sort��DQG�VSHFLDO�VKRUWFXWV�DUH�WDNHQ�WR�DYRLGVRUWLQJ�LW�RQH�ZD\�MXVW�WR�KDYH�WR�WXUQ�LW�DURXQG�WKH�RWKHU�ZD\��

Sorting a Hash by Value2QFH�\RX¦YH�EHHQ�VRUWLQJ�OLVWV�KDSSLO\�IRU�D�ZKLOH�\RX¦OO�UXQ�LQWR�D�VLWXDWLRQ�ZKHUH�\RXZDQW�WR�VRUW�D�KDVK�E\�YDOXH��)RU�H[DPSOH��WKUHH�RI�RXU�FKDUDFWHUV�ZHQW�RXW�ERZOLQJODVW�QLJKW��DQG�ZH¦YH�JRW�WKHLU�ERZOLQJ�VFRUHV�LQ�WKH�IROORZLQJ�KDVK��:H�ZDQW�WR�EH�DEOHWR�SULQW�RXW�WKH�OLVW�LQ�WKH�SURSHU�RUGHU��ZLWK�WKH�JDPH�ZLQQHU�DW�WKH�WRS��VR�ZH�ZDQWWR�VRUW�WKH�KDVK�E\�VFRUH�

my %score = ("barney" => 195, "fred" => 205, "dino" => 30);my @winners = sort by_score keys %score;

2I�FRXUVH��\RX�DUHQ¦W�UHDOO\�JRLQJ�WR�EH�DEOH�WR�VRUW�WKH�KDVK�E\�VFRUH��WKDW¦V�MXVW�D�YHUEDOVKRUWFXW��<RX�FDQ¦W�VRUW�D�KDVK��%XW�ZKHQ�ZH¦YH�XVHG�sort�ZLWK�KDVKHV�EHIRUH�QRZ�ZH¦YH�EHHQ�VRUWLQJ�WKH�NH\V�RI�WKH�KDVK��LQ�$6&,,EHWLFDO�RUGHU���1RZ��\RX¦UH�VWLOO�JRLQJWR�VRUW�WKH�NH\V�RI�WKH�KDVK��EXW�WKH�RUGHU�LV�GHILQHG�E\�WKHLU�FRUUHVSRQGLQJ�YDOXHV�IURPWKH�KDVK��,Q�WKLV�FDVH��WKH�UHVXOW�VKRXOG�EH�D�OLVW�RI�RXU�WKUHH�FKDUDFWHUV¦�QDPHV��LQ�RUGHUDFFRUGLQJ�WR�WKHLU�ERZOLQJ�VFRUHV�

:ULWLQJ�WKLV�VRUW�VXEURXWLQH�LV�IDLUO\�HDV\��:KDW�ZH�ZDQW�LV�WR�XVH�D�QXPHULF�FRPSDULVRQRQ� WKH�VFRUHV�� UDWKHU� WKDQ� WKH�QDPHV��7KDW� LV�� LQVWHDG�RI�FRPSDULQJ�$a� DQG�$b� �WKHSOD\HUV¦�QDPHV���ZH�ZDQW�WR�FRPSDUH�$score{$a}�DQG�$score{$b}��WKHLU�VFRUHV���,I�\RXWKLQN�RI�LW�WKDW�ZD\��LW�DOPRVW�ZULWHV�LWVHOI��DV�LQ�

sub by_score { $score{$b} <=> $score{$a} }

/HW¦V�VWHS�WKURXJK�WKLV�DQG�VHH�KRZ�LW�ZRUNV��/HW¦V�LPDJLQH�WKDW�WKH�ILUVW�WLPH�LW¦V�FDOOHG�3HUO� KDV� VHW�$a� WR�barney� DQG�$b� WR�fred�� 6R� WKH� FRPSDULVRQ� LV�$score{"fred"} <=>$score{"barney"`��ZKLFK��DV�ZH�FDQ�VHH�E\�FRQVXOWLQJ�WKH�KDVK��LV�205 <=> 195��5H�PHPEHU��QRZ��WKH�VSDFHVKLS�LV�QHDUVLJKWHG��VR�ZKHQ�LW�VHHV�205�EHIRUH�195��LW�VD\V��LQHIIHFW��£1R��WKDW¦V�QRW�WKH�ULJKW�QXPHULF�RUGHU��$b�VKRXOG�FRPH�EHIRUH�$a�¤�6R�LW�WHOOV3HUO�WKDW�fred�VKRXOG�FRPH�EHIRUH�barney�

Advanced Sorting | 217

0D\EH�WKH�QH[W�WLPH�WKH�URXWLQH�LV�FDOOHG��$a�LV�barney�DJDLQ�EXW�$b�LV�QRZ�dino��7KHQHDUVLJKWHG�QXPHULF�FRPSDULVRQ�VHHV�30 <=> 195�WKLV�WLPH��VR�LW�UHSRUWV�WKDW�WKDW�WKH\¦UHLQ� WKH� ULJKW�RUGHU��$a�GRHV� LQGHHG� VRUW� LQ� IURQW�RI�$b��7KDW� LV��barney� FRPHV�EHIRUHdino��$W�WKLV�SRLQW��3HUO�KDV�HQRXJK�LQIRUPDWLRQ�WR�SXW�WKH�OLVW� LQ�RUGHU��fred� LV�WKHZLQQHU��WKHQ�barney�LQ�VHFRQG�SODFH��WKHQ�dino�

:K\�GLG�WKH�FRPSDULVRQ�XVH�WKH�$score{$b}�EHIRUH�WKH�$score{$a}��LQVWHDG�RI�WKH�RWKHUZD\�DURXQG"�7KDW¦V�EHFDXVH�ZH�ZDQWHG�ERZOLQJ�VFRUHV�DUUDQJHG�LQ�GHVFHQGLQJ�RUGHU�IURP�WKH�KLJKHVW�VFRUH�GRZQ��6R�\RX�FDQ��DJDLQ��DIWHU�D�OLWWOH�SUDFWLFH��UHDG�WKLV�RQH�DWVLJKW� DV�ZHOO��$score{$b} <=> $score{$a}�PHDQV� WR� VRUW� DFFRUGLQJ� WR� WKH� VFRUHV�� LQUHYHUVHG�QXPHULF�RUGHU�

Sorting by Multiple Keys:H�IRUJRW�WR�PHQWLRQ�WKDW�WKHUH�ZDV�D�IRXUWK�SOD\HU�ERZOLQJ�ODVW�QLJKW�ZLWK�WKH�RWKHUWKUHH��VR�WKH�KDVK�UHDOO\�ORRNHG�OLNH�WKLV�

my %score = ( "barney" => 195, "fred" => 205, "dino" => 30, "bamm-bamm" => 195,);

1RZ��DV�\RX�FDQ�VHH��bamm-bamm�KDV�WKH�VDPH�VFRUH�DV�barney��6R�ZKLFK�RQH�ZLOO�EH�ILUVWLQ�WKH�VRUWHG�OLVW�RI�SOD\HUV"�7KHUH¦V�QR�WHOOLQJ�EHFDXVH�WKH�FRPSDULVRQ�RSHUDWRU��VHHLQJWKH�VDPH�VFRUH�RQ�ERWK�VLGHV��ZLOO�KDYH�WR�UHWXUQ�]HUR�ZKHQ�FKHFNLQJ�WKRVH�WZR�

0D\EH�WKDW�GRHVQ¦W�PDWWHU��EXW�ZH�JHQHUDOO\�SUHIHU�WR�KDYH�D�ZHOO�GHILQHG�VRUW��,I�VHYHUDOSOD\HUV�KDYH�WKH�VDPH�VFRUH��ZH�ZDQW�WKHP�WR�EH�WRJHWKHU�LQ�WKH�OLVW��RI�FRXUVH��%XWZLWKLQ�WKDW�JURXS��WKH�QDPHV�VKRXOG�EH�LQ�$6&,,EHWLFDO�RUGHU��%XW�KRZ�FDQ�ZH�ZULWHWKH�VRUW�VXEURXWLQH�WR�VD\�WKDW"�$JDLQ��WKLV�WXUQV�RXW�WR�EH�SUHWW\�HDV\�

my @winners = sort by_score_and_name keys %score;

sub by_score_and_name { $score{$b} <=> $score{$a} # by descending numeric score or $a cmp $b # ASCIIbetically by name}

+RZ�GRHV�WKLV�ZRUN"�:HOO��LI�WKH�VSDFHVKLS�VHHV�WZR�GLIIHUHQW�VFRUHV��WKDW¦V�WKH�FRP�SDULVRQ�ZH�ZDQW�WR�XVH��,W�UHWXUQV�!1�RU�1��D�WUXH�YDOXH��VR�WKH�ORZ�SUHFHGHQFH�VKRUW�FLUFXLW�or�ZLOO�PHDQ�WKDW�WKH�UHVW�RI�WKH�H[SUHVVLRQ�ZLOO�EH�VNLSSHG��DQG�WKH�FRPSDULVRQZH�ZDQW�LV�UHWXUQHG���5HPHPEHU��WKH�VKRUW�FLUFXLW�or�UHWXUQV�WKH�ODVW�H[SUHVVLRQ�HYDO�XDWHG���%XW�LI�WKH�VSDFHVKLS�VHHV�WZR�LGHQWLFDO�VFRUHV��LW�UHWXUQV�0��D�IDOVH�YDOXH��DQG�WKXVWKH�cmp�RSHUDWRU�JHWV�LWV�WXUQ�DW�EDW��UHWXUQLQJ�DQ�DSSURSULDWH�RUGHULQJ�YDOXH�FRQVLGHULQJWKH�NH\V�DV�VWULQJV��7KDW�LV��LI�WKH�VFRUHV�DUH�WKH�VDPH��WKH�VWULQJ�RUGHU�FRPSDULVRQ�EUHDNVWKH�WLH�

218 | Chapter 14:ಗStrings and Sorting

:H�NQRZ�WKDW�ZKHQ�ZH�XVH�WKH�by_score_and_name�VRUW�VXEURXWLQH�OLNH�WKLV��LW�ZLOO�QHYHUUHWXUQ�0���'R�\RX�VHH�ZK\�LW�ZRQ¦W"�7KH�DQVZHU�LV�LQ�WKH�IRRWQRWH� ��6R�ZH�NQRZ�WKDWWKH�VRUW�RUGHU� LV�DOZD\V�ZHOO�GHILQHG��WKDW� LV��ZH�NQRZ�WKDW�WKH�UHVXOW� WRGD\�ZLOO�EHLGHQWLFDO�WR�WKH�UHVXOW�ZLWK�WKH�VDPH�GDWD�WRPRUURZ�

7KHUH¦V�QR�UHDVRQ�WKDW�\RXU�VRUW�VXEURXWLQH�KDV�WR�EH�OLPLWHG�WR�WZR�OHYHOV�RI�VRUWLQJ�RI�FRXUVH��+HUH�WKH�%HGURFN�OLEUDU\�SURJUDP�SXWV�D�OLVW�RI�SDWURQ�,'�QXPEHUV�LQ�RUGHUDFFRUGLQJ�WR�D� ILYH�OHYHO�VRUW���7KLV�H[DPSOH�VRUWV�DFFRUGLQJ�WR�WKH�DPRXQW�RI�HDFKSDWURQ¦V�RXWVWDQGLQJ�ILQHV��DV�FDOFXODWHG�E\�D�VXEURXWLQH�&fines��QRW�VKRZQ�KHUH���WKHQXPEHU�RI�LWHPV�WKH\�FXUUHQWO\�KDYH�FKHFNHG�RXW��IURP�%items���WKHLU�QDPH��LQ�RUGHUE\�IDPLO\�QDPHV��WKHQ�E\�SHUVRQDO�QDPH��ERWK�IURP�KDVKHV���DQG�ILQDOO\�E\�WKH�SDWURQ¦V,'�QXPEHU��LQ�FDVH�HYHU\WKLQJ�HOVH�LV�WKH�VDPH�

@patron_IDs = sort { &fines($b) <=> &fines($a) or $items{$b} <=> $items{$a} or $family_name{$a} cmp $family_name{$a} or $personal_name{$a} cmp $family_name{$b} or $a <=> $b} @patron_IDs;

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >��@�:ULWH�D�SURJUDP�WR�UHDG�LQ�D�OLVW�RI�QXPEHUV�DQG�VRUW�WKHP�QXPHULFDOO\��SULQW�LQJ�RXW�WKH�UHVXOWLQJ�OLVW�LQ�D�ULJKW�MXVWLILHG�FROXPQ��7U\�LW�RXW�RQ�WKLV�VDPSOH�GDWDRU�XVH�WKH�ILOH�QXPEHUV�IURP�WKH�2¦5HLOO\�ZHE�VLWH��VHH�WKH�3UHIDFH��

17 1000 04 1.50 3.14159 !10 1.5 4 2001 90210 666

�� >��@� 0DNH� D� SURJUDP� WKDW� ZLOO� SULQW� WKH� IROORZLQJ� KDVK¦V� GDWD� VRUWHG� LQFDVH�LQVHQVLWLYH�DOSKDEHWLFDO�RUGHU�E\�ODVW�QDPH��:KHQ�WKH�ODVW�QDPHV�DUH�WKH�VDPH�VRUW�WKRVH�E\�ILUVW�QDPH��DJDLQ��ZLWKRXW�UHJDUG�IRU�FDVH���7KDW�LV��WKH�ILUVW�QDPH�LQWKH�RXWSXW�VKRXOG�EH�)UHG¦V��ZKLOH�WKH�ODVW�RQH�VKRXOG�EH�%HWW\¦V��$OO�RI�WKH�SHRSOHZLWK�WKH�VDPH�IDPLO\�QDPH�VKRXOG�EH�JURXSHG�WRJHWKHU��'RQ¦W�DOWHU�WKH�GDWD��7KHQDPHV�VKRXOG�EH�SULQWHG�ZLWK�WKH�VDPH�FDSLWDOL]DWLRQ�DV�VKRZQ�KHUH���<RX�FDQ�ILQGWKH�VRXUFH�FRGH�WR�FUHDWH�D�KDVK�OLNH�WKLV�LQ�WKH�ILOH�VRUWDEOHBKDVK�ZLWK�WKH�RWKHUGRZQORDGHG�ILOHV��

7KH�RQO\�ZD\�LW�FRXOG�UHWXUQ�0�ZRXOG�EH�LI�WKH�WZR�VWULQJV�ZHUH�LGHQWLFDO��DQG��VLQFH�WKH�VWULQJV�DUH�NH\V�RI�DKDVK��ZH�DOUHDG\�NQRZ�WKDW�WKH\¦UH�GLIIHUHQW��2I�FRXUVH��LI�\RX�SDVVHG�D�OLVW�ZLWK�GXSOLFDWH��LGHQWLFDO��VWULQJVWR�sort��LW�ZRXOG�UHWXUQ�0�ZKHQ�FRPSDULQJ�WKRVH��EXW�ZH¦UH�SDVVLQJ�D�OLVW�RI�KDVK�NH\V�

� ,W¦V�QRW�XQXVXDO�LQ�WKH�PRGHUQ�ZRUOG�WR�QHHG�D�ILYH�OHYHO�VRUW�OLNH�WKLV��DOWKRXJK�LW�ZDV�TXLWH�LQIUHTXHQW�LQSUHKLVWRULF�WLPHV�

Exercises | 219

my %last_name = qw{ fred flintstone Wilma Flintstone Barney Rubble betty rubble Bamm-Bamm Rubble PEBBLES FLINTSTONE};

�� >��@�0DNH�D�SURJUDP�WKDW�ORRNV�WKURXJK�D�JLYHQ�VWULQJ�IRU�HYHU\�RFFXUUHQFH�RI�DJLYHQ� VXEVWULQJ�� SULQWLQJ� RXW� WKH� SRVLWLRQV� ZKHUH� WKH� VXEVWULQJ� LV� IRXQG�� )RUH[DPSOH��JLYHQ�WKH�LQSXW�VWULQJ�"This is a test."�DQG�WKH�VXEVWULQJ�"is"��LW�VKRXOGUHSRUW�SRVLWLRQV�2�DQG�5��,I�WKH�VXEVWULQJ�ZHUH�"a"��LW�VKRXOG�UHSRUW�8��:KDW�GRHV�LW�UHSRUW�LI�WKH�VXEVWULQJ�LV�"t""

220 | Chapter 14:ಗStrings and Sorting

CHAPTER 15

Smart Matching and given-when

:RXOGQ¦W�LW�EH�JUHDW�LI�FRPSXWHUV�FRXOG�MXVW�ILJXUH�RXW�ZKDW�\RX�ZDQWHG�DQG�GR�LW"�3HUODOUHDG\�GRHV�LWV�EHVW�WR�XVH�QXPEHUV�ZKHQ�\RX�ZDQW�QXPEHUV��VWULQJV�ZKHQ�\RX�ZDQWVWULQJV��VLQJOH�YDOXHV�ZKHUH�\RX�PHDQ�D�VLQJOH�YDOXH��DQG�OLVWV�ZKHQ�\RX�PHDQ�OLVWV�:LWK�3HUO�����¦V�VPDUW�PDWFK�RSHUDWRU�DQG�given-when�FRQWURO�VWUXFWXUH��LW�JHWV�HYHQEHWWHU�

The Smart Match Operator7KH�VPDUW�PDWFK�RSHUDWRU��~~��ORRNV�DW�ERWK�RI�LWV�RSHUDQGV�DQG�GHFLGHV�RQ�LWV�RZQKRZ�LW�VKRXOG�FRPSDUH�WKHP��,I�WKH�RSHUDQGV�ORRN�OLNH�QXPEHUV�� LW�GRHV�D�QXPHULFFRPSDULVRQ��,I�WKH\�ORRN�OLNH�VWULQJV��LW�GRHV�D�VWULQJ�FRPSDULVRQ��,I�RQH�RI�WKH�RSHUDQGVLV�D�UHJXODU�H[SUHVVLRQ��LW�GRHV�D�SDWWHUQ�PDWFK��,W�FDQ�DOVR�GR�VRPH�FRPSOH[�WDVNV�WKDWZRXOG�RWKHUZLVH�WDNH�D�ORW�RI�FRGH��VR�LW�NHHSV�\RX�IURP�GRLQJ�WRR�PXFK�W\SLQJ�

7KH�~~�ORRNV�DOPRVW�OLNH�WKH�ELQGLQJ�RSHUDWRU��=~��ZKLFK�\RX�VDZ�LQ�&KDSWHU����EXW~~�FDQ�GR�PXFK�PRUH��,W�FDQ�HYHQ�VWDQG�LQ�IRU�WKH�ELQGLQJ�RSHUDWRU��8S�WR�QRZ��\RX¦GPDWFK�D�SDWWHUQ�E\�XVLQJ�WKH�ELQGLQJ�RSHUDWRU�WR�DVVRFLDWH�$name�ZLWK�WKH�UHJXODU�H[�SUHVVLRQ�RSHUDWRU�

print "I found Fred in the name!\n" if $name =~ /Fred/;

1RZ��\RX�FDQ�FKDQJH�WKDW�ELQGLQJ�RSHUDWRU�WR�WKH�VPDUW�PDWFK�RSHUDWRU�DQG�GR�H[DFWO\WKH�VDPH�WKLQJ�

use 5.010;

say "I found Fred in the name!" if $name ~~ /Fred/;

7KH�VPDUW�PDWFK�RSHUDWRU�VHHV�WKDW�LW�KDV�D�VFDODU�RQ�WKH�OHIWKDQG�VLGH�DQG�WKH�UHJXODUH[SUHVVLRQ�RSHUDWRU�RQ�WKH�ULJKWKDQG�VLGH��DQG�ILJXUHV�RXW�RQ�LWV�RZQ�WR�GR�WKH�SDWWHUQPDWFK��7KDW¦V�QRW�LPSUHVVLYH��WKRXJK��,W�JHWV�PXFK��PXFK�EHWWHU�

7KH�VPDUW�PDWFK�RSHUDWRU�VWDUWV�WR�VKRZ�LWV�SRZHU�ZLWK�PRUH�FRPSOH[�RSHUDWLRQV�6XSSRVH�\RX�ZDQWHG�WR�SULQW�D�PHVVDJH�LI�RQH�RI�WKH�NH\V�LQ�WKH�KDVK�%names�PDWFKHVFred��<RX�FDQ¦W�XVH�exists�EHFDXVH�LW�RQO\�FKHFNV�IRU�WKH�H[DFW�NH\��<RX�FRXOG�GR�LW

221

ZLWK�D�foreach�WKDW�WHVWV�HDFK�NH\�ZLWK�WKH�UHJXODU�H[SUHVVLRQ�RSHUDWRU��VNLSSLQJ�WKRVHWKDW�GRQ¦W�PDWFK��:KHQ�\RX�ILQG�RQH�WKDW�GRHV�PDWFK��\RX�FDQ�FKDQJH�WKH�YDOXH�RI$flag�DQG�VNLS�WKH�UHVW�RI�WKH�LWHUDWLRQV�ZLWK�last�

my $flag = 0;foreach my $key ( keys %names ) { next unless $key =~ /Fred/; $flag = $key; last; }

print "I found a key matching 'Fred'. It was $flag\n" if $flag;

:KHZ��7KDW�ZDV�D�ORW�RI�ZRUN�MXVW�WR�H[SODLQ�LW��EXW�LW�ZRUNV�LQ�DQ\�YHUVLRQ�RI�3HUO���:LWK�WKH�VPDUW�PDWFK�RSHUDWRU��\RX�MXVW�QHHG�WKH�KDVK�RQ�WKH�OHIWKDQG�VLGH�DQG�WKHUHJXODU�H[SUHVVLRQ�RSHUDWRU�RQ�WKH�ULJKWKDQG�VLGH�

use 5.010;

say "I found a key matching 'Fred'" if %names ~~ /Fred/;

7KH�VPDUW�PDWFK�RSHUDWRU�NQRZV�ZKDW�WR�GR�EHFDXVH�LW�VHHV�D�KDVK�DQG�D�UHJXODU�H[�SUHVVLRQ��:LWK�WKRVH�WZR�RSHUDQGV��WKH�VPDUW�PDWFK�RSHUDWRU�NQRZV�WR�ORRN�WKURXJKWKH�NH\V�LQ�%names�DQG�DSSO\�WKH�UHJXODU�H[SUHVVLRQ�WR�HDFK�RQH��,I�LW�ILQGV�RQH�WKDWPDWFKHV��LW�DOUHDG\�NQRZV�WR�VWRS�DQG�UHWXUQ�WUXH��,W¦V�QRW�WKH�VDPH�VRUW�RI�PDWFK�DVWKH�VFDODU�DQG�UHJXODU�H[SUHVVLRQ��,W¦V�VPDUW��LW�GRHV�ZKDW¦V�ULJKW�IRU�WKH�VLWXDWLRQ��,W¦VMXVW�WKDW�WKH�RSHUDWRU�LV�WKH�VDPH��HYHQ�WKRXJK�WKH�RSHUDWLRQ�LVQ¦W�

,I�\RX�ZDQW�WR�FRPSDUH�WZR�DUUD\V��OLPLWLQJ�WKHP�WR�WKH�VDPH�VL]H�MXVW�WR�PDNH�WKLQJVVLPSOHU���\RX�FRXOG�JR�WKURXJK�WKH�LQGLFHV�RI�RQH�RI�WKH�DUUD\V�DQG�FRPSDUH�WKH�FRU�UHVSRQGLQJ�HOHPHQWV�LQ�HDFK�RI�WKH�DUUD\V��(DFK�WLPH�WKH�FRUUHVSRQGLQJ�HOHPHQWV�DUHWKH�VDPH��\RX�LQFUHPHQW�WKH�$equal�FRXQWHU��$IWHU�WKH�ORRS��LI�$equal�LV�WKH�VDPH�DV�WKHQXPEHU�RI�HOHPHQWV�LQ�@names1��WKHQ�WKH�DUUD\V�PXVW�EH�WKH�VDPH�

my $equal = 0;foreach my $index ( 0 .. $#names1 ) { last unless $names1[$index] eq $names2[$index]; $equal++; }

print "The arrays have the same elements!\n" if $equal == @names1;

$JDLQ��WKDW¦V�WRR�PXFK�ZRUN��:RXOGQ¦W�LW�EH�JUHDW�LI�WKHUH�ZDV�DQ�HDV\�ZD\�WR�GR�WKDW":DLW��+RZ�DERXW�WKH�VPDUW�PDWFK�RSHUDWRU"�-XVW�SXW�WKH�DUUD\V�RQ�HLWKHU�VLGH�RI�WKH~~��7KLV�OLWWOH�ELW�RI�FRGH�GRHV�WKH�VDPH�WKLQJV�DV�WKH�ODVW�H[DPSOH��EXW�ZLWK�DOPRVW�QRFRGH�

use 5.010;

say "The arrays have the same elements!" if @names1 ~~ @names2;

222 | Chapter 15:ಗSmart Matching and given-when

2ND\��RQH�PRUH�H[DPSOH��6XSSRVH�\RX�FDOO�D�IXQFWLRQ�DQG�ZDQW�WR�FKHFN�WKDW�LWV�UHWXUQYDOXH�LV�RQH�RI�D�VHW�RI�SRVVLEOH�RU�H[SHFWHG�YDOXHV��*RLQJ�EDFN�WR�WKH�max()�VXEURXWLQHLQ�&KDSWHU����\RX�NQRZ�WKDW�max()�VKRXOG�UHWXUQ�RQH�RI�WKH�YDOXHV�\RX�SDVVHG�LW��<RXFRXOG�FKHFN�WKDW�E\�FRPSDULQJ�WKH�UHWXUQ�YDOXH�RI�max�WR�LWV�DUJXPHQW�OLVW�XVLQJ�WKHVDPH�WHFKQLTXHV�DV�WKH�SUHYLRXV�KDUG�ZD\V�

my @nums = qw( 1 2 3 27 42 );my $result = max( @nums );

my $flag = 0;foreach my $num ( @nums ) { next unless $result == $num; $flag = 1; last; }

print "The result is one of the input values\n" if $flag;

<RX�DOUHDG\�NQRZ�ZKDW�ZH�DUH�JRLQJ�WR�VD\��WKDW¦V�WRR�PXFK�ZRUN��<RX�FDQ�JHW�ULG�RIDOO�RI�WKH�FRGH�LQ�WKH�PLGGOH�E\�XVLQJ�~~��7KLV�LV�PXFK�HDVLHU�WKDQ�WKH�SUHYLRXV�H[DPSOH�

use 5.010;

my @nums = qw( 1 2 3 27 42 );my $result = max( @nums );

say "The result [$result] is one of the input values (@nums)" if @nums ~~ $result;

<RX�FDQ�DOVR�ZULWH�WKDW�VPDUW�PDWFK�ZLWK�WKH�RSHUDQGV�LQ�WKH�RWKHU�RUGHU�DQG�JHW�WKHVDPH�DQVZHU��7KH�VPDUW�PDWFK�RSHUDWRU�GRHVQ¦W�FDUH�ZKLFK�RSHUDQGV�DUH�RQ�ZKLFK�VLGH�

use 5.010;

my @nums = qw( 1 2 3 27 42 );my $result = max( @nums );

say "The result [$result] is one of the input values (@nums)" if $result ~~ @nums;

7KH�VPDUW�PDWFK�RSHUDWRU�LV�FRPPXWDWLYH��ZKLFK�\RX�PD\�UHPHPEHU�IURP�KLJK�VFKRRODOJHEUD�DV�WKH�IDQF\�ZD\�WR�VD\�WKDW�WKH�RUGHU�RI�WKH�RSHUDQGV�GRHVQ¦W�PDWWHU��7KH�VPDUWPDWFK�RSHUDWRU�LV�MXVW�OLNH�DGGLWLRQ�RU�PXOWLSOLFDWLRQ��\RX�JHW�WKH�VDPH�DQVZHU�ERWKZD\V��,W�GRHVQ¦W�PDWWHU�ZKDW�VRUW�RI�PDWFKLQJ�LW¦V�GRLQJ�HLWKHU��7KHVH�WZR�DUH�WKH�VDPH�

use 5.010;

say "I found a name matching 'Fred'" if $name ~~ /Fred/;say "I found a name matching 'Fred'" if /Fred/ ~~ $name;

The Smart Match Operator | 223

Smart Match Precedence1RZ�WKDW�\RX¦YH�VHHQ�KRZ�WKH�VPDUW�PDWFK�RSHUDWRU�FDQ�VDYH�\RX�D�ORW�RI�ZRUN��\RXMXVW�QHHG�WR�NQRZ�KRZ�WR�WHOO�ZKLFK�VRUW�RI�PDWFK�LW�ZLOO�GR��)RU�WKDW�\RX�KDYH�WR�FKHFNWKH�WDEOH�LQ�WKH�SHUOV\Q�GRFXPHQWDWLRQ�XQGHU�£6PDUW�PDWFKLQJ�LQ�GHWDLO�¤�7DEOH�����VKRZV�VRPH�RI�WKH�WKLQJV�WKH�VPDUW�PDWFK�RSHUDWRU�FDQ�GR�

7DEOH�������6PDUW�PDWFK�RSHUDWLRQV�IRU�SDLUV�RI�RSHUDQGV

Example Type of match

%a ~~ %b Hash keys identical

%a ~~ @b At least one key in %a is in @b

%a ~~ /Fred/ At least one key matches pattern

%a ~~ 'Fred' Hash key existence exists $a{Fred}

@a ~~ @b Arrays are the same

@a ~~ /Fred/ At least one element matches pattern

@a ~~ 123 At least one element is 123, numerically

@a ~~ 'Fred' At least one element is 'Fred', stringwise

$name ~~ undef $name is not defined

$name ~~ /Fred/ Pattern match

123 ~~ '123.0' Numeric equality with “numish” string

'Fred' ~~ 'Fred' String equality

123 ~~ 456 Numeric equality

:KHQ�\RX�XVH�WKH�VPDUW�PDWFK�RSHUDWRU��3HUO�JRHV�WR�WKH�WRS�RI�WKH�FKDUW�DQG�VWDUWVORRNLQJ�IRU�D�W\SH�RI�PDWFK�WKDW�FRUUHVSRQGV�WR�LWV�WZR�RSHUDQGV��,W�WKHQ�GRHV�WKH�ILUVWW\SH�RI�PDWFK�LW�ILQGV��7KH�RUGHU�RI�WKH�RSHUDQGV�GRHVQ¦W�PDWWHU��)RU�LQVWDQFH��\RX�KDYHDQ�DUUD\�DQG�D�KDVK�ZLWK�WKH�VPDUW�PDWFK�

use 5.010;

if( @array ~~ %hash ) { ... }

3HUO�ILUVW�ILQGV�WKH�PDWFK�W\SH�IRU�D�KDVK�DQG�DQ�DUUD\��ZKLFK�FKHFNV�WKDW�DW�OHDVW�RQHRI�WKH�HOHPHQWV�RI�@array�LV�D�NH\�LQ�%hash��7KDW�RQH�LV�HDV\�EHFDXVH�WKHUH�LV�RQO\�RQHW\SH�RI�PDWFK�IRU�WKRVH�WZR�RSHUDQGV��:KDW�LI�\RX�KDYH�WZR�VFDODUV"

use 5.010;

if( $fred ~~ $barney ) { ... }

224 | Chapter 15:ಗSmart Matching and given-when

6R�IDU�\RX�FDQ¦W�WHOO�ZKDW�VRUW�RI�PDWFK�LW�LV�JRLQJ�WR�GR�EHFDXVH�3HUO�QHHGV�WR�ORRN�LQVLGH$scalar1�DQG�$scalar2�WR�VHH�ZKDW�ZRXOG�KDSSHQ��3HUO�FDQ¦W�GHFLGH�WKDW�XQWLO�LW�VHHVWKH�DFWXDO�GDWD�LQVLGH�WKH�VFDODUV��,V�WKH�VPDUW�PDWFK�JRLQJ�WR�GR�D�QXPHULF�RU�VWULQJFRPSDULVRQ"

7R�ILJXUH�RXW�KRZ�3HUO�ZLOO�FRPSDUH�$fred�DQG�$barney��3HUO�ORRNV�DW�WKH�YDOXHV�DQGIROORZV�WKH�VDPH�UXOHV�ZH�MXVW�WROG�\RX��,W�JRHV�GRZQ�WKH�SUHFHGHQFH�FKDUW�XQWLO�LW�ILQGVD�VLWXDWLRQ�WKDW�PDWFKHV��WKHQ�XVHV�WKH�ULJKW�FRPSDULVRQ�IRU�WKDW�VLWXDWLRQ��7KHUH¦V�DELW�RI�D�WULFN��3HUO�FDQ�UHFRJQL]H�VRPH�VWULQJV�DV�QXPEHUV��ZKLFK�LW�FDOOV�QXPLVK�VWULQJV�7KRVH�DUH�VWULQJV�VXFK�DV�'123'��'3.14149'��DQG�VR�RQ��:H¦YH�TXRWHG�HDFK�RQH��VR�WKH\DUH�UHDOO\�VWULQJV��ZKLFK�DUH�MXVW�VHTXHQFHV�RI�FKDUDFWHUV��+RZHYHU��3HUO�FDQ�FRQYHUWWKHP�WR�QXPEHUV�ZLWKRXW�ZDUQLQJV��,I�3HUO�VHHV�QXPEHUV�RU�QXPLVK�VWULQJV�RQ�ERWKVLGHV�RI�WKH�VPDUW�PDWFK�RSHUDWRU��LW�GRHV�D�QXPHULF�FRPSDULVRQ��2WKHUZLVH��LW�GRHV�DVWULQJ�FRPSDULVRQ�

The given Statement7KH�given-when�FRQWURO�VWUXFWXUH�DOORZV�\RX�WR�UXQ�D�EORFN�RI�FRGH�ZKHQ�WKH�DUJXPHQWWR�given�VDWLVILHV�D�FRQGLWLRQ��,W¦V�3HUO¦V�HTXLYDOHQW�WR�&¦V�switch�VWDWHPHQW��EXW�DV�ZLWKPRVW�WKLQJV�3HUO\��LW¦V�D�ELW�PRUH�IDQF\��VR�LW�JHWV�D�IDQFLHU�QDPH�

+HUH¦V�D�ELW�RI�FRGH�WKDW�WDNHV�WKH�ILUVW�DUJXPHQW�IURP�WKH�FRPPDQG�OLQH��$ARGV[0]��DQGJRHV�WKURXJK�WKH�when�FRQGLWLRQV�WR�VHH�LI�LW�FDQ�ILQG�Fred��(DFK�when�EORFN�UHSRUWV�DGLIIHUHQW�ZD\�WKDW�LW�IRXQG�Fred��VWDUWLQJ�ZLWK�WKH�OHDVW�UHVWULFWLYH�WR�WKH�PRVW�

use 5.010;

given( $ARGV[0] ) { when( /fred/i ) { say 'Name has fred in it' } when( /^Fred/ ) { say 'Name starts with Fred' } when( 'Fred' ) { say 'Name is Fred' } default { say "I don't see a Fred" } }

7KH�given�DOLDVHV�LWV�DUJXPHQW�WR�$_� �DQG�HDFK�RI�WKH�when�FRQGLWLRQV�WULHV�DQ�LPSOLFLWVPDUW�PDWFK�DJDLQVW�$_��<RX�FRXOG�UHZULWH�WKH�SUHYLRXV�H[DPSOH�ZLWK�H[SOLFLW�VPDUWPDWFKLQJ�WR�VHH�H[DFWO\�ZKDW¦V�KDSSHQLQJ�

use 5.010;

given( $ARGV[0] ) { when( $_ ~~ /fred/i ) { say 'Name has fred in it' } when( $_ ~~ /^Fred/ ) { say 'Name starts with Fred' } when( $_ ~~ 'Fred' ) { say 'Name is Fred' } default { say "I don't see a Fred" } }

,Q�3HUO�SDUODQFH��given�LV�D�WRSLFDOL]HU�EHFDXVH�LW�PDNHV�LWV�DUJXPHQW�WKH�WRSLF��WKH�IDQF\�QHZ�QDPH�IRU�$_�LQ3HUO���

The given Statement | 225

,I�$_�GRHV�QRW�VDWLVI\�DQ\�RI�WKH�when�FRQGLWLRQV��3HUO�H[HFXWHV�WKH�default�EORFN��+HUH¦VWKH�RXWSXW�IURP�VHYHUDO�WULDO�UXQV�

$ perl5.10.0 switch.pl FredName has fred in it$ perl5.10.0 switch.pl FrederickName has fred in it$ perl5.10.0 switch.pl BarneyI don't see a Fred$ perl5.10.0 switch.pl AlfredName has fred in it

£%LJ�GHDO�¤�\RX�VD\��£,�FRXOG�ZULWH�WKLV�H[DPSOH�ZLWK�if-elsif-else�¤�7KH�QH[W�H[DPSOHGRHV�MXVW�WKDW�XVLQJ�D�$_�GHFODUHG�ZLWK�my�DQG�ZLWK�DOO�WKH�VFRSLQJ�UXOHV�RI�my��DQRWKHUQHZ�IHDWXUH�RI�3HUO������

use 5.010;

{my $_ = $ARGV[0]; # lexical $_ as of 5.10!

if( $_ ~~ /fred/i ) { say 'Name has fred in it' }elsif( $_ ~~ /^Fred/ ) { say 'Name starts with Fred' }elsif( $_ ~~ 'Fred' ) { say 'Name is Fred' }else { say "I don't see a Fred" }}

,I�given�ZHUH� MXVW� WKH� VDPH� WKLQJ�DV�if-elsif-else�� LW�ZRXOGQ¦W�EH� WKDW� LQWHUHVWLQJ�8QOLNH�DQ�if-elsif-else�FRQVWUXFW��KRZHYHU��D�given-when�FDQ�VDWLVI\�RQH�FRQGLWLRQDQG�WKHQ�WU\�WKH�RWKHUV�WRR��2QFH�DQ�if-elsif-else�VDWLVILHV�D�FRQGLWLRQ��LW�ZLOO�RQO\HYHU�H[HFXWH�RQH�EORFN�RI�FRGH�

%HIRUH�ZH�JR�RQ��OHW¦V�PDNH�D�FRXSOH�PRUH�WKLQJV�H[SOLFLW�VR�WKDW�\RX�FDQ�VHH�HYHU\WKLQJWKDW¦V�KDSSHQLQJ��8QOHVV�\RX�VD\�RWKHUZLVH��WKHUH�LV�DQ�LPSOLFLW�break�DW�WKH�HQG�RI�HDFKwhen�EORFN��DQG�WKDW�WHOOV�3HUO�WR�VWRS�WKH�given-when�FRQVWUXFW�DQG�PRYH�RQ�ZLWK�WKHUHVW�RI�WKH�SURJUDP��7KH�SUHYLRXV�H[DPSOH�UHDOO\�KDV�breakV�LQ�LW��DOWKRXJK�\RX�GRQ¦WKDYH�WR�W\SH�WKHP�\RXUVHOI�

use 5.010;

given( $ARGV[0] ) { when( $_ ~~ /fred/i ) { say 'Name has fred in it'; break } when( $_ ~~ /^Fred/ ) { say 'Name starts with Fred'; break } when( $_ ~~ 'Fred' ) { say 'Name is Fred'; break } default { say "I don't see a Fred"; break } }

7KLV�GRHVQ¦W�ZRUN�YHU\�ZHOO� IRU�WKH�SUREOHP��WKRXJK��6LQFH�RXU�H[DPSOH�JRHV�IURPJHQHUDO�WR�VSHFLILF��LI�WKH�DUJXPHQW�PDWFKHV�/fred/i��3HUO�GRHVQ¦W�WHVW�DQ\�RI�WKH�whenFRQGLWLRQV��:H�GRQ¦W�JHW�WR�FKHFN�ZKHWKHU�WKH�DUJXPHQW�LV�H[DFWO\�Fred�EHFDXVH�WKHILUVW�when�EORFN�VWRSV�WKH�HQWLUH�FRQWURO�VWUXFWXUH�

226 | Chapter 15:ಗSmart Matching and given-when

,I�\RX�XVH�continue�DW�WKH�HQG�RI�D�when�LQVWHDG��3HUO�WULHV�WKH�VXFFHHGLQJ�when�VWDWHPHQWVWRR��UHSHDWLQJ�WKH�SURFHVV�LW�VWDUWHG�EHIRUH��7KDW¦V�VRPHWKLQJ�WKDW�if-elsif-else�FDQ¦WGR��:KHQ�DQRWKHU�when�VDWLVILHV�LWV�FRQGLWLRQ��3HUO�H[HFXWHV�LWV�EORFN��DJDLQ��LPSOLFLWO\EUHDNLQJ�DW�WKH�HQG�RI�WKH�EORFN�XQOHVV�\RX�VD\�RWKHUZLVH���3XWWLQJ�D�continue�DW�WKHHQG�RI�HDFK�when�EORFN�PHDQV�3HUO�ZLOO�WU\�HYHU\�FRQGLWLRQ�

use 5.010;

given( $ARGV[0] ) { when( $_ ~~ /fred/i ) { say 'Name has fred in it'; continue } when( $_ ~~ /^Fred/ ) { say 'Name starts with Fred'; continue } when( $_ ~~ 'Fred' ) { say 'Name is Fred'; continue } # OOPS! default { say "I don't see a Fred" } }

7KHUH¦V� D� VOLJKW�SUREOHP�ZLWK� WKDW� FRGH�� WKRXJK��:KHQ�ZH� UXQ� LW��ZH� VHH� WKDW� WKHdefault�EORFN�UXQV�WRR�

$ perl5.10.0 switch.pl AlfredName has fred in itI don't see a Fred

7KDW�default�EORFN�LV�UHDOO\�D�when�ZLWK�D�FRQGLWLRQ�WKDW�LV�DOZD\V�WUXH��,I�WKH�when�EHIRUHWKH�default�KDV�D�continue��3HUO�JRHV�RQ�WR�WKH�default�WRR��,W¦V�DV�LI�WKH�default�ZHUHUHDOO\�DQRWKHU�when�

use 5.010;

given( $ARGV[0] ) { when( $_ ~~ /fred/i ) { say 'Name has fred in it'; continue } when( $_ ~~ /^Fred/ ) { say 'Name starts with Fred'; continue } when( $_ ~~ 'Fred' ) { say 'Name is Fred'; continue } # OOPS! when( 1 == 1 ) { say "I don't see a Fred" } # default }

7R�JHW�DURXQG�WKLV��ZH�OHDYH�RII�WKDW�ODVW�continue��VR�WKH�ODVW�when�VWRSV�WKH�SURFHVV�

use 5.010;

given( $ARGV[0] ) { when( $_ ~~ /fred/i ) { say 'Name has fred in it'; continue } when( $_ ~~ /^Fred/ ) { say 'Name starts with Fred'; continue } when( $_ ~~ 'Fred' ) { say 'Name is Fred'; break } # OK now! when( 1 == 1 ) { say "I don't see a Fred" } }

1RZ�WKDW�ZH¦YH�VKRZQ�\RX�HYHU\WKLQJ�WKDW¦V�JRLQJ�RQ��ZH�UHZULWH�LW�LQ�WKH�LGLRPDWLFIRUP��ZKLFK�LV�KRZ�\RX�VKRXOG�XVH�LW�LQ�\RXU�SURJUDPV�

use 5.010;

given( $ARGV[0] ) { when( /fred/i ) { say 'Name has fred in it'; continue } when( /^Fred/ ) { say 'Name starts with Fred'; continue } when( 'Fred' ) { say 'Name is Fred'; }

The given Statement | 227

default { say "I don't see a Fred" } }

Dumb Matching$OWKRXJK�WKH�given-when�FDQ�XVH�VPDUW�PDWFKLQJ��\RX�FDQ�XVH�WKH�£GXPE¤�FRPSDULVRQVWKDW�\RX�DOUHDG\�NQRZ��,W¦V�QRW�UHDOO\�GXPE�� LW¦V� MXVW�WKH�UHJXODU�PDWFKLQJ�WKDW�\RXDOUHDG\�NQRZ��:KHQ�3HUO�VHHV�DQ�H[SOLFLW�FRPSDULVRQ�RSHUDWRU��RI�DQ\�W\SH��RU�WKHELQGLQJ�RSHUDWRU��LW�GRHV�RQO\�ZKDW�WKRVH�RSHUDWRUV�GR�

use 5.010;

given( $ARGV[0] ) { when( $_ =~ /fred/i ) { say 'Name has fred in it'; continue } when( $_ =~ /^Fred/ ) { say 'Name starts with Fred'; continue } when( $_ eq 'Fred' ) { say 'Name is Fred' } default { say "I don't see a Fred" } }

<RX�FDQ�HYHQ�PL[�DQG�PDWFK�GXPE�DQG�VPDUW�PDWFKLQJ��WKH�LQGLYLGXDO�when�H[SUHV�VLRQV�ILJXUH�RXW�WKHLU�FRPSDULVRQV�RQ�WKHLU�RZQ�

use 5.010;

given( $ARGV[0] ) { when( /fred/i ) { #smart say 'Name has fred in it'; continue } when( $_ =~ /^Fred/ ) { #dumb say 'Name starts with Fred'; continue } when( 'Fred' ) { #smart say 'Name is Fred' } default { say "I don't see a Fred" } }

1RWH�WKDW�WKH�GXPE�DQG�VPDUW�PDWFK�IRU�D�SDWWHUQ�PDWFK�DUH�LQGLVWLQJXLVKDEOH�VLQFHWKH�UHJXODU�H[SUHVVLRQ�RSHUDWRU�DOUHDG\�ELQGV�WR�$_�E\�GHIDXOW�

7KH�VPDUW�PDWFK�RSHUDWRU�ILQGV�WKLQJV�WKDW�DUH�WKH�VDPH��RU�PRVWO\�WKH�VDPH���VR�LWGRHVQ¦W�ZRUN�ZLWK�FRPSDULVRQV�IRU�JUHDWHU�WKDQ�RU�OHVV�WKDQ��,Q�WKRVH�FDVHV��\RX�KDYHWR�XVH�WKH�ULJKW�FRPSDULVRQ�RSHUDWRUV�

use 5.010;

given( $ARGV[0] ) { when( /^-?\d+\.\d+$/ ) { #smart say 'Not a number!' } when( $_ > 10 ) { #dumb say 'Number is greater than 10' } when( $_ < 10 ) { #dumb say 'Number is less than 10' } default { say 'Number is 10' } }

228 | Chapter 15:ಗSmart Matching and given-when

7KHUH�DUH�FHUWDLQ�VLWXDWLRQV�LQ�ZKLFK�3HUO�ZLOO�DXWRPDWLFDOO\�XVH�GXPE�PDWFKLQJ��<RXFDQ�XVH�WKH�UHVXOW�RI�D�VXEURXWLQH �LQVLGH�WKH�when��LQ�ZKLFK�FDVH��3HUO�XVHV�WKH�WUXWK�RUIDOVHQHVV�RI�WKH�UHWXUQ�YDOXH�

use 5.010;

given( $ARGV[0] ) { when( name_has_fred( $_ ) ) { #dumb say 'Name has fred in it'; continue } }

7KH�VXEURXWLQH�FDOO�UXOH�DOVR�DSSOLHV�WR�WKH�3HUO�EXLOW�LQV�defined��exists��DQG�eof�WRR�VLQFH�WKRVH�DUH�GHVLJQHG�WR�UHWXUQ�WUXH�RU�IDOVH�

1HJDWHG�H[SUHVVLRQV��LQFOXGLQJ�QHJDWHG�UHJXODU�H[SUHVVLRQV��GRQ¦W�XVH�D�VPDUW�PDWFKHLWKHU��7KHVH�FDVHV�DUH�MXVW�OLNH�WKH�FRQWURO�VWUXFWXUH�FRQGLWLRQV�\RX�VDZ�LQ�SUHYLRXVFKDSWHUV�

use 5.010;

given( $ARGV[0] ) { when( ! $boolean ) { #dumb say 'Name has fred in it' } when( ! /fred/i } { #dumb say 'Does not match Fred' } }

when with Many Items6RPHWLPHV�\RX¦OO�ZDQW�WR�JR�WKURXJK�PDQ\�LWHPV��EXW�given�WDNHV�RQO\�RQH�WKLQJ�DW�DWLPH��,Q�WKLV�FDVH��\RX�FRXOG�ZUDS�given�LQ�D�foreach�ORRS��,I�\RX�ZDQWHG�WR�JR�WKURXJK@names��\RX�FRXOG�DVVLJQ�WKH�FXUUHQW�HOHPHQW�WR�$name��WKHQ�XVH�WKDW�IRU�given�

use 5.010;

foreach my $name ( @names ) { given( $name ) { ... } }

*XHVV�ZKDW"�<HS��WKDW¦V�WRR�PXFK�ZRUN���$UH�\RX�WLUHG�RI�DOO�RI�WKLV�H[WUD�ZRUN�\HW"�7KLV�WLPH��OHW¦V�DOLDV�WKH�FXUUHQW�HOHPHQW�RI�@names�MXVW�VR�given�FDQ�DOLDV�LW�DOVR��3HUOVKRXOG�EH�VPDUWHU�WKDQ�WKDW��'RQ¦W�ZRUU\��LW�LV�

7R�JR�WKURXJK�PDQ\�HOHPHQWV��\RX�GRQ¦W�QHHG�WKH�given��/HW�foreach�SXW�WKH�FXUUHQWHOHPHQW�LQ�$_�RQ�LWV�RZQ��,I�\RX�ZDQW�WR�XVH�VPDUW�PDWFKLQJ��WKH�FXUUHQW�HOHPHQW�KDVWR�EH�LQ�$_�

3HUO�GRHVQ¦W�XVH�VPDUW�PDWFKLQJ�IRU�PHWKRG�FDOOV�HLWKHU��EXW�ZH�GRQ¦W�FRYHU�REMHFW�RULHQWHG�SURJUDPPLQJXQWLO�,QWHUPHGLDWH�3HUO��2¦5HLOO\��

when with Many Items | 229

use 5.010;

foreach ( @names ) { # don't use a named variable! when( /fred/i ) { say 'Name has fred in it'; continue } when( /^Fred/ ) { say 'Name starts with Fred'; continue } when( 'Fred' ) { say 'Name is Fred'; } default { say "I don't see a Fred" } }

,I�\RX�DUH�JRLQJ�WR�JR�WKURXJK�VHYHUDO�QDPHV�WKRXJK��\RX�SUREDEO\�ZDQW�WR�VHH�ZKLFKQDPH�\RX¦UH�ZRUNLQJ�RQ��<RX�FDQ�SXW�RWKHU�VWDWHPHQWV�LQ�WKH�foreach�EORFN��VXFK�DVD�say�VWDWHPHQW�

use 5.010;

foreach ( @names ) { # don't use a named variable! say "\nProcessing $_";

when( /fred/i ) { say 'Name has fred in it'; continue } when( /^Fred/ ) { say 'Name starts with Fred'; continue } when( 'Fred' ) { say 'Name is Fred'; } default { say "I don't see a Fred" } }

<RX�FDQ�HYHQ�SXW�H[WUD�VWDWHPHQWV�EHWZHHQ�WKH�whenV��VXFK�DV�SXWWLQJ�D�GHEXJJLQJVWDWHPHQW�ULJKW�EHIRUH�WKH�default��ZKLFK�\RX�FDQ�DOVR�GR�ZLWK�given��

use 5.010;

foreach ( @names ) { # don't use a named variable! say "\nProcessing $_";

when( /fred/i ) { say 'Name has fred in it'; continue } when( /^Fred/ ) { say 'Name starts with Fred'; continue } when( 'Fred' ) { say 'Name is Fred'; } say "Moving on to default..."; default { say "I don't see a Fred" } }

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >��@�5HZULWH�\RXU�QXPEHU�JXHVVLQJ�SURJUDP�IURP�([HUFLVH���LQ�&KDSWHU����WR�XVHgiven��+RZ�ZRXOG�\RX�KDQGOH�QRQQXPHULF�LQSXW"�<RX�GRQ¦W�QHHG�WR�XVH�VPDUWPDWFKLQJ�

�� >��@�:ULWH�D�SURJUDP�XVLQJ�given-when�WKDW�WDNHV�D�QXPEHU�DV�LWV�LQSXW��WKHQ�SULQWV£)L]]¤�LI�LW�LV�GLYLVLEOH�E\�WKUHH��£%LQ¤�LI�LW�LV�GLYLVLEOH�E\�ILYH��DQG�£6DXVDJH¤�LI�LW�LVGLYLVLEOH�E\�VHYHQ��)RU�D�QXPEHU�OLNH�����LW�VKRXOG�SULQW�£)L]]¤�DQG�£%LQ¤�VLQFH���LV�GLYLVLEOH�E\�ERWK���DQG����:KDW¦V�WKH�ILUVW�QXPEHU�IRU�ZKLFK�\RXU�SURJUDP�SULQWV£)L]]�%LQ�6DXVDJH¤"

230 | Chapter 15:ಗSmart Matching and given-when

�� >��@�8VLQJ�for-when��ZULWH�D�SURJUDP�WKDW�JRHV�WKURXJK�D�OLVW�RI�ILOHV�RQ�WKH�FRP�PDQG�OLQH�DQG�UHSRUWV�LI�HDFK�ILOH�LV�UHDGDEOH��ZULWDEOH��RU�H[HFXWDEOH��<RX�GRQ¦WQHHG�WR�XVH�VPDUW�PDWFKLQJ�

�� >��@�8VLQJ�given�DQG�VPDUW�PDWFKLQJ��ZULWH�D�SURJUDP�WKDW�UHSRUWV�DOO�WKH�GLYLVRUV�H[FHSW���DQG�WKH�QXPEHU�LWVHOI��RI�D�QXPEHU�\RX�VSHFLI\�RQ�WKH�FRPPDQG�OLQH�)RU�LQVWDQFH��IRU�WKH�QXPEHU�����\RXU�SURJUDP�VKRXOG�UHSRUW�WKDW�LW�LV�GLYLVLEOH�E\����������DQG�����,I�WKH�QXPEHU�LV�SULPH��LW�KDV�QR�GLYLVRUV���LW�VKRXOG�UHSRUW�WKDWWKH�QXPEHU�LV�SULPH�LQVWHDG��,I�WKH�FRPPDQG�OLQH�DUJXPHQW�LV�QRW�D�QXPEHU��LWVKRXOG�UHSRUW�WKH�HUURU�DQG�QRW�WU\�WR�FRPSXWH�WKH�GLYLVRUV��$OWKRXJK�\RX�FRXOGGR�WKLV�ZLWK�if�FRQVWUXFWV�DQG�ZLWK�GXPE�PDWFKLQJ��XVH�RQO\�VPDUW�PDWFKLQJ�

7R�JHW�\RX�VWDUWHG��KHUH¦V�D�VXEURXWLQH�WR�UHWXUQ�D�OLVW�RI�GLYLVRUV��,W�WULHV�DOO�RI�WKHQXPEHUV�XS�WR�RQH�KDOI�RI�$number�

sub divisors { my $number = shift;

my @divisors = (); foreach my $divisor ( 2 .. $number/2 ) ) { push @divisors, $divisor unless $_ % $divisor; }

return @divisors; }

�� >��@�0RGLI\�WKH�SURJUDP�IURP�WKH�SUHYLRXV�H[HUFLVH�WR�DOVR�UHSRUW�LI�WKH�QXPEHULV�RGG�RU�HYHQ��LI�WKH�QXPEHU�LV�SULPH��\RX�ILQG�QR�GLYLVRUV�RWKHU�WKDQ���DQG�WKHQXPEHU�LWVHOI���DQG�LI�LW�LV�GLYLVLEOH�E\�\RXU�IDYRULWH�QXPEHU��$JDLQ��XVH�RQO\�VPDUWPDWFKLQJ�

Exercises | 231

CHAPTER 16

Process Management

2QH�RI�WKH�EHVW�SDUWV�RI�EHLQJ�D�SURJUDPPHU�LV�ODXQFKLQJ�VRPHRQH�HOVH¦V�FRGH�VR�WKDW\RX�GRQ¦W�KDYH�WR�ZULWH�LW�\RXUVHOI��,W¦V�WLPH�WR�OHDUQ�KRZ�WR�PDQDJH�\RXU�FKLOGUHQ �E\ODXQFKLQJ�RWKHU�SURJUDPV�GLUHFWO\�IURP�3HUO�

$QG�OLNH�HYHU\WKLQJ�HOVH�LQ�3HUO��7KHUH¦V�0RUH�7KDQ�2QH�:D\�7R�'R�,W��ZLWK�ORWV�RIRYHUODS��YDULDWLRQV��DQG�VSHFLDO�IHDWXUHV��6R��LI�\RX�GRQ¦W�OLNH�WKH�ILUVW�ZD\��MXVW�UHDG�RQIRU�DQRWKHU�SDJH�RU�WZR�IRU�D�VROXWLRQ�PRUH�WR�\RXU�OLNLQJ�

3HUO�LV�YHU\�SRUWDEOH��PRVW�RI�WKH�UHVW�RI�WKLV�ERRN�GRHVQ¦W�QHHG�PDQ\�QRWHV�VD\LQJ�WKDWLW�ZRUNV�WKLV�ZD\�RQ�8QL[�V\VWHPV�DQG�WKDW�ZD\�RQ�:LQGRZV�DQG�WKH�RWKHU�ZD\�RQ906��%XW�ZKHQ�\RX¦UH�VWDUWLQJ�RWKHU�SURJUDPV�RQ�\RXU�PDFKLQH��GLIIHUHQW�SURJUDPVDUH�DYDLODEOH�RQ�D�0DFLQWRVK�WKDQ�\RX¦OO�OLNHO\�ILQG�RQ�D�&UD\��7KH�H[DPSOHV�LQ�WKLVFKDSWHU�DUH�SULPDULO\�8QL[�EDVHG��LI�\RX�KDYH�D�QRQ�8QL[�V\VWHP��\RX�FDQ�H[SHFW�WRVHH�VRPH�GLIIHUHQFHV�

The system Function7KH� VLPSOHVW�ZD\� WR� ODXQFK�D� FKLOG�SURFHVV� LQ�3HUO� WR� UXQ�D�SURJUDP� LV� WKH�systemIXQFWLRQ��)RU�H[DPSOH��WR�LQYRNH�WKH�8QL[�GDWH�FRPPDQG�IURP�ZLWKLQ�3HUO��LW�ORRNV�OLNH�

system "date";

7KH�FKLOG�SURFHVV�UXQV�WKH�GDWH�FRPPDQG��ZKLFK�LQKHULWV�3HUO¦V�VWDQGDUG�LQSXW��VWDQG�DUG�RXWSXW��DQG�VWDQGDUG�HUURU��7KLV�PHDQ�WKDW�WKH�QRUPDO�VKRUW�GDWH�DQG�WLPH�VWULQJJHQHUDWHG�E\�GDWH�HQGV�XS�ZKHUHYHU�3HUO¦V�STDOUT�ZDV�DOUHDG\�JRLQJ�

7KH�SDUDPHWHU�WR�WKH�V\VWHP�IXQFWLRQ�LV�JHQHUDOO\�ZKDWHYHU�\RX¦G�QRUPDOO\�W\SH�DW�WKHVKHOO��6R��LI�LW�ZHUH�D�PRUH�FRPSOLFDWHG�FRPPDQG��OLNH�OV��O��+20(��ZH¦G�MXVW�KDYH�WRSXW�DOO�WKDW�LQWR�WKH�SDUDPHWHU�

system 'ls -l $HOME';

&KLOG�SURFHVVHV��WKDW�LV�

233

1RWH�WKDW�ZH�KDG�WR�VZLWFK�KHUH�IURP�GRXEOH�TXRWHV�WR�VLQJOH�TXRWHV��VLQFH�$HOME�LV�WKHVKHOO¦V�YDULDEOH��2WKHUZLVH��WKH�VKHOO�ZRXOG�QHYHU�KDYH�VHHQ�WKH�GROODU�VLJQ��VLQFH�WKDW¦VDOVR�DQ�LQGLFDWRU�IRU�3HUO�WR�LQWHUSRODWH��$OWHUQDWLYHO\��ZH�FRXOG�ZULWH�

system "ls -l \$HOME";

%XW�WKDW�FDQ�TXLFNO\�EHFRPH�XQZLHOG\�

1RZ��WKH�GDWH�FRPPDQG�LV�RXWSXW�RQO\��EXW�OHW¦V�VD\�LW�KDG�EHHQ�D�FKDWW\�FRPPDQG�DVNLQJ�ILUVW�£IRU�ZKLFK�WLPH�]RQH�GR�\RX�ZDQW�WKH�WLPH"¤ �7KDW¦OO�HQG�XS�RQ�VWDQGDUGRXWSXW�� DQG� WKHQ� WKH� SURJUDP�ZLOO� OLVWHQ� RQ� VWDQGDUG� LQSXW� �LQKHULWHG� IURP� 3HUO¦VSTDIN��IRU�WKH�UHVSRQVH��<RX¦OO�VHH�WKH�TXHVWLRQ��DQG�W\SH�LQ�WKH�DQVZHU��OLNH�£=LPEDEZHWLPH¤���DQG�WKHQ�GDWH�ZLOO�ILQLVK�LWV�GXW\�

:KLOH�WKH�FKLOG�SURFHVV�LV�UXQQLQJ��3HUO�LV�SDWLHQWO\�ZDLWLQJ�IRU�LW�WR�ILQLVK��6R��LI�WKHGDWH�FRPPDQG�WRRN����VHFRQGV��WKHQ�3HUO�LV�SDXVHG�IRU�WKRVH����VHFRQGV��<RX�FDQ�XVHWKH�VKHOO¦V�IDFLOLW\�WR�ODXQFK�D�EDFNJURXQG�SURFHVV���KRZHYHU�

system "long_running_command with parameters &";

+HUH��WKH�VKHOO�ODXQFKHV��WKHQ�QRWLFHV�WKH�DPSHUVDQG�DW�WKH�HQG�RI�WKH�FRPPDQG�OLQH�ZKLFK�FDXVHV�LW�WR�SXW�ORQJBUXQQLQJBFRPPDQG�LQWR�WKH�EDFNJURXQG��$QG�WKHQ�WKH�VKHOOH[LWV� UDWKHU� TXLFNO\�� ZKLFK� 3HUO� QRWLFHV� DQG� PRYHV� RQ�� ,Q� WKLV� FDVH�� WKHORQJBUXQQLQJBFRPPDQG�LV�UHDOO\�D�JUDQGFKLOG�RI�WKH�3HUO�SURFHVV��WR�ZKLFK�3HUO�UHDOO\KDV�QR�GLUHFW�DFFHVV�RU�NQRZOHGJH�

:KHQ�WKH�FRPPDQG�LV�£VLPSOH�HQRXJK�¤�QR�VKHOO�JHWV�LQYROYHG��VR�IRU�WKH�GDWH�DQG�OVFRPPDQGV�HDUOLHU��WKH�UHTXHVWHG�FRPPDQG�LV�ODXQFKHG�GLUHFWO\�E\�3HUO��ZKLFK�VHDUFKHVWKH�LQKHULWHG�PATH®�WR�ILQG�WKH�FRPPDQG��LI�QHFHVVDU\��%XW�LI�WKHUH¦V�DQ\WKLQJ�ZHLUG�LQWKH�VWULQJ��VXFK�DV�VKHOO�PHWDFKDUDFWHUV�OLNH�WKH�GROODU�VLJQ��VHPLFRORQ��RU�YHUWLFDO�EDU��WKHQ�WKH�VWDQGDUG�%RXUQH�6KHOO���ELQ�VK��JHWV�LQYRNHG�WR�ZRUN�WKURXJK�WKH�FRPSOLFDWHGVWXII�� ,Q� WKDW� FDVH�� WKH� VKHOO� LV� WKH� FKLOG� SURFHVV�� DQG� WKH� UHTXHVWHG� FRPPDQGV� DUHJUDQGFKLOGUHQ��RU�IXUWKHU�RIIVSULQJ���)RU�H[DPSOH��\RX�FDQ�ZULWH�DQ�HQWLUH�OLWWOH�VKHOOVFULSW�LQ�WKH�DUJXPHQW�

system 'for i in *; do echo == $i ==; cat $i; done';

+HUH�DJDLQ��ZH¦UH�XVLQJ�VLQJOH�TXRWHV�EHFDXVH�WKH�GROODU�VLJQV�KHUH�DUH�PHDQW�IRU�WKHVKHOO�DQG�QRW�IRU�3HUO��'RXEOH�TXRWHV�ZRXOG�KDYH�SHUPLWWHG�3HUO�WR�H[SDQG�$i�WR�LWV

$V�IDU�DV�ZH�NQRZ��QR�RQH�KDV�PDGH�D�GDWH�FRPPDQG�WKDW�ZRUNV�OLNH�WKLV�

� 6HH� ZKDW� ZH�PHDQ� DERXW� WKLV� GHSHQGLQJ� XSRQ� \RXU� V\VWHP"� 7KH� 8QL[� VKHOO� ��ELQ�VK�� OHWV� \RX� XVH� WKHDPSHUVDQG�RQ�WKLV�NLQG�RI�FRPPDQG�WR�PDNH�D�EDFNJURXQG�SURFHVV��,I�\RXU�QRQ�8QL[�V\VWHP�GRHVQ¦W�VXSSRUWWKLV�ZD\�WR�ODXQFK�D�EDFNJURXQG�SURFHVV��WKHQ�\RX�FDQ¦W�GR�LW�WKLV�ZD\��WKDW¦V�DOO�

® 7KH�PATH�FDQ�EH�FKDQJHG�E\�DGMXVWLQJ�$ENV{'PATH'}�DW�DQ\�WLPH��,QLWLDOO\��WKLV�LV�WKH�HQYLURQPHQW�YDULDEOHLQKHULWHG�IURP�WKH�SDUHQW�SURFHVV��XVXDOO\�WKH�VKHOO���&KDQJLQJ�WKLV�YDOXH�DIIHFWV�QHZ�FKLOG�SURFHVVHV��EXWFDQQRW�DIIHFW�DQ\�SUHFHGLQJ�SDUHQW�SURFHVVHV��7KH�PATH�LV�WKH�OLVW�RI�GLUHFWRULHV�ZKHUH�H[HFXWDEOH�SURJUDPV�FRPPDQGV��DUH�IRXQG��HYHQ�RQ�VRPH�QRQ�8QL[�V\VWHPV�

2U�ZKDWHYHU�ZDV�GHWHUPLQHG�ZKHQ�3HUO�ZDV�EXLOW��3UDFWLFDOO\�DOZD\V��WKLV�LV�MXVW��ELQ�VK�RQ�8QL[�OLNH�V\VWHPV�

234 | Chapter 16:ಗProcess Management

FXUUHQW�3HUO�YDOXH�DQG�QRW�OHW�WKH�VKHOO�H[SDQG�LW�WR�LWV�RZQ�YDOXH� �%\�WKH�ZD\��WKDW�OLWWOHVKHOO�VFULSW�JRHV�WKURXJK�DOO�RI�WKH�QRUPDO�ILOHV�LQ�WKH�FXUUHQW�GLUHFWRU\��SULQWLQJ�RXWHDFK�RQH¦V�QDPH�DQG�FRQWHQWV��\RX�FDQ�WU\�LW�RXW�\RXUVHOI�LI�\RX�GRQ¦W�EHOLHYH�XV�

Avoiding the Shell7KH�V\VWHP�RSHUDWRU�PD\�DOVR�EH�LQYRNHG�ZLWK�PRUH�WKDQ�RQH�DUJXPHQW���LQ�ZKLFKFDVH��D�VKHOO�GRHVQ¦W�JHW�LQYROYHG��QR�PDWWHU�KRZ�FRPSOLFDWHG�WKH�WH[W�

my $tarfile = "something*wicked.tar";my @dirs = qw(fred|flintstone <barney&rubble> betty );system "tar", "cvf", $tarfile, @dirs;

,Q�WKLV�FDVH��WKH�ILUVW�SDUDPHWHU��"tar"�KHUH��JLYHV�WKH�QDPH�RI�D�FRPPDQG�IRXQG�LQ�WKHQRUPDO�PATH�VHDUFKLQJ�ZD\��ZKLOH�WKH�UHPDLQLQJ�DUJXPHQWV�DUH�SDVVHG��RQH�E\�RQH�GLUHFWO\�WR�WKDW�FRPPDQG��(YHQ�LI�WKH�DUJXPHQWV�KDYH�VKHOO�VLJQLILFDQW�FKDUDFWHUV��VXFKDV�WKH�QDPH�LQ�$tarfile�RU�WKH�GLUHFWRU\�QDPHV�LQ�@dirs��WKH�VKHOO�QHYHU�JHWV�D�FKDQFHWR�PDQJOH�WKH�VWULQJ��6R�WKDW�tar�FRPPDQG�ZLOO�JHW�SUHFLVHO\�ILYH�SDUDPHWHUV��&RPSDUHWKLV�ZLWK�

system "tar cvf $tarfile @dirs"; # Oops!

+HUH��ZH¦YH�QRZ�SLSHG�D�EXQFK�RI�VWXII�LQWR�D�IOLQWVWRQH�FRPPDQG�DQG�SXW�LW�LQWR�WKHEDFNJURXQG��DQG�RSHQHG�EHWW\�IRU�RXWSXW�

$QG�WKDW¦V�D�ELW�VFDU\�®�HVSHFLDOO\�LI�WKRVH�YDULDEOHV�DUH�IURP�XVHU�LQSXW¢VXFK�DV�IURPD�ZHE�IRUP�RU�VRPHWKLQJ��6R��LI�\RX�FDQ�DUUDQJH�WKLQJV�VR�WKDW�\RX�FDQ�XVH�WKH�PXOWLSOH�DUJXPHQW�YHUVLRQ�RI�system��\RX�SUREDEO\�VKRXOG�XVH�WKDW�ZD\�WR�ODXQFK�\RXU�VXESUR�FHVV���<RX¦OO�KDYH�WR�JLYH�XS�WKH�DELOLW\�WR�KDYH�WKH�VKHOO�GR�WKH�ZRUN�IRU�\RX�WR�VHW�XS,�2�UHGLUHFWLRQ��EDFNJURXQG�SURFHVVHV��DQG�WKH�OLNH��WKRXJK��7KHUH¦V�QR�VXFK�WKLQJ�DVD�IUHH�ODXQFK��

1RWH�WKDW�UHGXQGDQWO\��D�VLQJOH�DUJXPHQW�LQYRFDWLRQ�RI�system�LV�QHDUO\�HTXLYDOHQW�WRWKH�SURSHU�PXOWLSOH�DUJXPHQW�YHUVLRQ�RI�system�

system $command_line;system "/bin/sh", "-c", $command_line;

%XW�QRERG\�ZULWHV�WKH�ODWWHU��XQOHVV�\RX�ZDQW�WKLQJV�SURFHVVHG�E\�D�GLIIHUHQW�VKHOO��OLNHWKH�&�VKHOO�

system "/bin/csh", "-fc", $command_line;

2I�FRXUVH��LI�\RX�VHW�$i = '$i'��WKHQ�LW�ZRXOG�ZRUN�DQ\ZD\��XQWLO�D�PDLQWHQDQFH�SURJUDPPHU�FDPH�DORQJDQG�£IL[HG¤�WKDW�OLQH�RXW�RI�H[LVWHQFH�

� 2U�ZLWK�D�SDUDPHWHU�LQ�WKH�LQGLUHFW�REMHFW�VORW��OLNH�system { 'fred' } 'barney';��ZKLFK�UXQV�WKH�SURJUDPbarney��EXW�OLHV�WR�LW�VR�LW�WKLQNV�WKDW�LW¦V�FDOOHG�'fred'��6HH�WKH�SHUOIXQF�PDQSDJH�

® 8QOHVV�\RX¦UH�XVLQJ�WDLQW�FKHFNLQJ�DQG�KDYH�GRQH�DOO�WKH�ULJKW�WKLQJV�WR�SUHVFDQ�\RXU�GDWD�WR�HQVXUH�WKDW�WKHXVHU�LVQ¦W�WU\LQJ�WR�SXOO�D�IDVW�RQH�RQ�\RX�

The system Function | 235

(YHQ�WKLV�LV�SUHWW\�UDUH��VLQFH�WKH�2QH�7UXH�6KHOO �VHHPV�WR�KDYH�D�ORW�PRUH�IOH[LELOLW\�HVSHFLDOO\�IRU�VFULSWHG�LWHPV�

7KH�UHWXUQ�YDOXH�RI�WKH�V\VWHP�RSHUDWRU�LV�EDVHG�XSRQ�WKH�H[LW�VWDWXV�RI�WKH�FKLOG�FRP�PDQG���,Q�8QL[��DQ�H[LW�YDOXH�RI�0�PHDQV�WKDW�HYHU\WKLQJ�LV�RND\��DQG�D�QRQ]HUR�H[LWYDOXH�XVXDOO\�LQGLFDWHV�WKDW�VRPHWKLQJ�ZHQW�ZURQJ�

unless (system "date") { # Return was zero - meaning success print "We gave you a date, OK!\n";}

1RWH�WKDW�WKLV�LV�EDFNZDUG�IURP�WKH�QRUPDO�£WUXH�LV�JRRG¢IDOVH�LV�EDG¤�VWUDWHJ\�IRUPRVW�RI�WKH�RSHUDWRUV��VR�WR�ZULWH�D�W\SLFDO�£GR�WKLV�RU�GLH¤�VW\OH��ZH¦OO�QHHG�WR�IOLS�IDOVHDQG�WUXH��7KH�HDVLHVW�ZD\�LV�VLPSO\�WR�SUHIL[�WKH�system�RSHUDWRU�ZLWK�D�EDQJ��WKH�ORJLFDO�QRW�RSHUDWRU��

!system "rm -rf files_to_delete" or die "something went wrong";

,Q�WKLV�FDVH��LQFOXGLQJ�$!�LQ�WKH�HUURU�PHVVDJH�ZRXOG�QRW�EH�DSSURSULDWH�EHFDXVH�WKHIDLOXUH�LV�PRVW�OLNHO\�VRPHZKHUH�ZLWKLQ�WKH�H[SHULHQFH�RI�WKH�UP�FRPPDQG��DQG�LW¦V�QRWD�V\VWHP�FDOO¡UHODWHG�HUURU�ZLWKLQ�3HUO�WKDW�$!�FDQ�UHYHDO�

The exec Function(YHU\WKLQJ�ZH¦YH�MXVW�VDLG�DERXW�system�V\QWD[�DQG�VHPDQWLFV�LV�DOVR�WUXH�DERXW�WKHexec�IXQFWLRQ��H[FHSW�IRU�RQH��YHU\�LPSRUWDQW��WKLQJ��7KH�system�IXQFWLRQ�FUHDWHV�D�FKLOGSURFHVV��ZKLFK�WKHQ�VFXUULHV�RII�WR�SHUIRUP�WKH�UHTXHVWHG�DFWLRQ�ZKLOH�3HUO�QDSV��7KHexec�IXQFWLRQ�FDXVHV�WKH�3HUO�SURFHVV�LWVHOI�WR�SHUIRUP�WKH�UHTXHVWHG�DFWLRQ��7KLQN�RI�LWDV�PRUH�OLNH�D�£JRWR¤�WKDQ�D�VXEURXWLQH�FDOO�

)RU�H[DPSOH��VXSSRVH�ZH�ZDQWHG�WR�UXQ�WKH�EHGURFN�FRPPDQG�LQ�WKH��WPS�GLUHFWRU\�SDVVLQJ�LW�DUJXPHQWV�RI��R�DUJV��IROORZHG�E\�ZKDWHYHU�DUJXPHQWV�RXU�RZQ�SURJUDPZDV�LQYRNHG�ZLWK��7KDW¦G�ORRN�OLNH�WKLV�

chdir "/tmp" or die "Cannot chdir /tmp: $!";exec "bedrock", "-o", "args1", @ARGV;

:KHQ�ZH�UHDFK�WKH�exec�RSHUDWLRQ��3HUO�ORFDWHV�EHGURFN��DQG�£MXPSV�LQWR�LW�¤�$W�WKDWSRLQW�� WKHUH� LV� QR� 3HUO� SURFHVV� DQ\PRUH�®� MXVW� WKH� SURFHVV� UXQQLQJ� WKH� EHGURFN

7KDW¦V��ELQ�VK��RU�ZKDWHYHU�\RXU�8QL[�V\VWHP�KDV�LQVWDOOHG�DV�WKH�PRVW�%RXUQH�OLNH�VKHOO��,I�\RX�GRQ¦W�KDYH�D2QH� 7UXH� 6KHOO�� 3HUO� ILJXUHV� RXW� KRZ� WR� LQYRNH� VRPH� RWKHU� FRPPDQG�OLQH� LQWHUSUHWHU�� ZLWK� QRWDEOHFRQVHTXHQFHV¢QRWHG��WKDW�LV��LQ�WKH�GRFXPHQWDWLRQ�IRU�WKDW�3HUO�SRUW�

� ,W¦V�DFWXDOO\�WKH�£ZDLW¤�VWDWXV��ZKLFK�LV�WKH�FKLOG�H[LW�FRGH�WLPHV������SOXV�����LI�FRUH�ZDV�GXPSHG��SOXV�WKHVLJQDO�QXPEHU�WULJJHULQJ�WHUPLQDWLRQ��LI�DQ\��%XW�ZH�UDUHO\�FKHFN�WKH�VSHFLILFV�RI�WKDW��DQG�D�VLPSOH�WUXH�IDOVHYDOXH�VXIILFHV�IRU�QHDUO\�DOO�DSSOLFDWLRQV�

® $FWXDOO\��LW¦V�WKH�VDPH�SURFHVV��KDYLQJ�SHUIRUPHG�WKH�8QL[�exec(2)�V\VWHP�FDOO��RU�HTXLYDOHQW���7KH�SURFHVV,'�UHPDLQV�WKH�VDPH�

236 | Chapter 16:ಗProcess Management

FRPPDQG��:KHQ�EHGURFN�LV�ILQLVKHG��WKHUH¦V�QR�3HUO�WR�FRPH�EDFN�WR��VR�ZH¦G�JHW�DSURPSW�EDFN�LI�ZH�LQYRNHG�WKLV�SURJUDP�IURP�WKH�FRPPDQG�OLQH�

:K\�LV�WKLV�XVHIXO"�:HOO��LI�WKH�SXUSRVH�RI�WKLV�3HUO�SURJUDP�ZHUH�WR�VHW�XS�D�SDUWLFXODUHQYLURQPHQW�WR�UXQ�DQRWKHU�SURJUDP��WKH�SXUSRVH�LV�IXOILOOHG�DV�VRRQ�DV�WKH�RWKHU�SUR�JUDP�KDV�VWDUWHG��,I�ZH¦G�XVHG�system�LQVWHDG�RI�exec��ZH¦G�KDYH�D�3HUO�SURJUDP�MXVWVWDQGLQJ�DURXQG�WDSSLQJ�LWV�WRHV�ZDLWLQJ�IRU�WKH�RWKHU�SURJUDP�WR�FRPSOHWH��MXVW�VR�3HUOFRXOG�ILQDOO\�LPPHGLDWHO\�H[LW�DV�ZHOO��DQG�WKDW¦V�D�ZDVWHG�UHVRXUFH�

+DYLQJ�VDLG�WKDW��LW¦V�DFWXDOO\�TXLWH�UDUH�WR�XVH�exec��H[FHSW�LQ�FRPELQDWLRQ�ZLWK�fork�ZKLFK�\RX¦OO�VHH�ODWHU���,I�\RX�DUH�SX]]OLQJ�RYHU�system�YHUVXV�exec��MXVW�SLFN�system�DQG�QHDUO\�DOO�RI�WKH�WLPH��\RX¦OO�EH�MXVW�ILQH�

%HFDXVH�3HUO�LV�QR�ORQJHU�LQ�FRQWURO�RQFH�WKH�UHTXHVWHG�FRPPDQG�KDV�VWDUWHG��LW�GRHVQ¦WPDNH�DQ\�VHQVH�WR�KDYH�DQ\�3HUO�FRGH�IROORZLQJ�WKH�exec��H[FHSW�IRU�KDQGOLQJ�WKH�HUURUZKHQ�WKH�UHTXHVWHG�FRPPDQG�FDQQRW�EH�VWDUWHG�

exec "date";die "date couldn't run: $!";

,Q�IDFW��LI�\RX�KDYH�ZDUQLQJV�WXUQHG�RQ��DQG�LI�\RX�KDYH�DQ\�FRGH�DIWHU�WKH�exec�RWKHUWKDQ�D�die� �\RX¦OO�JHW�QRWLILHG�

The Environment Variables:KHQ�\RX¦UH�VWDUWLQJ�DQRWKHU�SURFHVV��ZLWK�DQ\�RI�WKH�PHWKRGV�GLVFXVVHG�KHUH���\RXPD\�QHHG�WR�VHW�XS�LWV�HQYLURQPHQW�LQ�RQH�ZD\�RU�DQRWKHU��$V�ZH�PHQWLRQHG�HDUOLHU�\RX�FRXOG�VWDUW�WKH�SURFHVV�ZLWK�D�FHUWDLQ�ZRUNLQJ�GLUHFWRU\��ZKLFK�LW�LQKHULWV�IURP�\RXUSURFHVV��$QRWKHU�FRPPRQ�FRQILJXUDWLRQ�GHWDLO�LV�WKH�HQYLURQPHQW�YDULDEOHV�

2QH�RI�WKH�EHVW�NQRZQ�HQYLURQPHQW�YDULDEOHV�LV�PATH���,I�\RX¦YH�QHYHU�KHDUG�RI�LW��\RXSUREDEO\�KDYHQ¦W�XVHG�D�V\VWHP�WKDW�KDV�HQYLURQPHQW�YDULDEOHV���2Q�8QL[�DQG�VLPLODUV\VWHPV��PATH�LV�D�FRORQ�VHSDUDWHG�OLVW�RI�GLUHFWRULHV�WKDW�PD\�KROG�SURJUDPV��:KHQ\RX�W\SH�D�FRPPDQG�OLNH�UP�IUHG��WKH�V\VWHP�ZLOO�ORRN�IRU�WKH�UP�FRPPDQG�LQ�WKDW�OLVWRI�GLUHFWRULHV��LQ�RUGHU��3HUO��RU�\RXU�V\VWHP��ZLOO�XVH�PATH�ZKHQHYHU�LW�QHHGV�WR�ILQG�WKHSURJUDP�WR�UXQ��,I�WKH�SURJUDP�LQ�WXUQ�UXQV�RWKHU�SURJUDPV��WKRVH�PD\�DOVR�EH�IRXQGDORQJ�WKH�PATH���2I�FRXUVH��LI�\RX�JLYH�D�FRPSOHWH�QDPH�IRU�D�FRPPDQG��VXFK�DV��ELQ�HFKR��WKHUH¦V�QR�QHHG�WR�VHDUFK�PATH��%XW�WKDW¦V�JHQHUDOO\�PXFK�OHVV�FRQYHQLHQW��

,Q�3HUO��WKH�HQYLURQPHQW�YDULDEOHV�DUH�DYDLODEOH�YLD�WKH�VSHFLDO�%ENV�KDVK��HDFK�NH\�LQWKLV�KDVK�UHSUHVHQWV�RQH�HQYLURQPHQW�YDULDEOH��$W�WKH�VWDUW�RI�\RXU�SURJUDP¦V�H[HFXWLRQ�%ENV�KROGV�YDOXHV�LW�KDV�LQKHULWHG�IURP�LWV�SDUHQW�SURFHVV��JHQHUDOO\�WKH�VKHOO���0RGLI\LQJWKLV�KDVK�FKDQJHV�WKH�HQYLURQPHQW�YDULDEOHV��ZKLFK�ZLOO�WKHQ�EH�LQKHULWHG�E\�QHZ�SUR�FHVVHV�DQG�SRVVLEO\�XVHG�E\�3HUO�DV�ZHOO��)RU�H[DPSOH��VXSSRVH�\RX�ZLVKHG�WR�UXQ�WKHV\VWHP¦V�make�XWLOLW\� �ZKLFK� W\SLFDOO\� UXQV�RWKHU�SURJUDPV��� DQG�\RX�ZDQW� WR�XVH�D

2U�H[LW��2U�LI�LW¦V�DW�WKH�HQG�RI�D�EORFN��7KLV�PD\�FKDQJH�LQ�D�QHZ�UHOHDVH�RI�3HUO��WRR�

The Environment Variables | 237

SULYDWH�GLUHFWRU\�DV�WKH�ILUVW�SODFH�WR�ORRN�IRU�FRPPDQGV��LQFOXGLQJ�make�LWVHOI���$QGOHW¦V�VD\�WKDW�\RX�GRQ¦W�ZDQW�WKH�IFS�HQYLURQPHQW�YDULDEOH�WR�EH�VHW�ZKHQ�\RX�UXQ�WKHFRPPDQG�EHFDXVH�WKDW�PLJKW�FDXVH�PDNH�RU�VRPH�VXEFRPPDQG�GR�WKH�ZURQJ�WKLQJ�+HUH�ZH�JR�

$ENV{'PATH'} = "/home/rootbeer/bin:$ENV{'PATH'}";delete $ENV{'IFS'};my $make_result = system "make";

1HZO\�FUHDWHG�SURFHVVHV�ZLOO�JHQHUDOO\�LQKHULW�IURP�WKHLU�SDUHQW�WKH�HQYLURQPHQW�YDU�LDEOHV��WKH�FXUUHQW�ZRUNLQJ�GLUHFWRU\��WKH�VWDQGDUG�LQSXW��RXWSXW��DQG�HUURU�VWUHDPV�DQG�D�IHZ�PRUH�HVRWHULF�LWHPV��6HH�WKH�GRFXPHQWDWLRQ�DERXW�SURJUDPPLQJ�RQ�\RXUV\VWHP�IRU�PRUH�GHWDLOV���%XW�\RXU�SURJUDP�FDQ¦W�FKDQJH�WKH�HQYLURQPHQW�IRU�WKH�VKHOORU�RWKHU�SDUHQW�SURFHVV�WKDW�VWDUWHG�LW��RQ�PRVW�V\VWHPV��

Using Backquotes to Capture Output:LWK�ERWK�system�DQG�exec��WKH�RXWSXW�RI�WKH�ODXQFKHG�FRPPDQG�HQGV�XS�ZKHUHYHU3HUO¦V�VWDQGDUG�RXWSXW�LV�JRLQJ��6RPHWLPHV�LW¦V�LQWHUHVWLQJ�WR�FDSWXUH�WKDW�RXWSXW�DV�DVWULQJ�YDOXH�WR�SHUIRUP�IXUWKHU�SURFHVVLQJ��$QG�WKDW¦V�GRQH�VLPSO\�E\�FUHDWLQJ�D�VWULQJXVLQJ�EDFNTXRWHV�LQVWHDG�RI�VLQJOH�RU�GRXEOH�TXRWHV�

my $now = `date`; # grab the output of dateprint "The time is now $now"; # newline already present

1RUPDOO\��WKLV�GDWH�FRPPDQG�VSLWV�RXW�D�VWULQJ�DSSUR[LPDWHO\����FKDUDFWHUV�ORQJ�WR�LWVVWDQGDUG�RXWSXW��JLYLQJ�WKH�FXUUHQW�GDWH�DQG�WLPH�IROORZHG�E\�D�QHZOLQH��:KHQ�ZH¦YHSODFHG�GDWH�EHWZHHQ�EDFNTXRWHV��3HUO�H[HFXWHV�WKH�GDWH�FRPPDQG��DUUDQJLQJ�WR�FDSWXUHLWV�VWDQGDUG�RXWSXW�DV�D�VWULQJ�YDOXH�DQG��LQ�WKLV�FDVH��DVVLJQ�LW�WR�WKH�$now�YDULDEOH�

7KLV�LV�YHU\�VLPLODU�WR�WKH�8QL[�VKHOO¦V�PHDQLQJ�IRU�EDFNTXRWHV��+RZHYHU��WKH�VKHOO�DOVRSHUIRUPV�WKH�DGGLWLRQDO�MRE�RI�ULSSLQJ�RII�WKH�ILQDO�HQG�RI�OLQH�WR�PDNH�LW�HDVLHU�WR�XVHWKH�YDOXH�DV�SDUW�RI�RWKHU�WKLQJV��3HUO�LV�KRQHVW��LW�JLYHV�WKH�UHDO�RXWSXW��7R�JHW�WKH�VDPHUHVXOW�LQ�3HUO��ZH�FDQ�VLPSO\�DGG�DQ�DGGLWLRQDO�chomp�RSHUDWLRQ�RQ�WKH�UHVXOW�

chomp(my $no_newline_now = `date`);print "A moment ago, it was $no_newline_now, I think.\n";

7KH�YDOXH�EHWZHHQ�EDFNTXRWHV�LV�MXVW�OLNH�WKH�VLQJOH�DUJXPHQW�IRUP�RI�V\VWHP �DQG�LVLQWHUSUHWHG�DV�D�GRXEOH�TXRWHG�VWULQJ��PHDQLQJ�WKDW�EDFNVODVK�HVFDSHV�DQG�YDULDEOHVDUH�H[SDQGHG�DSSURSULDWHO\���)RU�H[DPSOH��WR�IHWFK�WKH�3HUO�GRFXPHQWDWLRQ�RQ�D�OLVW�RI3HUO� IXQFWLRQV��ZH�PLJKW� LQYRNH�WKH�SHUOGRF�FRPPDQG�UHSHDWHGO\��HDFK�WLPH�ZLWK�DGLIIHUHQW�DUJXPHQW�

7KDW�LV��LW¦V�DOVR�DOZD\V�LQWHUSUHWHG�E\�WKH�2QH�7UXH�6KHOO���ELQ�VK��RU�DOWHUQDWLYH��DV�ZLWK�system�

� 6R��LI�\RX�ZDQW�WR�SDVV�D�UHDO�EDFNVODVK�WR�WKH�VKHOO��\RX¦OO�QHHG�WR�XVH�WZR��,I�\RX�QHHG�WR�SDVV�WZR��ZKLFKKDSSHQV�IUHTXHQWO\�RQ�:LQGRZV�V\VWHPV���\RX¦OO�QHHG�WR�XVH�IRXU�

238 | Chapter 16:ಗProcess Management

my @functions = qw{ int rand sleep length hex eof not exit sqrt umask };my %about;

foreach (@functions) { $about{$_} = `perldoc -t -f $_`;}

1RWH�WKDW�$_�ZLOO�EH�D�GLIIHUHQW�YDOXH�IRU�HDFK�LQYRFDWLRQ��OHWWLQJ�XV�JUDE�WKH�RXWSXW�RID�GLIIHUHQW�FRPPDQG�YDU\LQJ�RQO\�LQ�RQH�RI�LWV�SDUDPHWHUV��$OVR�QRWH�WKDW�LI�\RX�KDYHQ¦WVHHQ�VRPH�RI�WKHVH�IXQFWLRQV�\HW��LW�PLJKW�EH�XVHIXO�WR�ORRN�WKHP�XS�LQ�WKH�GRFXPHQ�WDWLRQ�WR�VHH�ZKDW�WKH\�GR�

7KHUH¦V�QR�HDV\�HTXLYDOHQW�RI�VLQJOH�TXRWHV�IRU�EDFNTXRWHV� �YDULDEOH�UHIHUHQFHV�DQGEDFNVODVK�LWHPV�DUH�DOZD\V�H[SDQGHG��$OVR��WKHUH¦V�QR�HDV\�HTXLYDOHQW�RI�WKH�PXOWLSOH�DUJXPHQW�YHUVLRQ�RI�system��ZKHUH�D�VKHOO�LV�QHYHU�LQYROYHG���,I�WKH�FRPPDQG�LQVLGH�WKHEDFNTXRWHV�LV�FRPSOH[�HQRXJK��D�8QL[�%RXUQH�6KHOO��RU�ZKDWHYHU�\RXU�V\VWHP�XVHVLQVWHDG��LV�LQYRNHG�WR�LQWHUSUHW�WKH�FRPPDQG�DXWRPDWLFDOO\�

$W�WKH�ULVN�RI�DFWXDOO\�LQWURGXFLQJ�WKH�EHKDYLRU�E\�GHPRQVWUDWLQJ�KRZ�QRW�WR�GR�LW��ZH¦GDOVR�OLNH�WR�VXJJHVW�WKDW�\RX�DYRLG�XVLQJ�EDFNTXRWHV�LQ�D�SODFH�ZKHUH�WKH�YDOXH�LVQ¦WEHLQJ�FDSWXUHG���)RU�H[DPSOH�

print "Starting the frobnitzigator:\n";`frobnitz -enable`; # please don't do this!print "Done!\n";

7KH�SUREOHP�LV�WKDW�3HUO�KDV�WR�ZRUN�D�ELW�KDUGHU�WR�FDSWXUH�WKH�RXWSXW�RI�WKLV�FRPPDQG�HYHQ�ZKHQ�\RX¦UH�MXVW�WKURZLQJ�LW�DZD\��DQG�WKHQ�\RX�DOVR�ORVH�WKH�RSWLRQ�WR�XVH�PXO�WLSOH�DUJXPHQWV�WR�system�WR�SUHFLVHO\�FRQWURO�WKH�DUJXPHQW�OLVW��6R�IURP�ERWK�D�VHFXULW\VWDQGSRLQW�DQG�DQ�HIILFLHQF\�YLHZSRLQW��MXVW�XVH�system�LQVWHDG��SOHDVH�

6WDQGDUG�HUURU�RI�D�EDFNTXRWHG�FRPPDQG�LV�LQKHULWHG�IURP�3HUO¦V�FXUUHQW�VWDQGDUG�HUURURXWSXW��,I�WKH�FRPPDQG�VSLWV�RXW�HUURU�PHVVDJHV�WR�VWDQGDUG�HUURU��\RX¦OO�SUREDEO\�VHHWKHP�RQ� WKH� WHUPLQDO��ZKLFK�FRXOG�EH�FRQIXVLQJ� WR� WKH�XVHU�ZKR�KDVQ¦W�SHUVRQDOO\LQYRNHG�WKH�IUREQLW]�FRPPDQG��,I�\RX�ZDQW�WR�FDSWXUH�HUURU�PHVVDJHV�ZLWK�VWDQGDUGRXWSXW��\RX�FDQ�XVH�WKH�VKHOO¦V�QRUPDO�£PHUJH�VWDQGDUG�HUURU�WR�WKH�FXUUHQW�VWDQGDUGRXWSXW�¤�ZKLFK�LV�VSHOOHG�2>&1�LQ�WKH�QRUPDO�8QL[�VKHOO�

my $output_with_errors = `frobnitz -enable 2>&1`;

1RWH� WKDW� WKLV�ZLOO�PDNH� WKH� VWDQGDUG�HUURU�RXWSXW� LQWHUPLQJOHG�ZLWK� WKH� VWDQGDUGRXWSXW��PXFK�DV�LW�DSSHDUV�RQ�WKH�WHUPLQDO��DOWKRXJK�SRVVLEO\�LQ�D�VOLJKWO\�GLIIHUHQWVHTXHQFH�EHFDXVH�RI�EXIIHULQJ���,I�\RX�QHHG�WKH�RXWSXW�DQG�WKH�HUURU�RXWSXW�VHSDUDWHG�WKHUH�DUH�PDQ\�KDUGHU�WR�W\SH�VROXWLRQV�®�6LPLODUO\��VWDQGDUG�LQSXW�LV�LQKHULWHG�IURP

)RU�D�FRXSOH�RI�KDUGHU�ZD\V��\RX�FDQ�SODFH�\RXU�VWULQJ�LQVLGH�qx'...'�GHOLPLWHUV��RU�\RX�FDQ�SXW�LW�DOO�LQ�DYDULDEOH� XVLQJ� D� VLQJOH�TXRWHG� VWULQJ�� WKHQ� LQWHUSRODWH� WKDW� VWULQJ� LQWR� D� EDFNTXRWHG� VWULQJ�� VLQFH� WKHLQWHUSRODWLRQ�ZLOO�EH�RQO\�RQH�OHYHO�

� 7KLV�LV�FDOOHG�D�£YRLG¤�FRQWH[W�

® 6XFK�DV�IPC::Open3�LQ�WKH�VWDQGDUG�3HUO�OLEUDU\��RU�ZULWLQJ�\RXU�RZQ�IRUNLQJ�FRGH��DV�\RX�ZLOO�VHH�ODWHU�

Using Backquotes to Capture Output | 239

3HUO¦V�FXUUHQW�VWDQGDUG�LQSXW��0RVW�FRPPDQGV�ZH�W\SLFDOO\�XVH�ZLWK�EDFNTXRWHV�GRQRW�UHDG�VWDQGDUG�LQSXW��VR�WKDW¦V�UDUHO\�D�SUREOHP��+RZHYHU��OHW¦V�VD\�WKH�GDWH�FRP�PDQG�DVNHG�ZKLFK�WLPH�]RQH�\RX�ZDQW��DV�ZH�LPDJLQHG�HDUOLHU���7KDW¦OO�EH�D�SUREOHPEHFDXVH�WKH�SURPSW�IRU�£ZKLFK�WLPH�]RQH¤�ZLOO�EH�VHQW�WR�VWDQGDUG�RXWSXW��ZKLFK�LVEHLQJ�FDSWXUHG�DV�SDUW�RI�WKH�YDOXH��DQG�WKHQ�WKH�GDWH�FRPPDQG�ZLOO�VWDUW�WU\LQJ�WR�UHDGIURP�VWDQGDUG�LQSXW��%XW�VLQFH�WKH�XVHU�KDV�QHYHU�VHHQ�WKH�SURPSW��KH�GRHVQ¦W�NQRZKH�VKRXOG�EH�W\SLQJ�DQ\WKLQJ��3UHWW\�VRRQ��WKH�XVHU�FDOOV�\RX�XS�DQG�WHOOV�\RX�WKDW�\RXUSURJUDP�LV�VWXFN�

6R��VWD\�DZD\�IURP�FRPPDQGV�WKDW�UHDG�VWDQGDUG�LQSXW��,I�\RX¦UH�QRW�VXUH�ZKHWKHUVRPHWKLQJ�UHDGV�IURP�VWDQGDUG�LQSXW��WKHQ�DGG�D�UHGLUHFWLRQ�IURP��GHY�QXOO�IRU�LQSXW�OLNH�WKLV�

my $result = `some_questionable_command arg arg argh </dev/null`;

7KHQ�WKH�FKLOG�VKHOO�ZLOO�UHGLUHFW�LQSXW�IURP��GHY�QXOO��DQG�WKH�JUDQGFKLOG�TXHVWLRQDEOHFRPPDQG�ZLOO�DW�ZRUVW�WU\�WR�UHDG�DQG�LPPHGLDWHO\�JHW�DQ�HQG�RI�ILOH�

Using Backquotes in a List Context,I�WKH�RXWSXW�IURP�D�FRPPDQG�KDV�PXOWLSOH�OLQHV��WKH�VFDODU�XVH�RI�EDFNTXRWHV�UHWXUQVLW�DV�D�VLQJOH�ORQJ�VWULQJ�FRQWDLQLQJ�QHZOLQH�FKDUDFWHUV��+RZHYHU��XVLQJ�WKH�VDPH�EDFN�TXRWHG�VWULQJ�LQ�D�OLVW�FRQWH[W�\LHOGV�D�OLVW�FRQWDLQLQJ�RQH�OLQH�RI�RXWSXW�SHU�HOHPHQW�

)RU�H[DPSOH��WKH�8QL[�ZKR�FRPPDQG�QRUPDOO\�VSLWV�RXW�D�OLQH�RI�WH[W�IRU�HDFK�FXUUHQWORJLQ�RQ�WKH�V\VWHP�DV�IROORZV�

merlyn tty/42 Dec 7 19:41rootbeer console Dec 2 14:15rootbeer tty/12 Dec 6 23:00

7KH�OHIW�FROXPQ�LV�WKH�XVHUQDPH��WKH�PLGGOH�FROXPQ�LV�WKH�WW\�QDPH��WKDW�LV��WKH�QDPHRI�WKH�XVHU¦V�FRQQHFWLRQ�WR�WKH�PDFKLQH���DQG�WKH�UHVW�RI�WKH�OLQH�LV�WKH�GDWH�DQG�WLPHRI�ORJLQ��DQG�SRVVLEO\�UHPRWH�ORJLQ�LQIRUPDWLRQ��EXW�QRW�LQ�WKLV�H[DPSOH���,Q�D�VFDODUFRQWH[W��ZH�JHW�DOO�WKDW�DW�RQFH��ZKLFK�ZH�ZRXOG�WKHQ�QHHG�WR�VSOLW�XS�

my $who_text = `who`;

%XW�LQ�D�OLVW�FRQWH[W��ZH�DXWRPDWLFDOO\�JHW�WKH�GDWD�EURNHQ�XS�E\�OLQHV�

my @who_lines = `who`;

:H¦OO�KDYH�D�QXPEHU�RI�VHSDUDWH�HOHPHQWV� LQ�@who_lines��HDFK�RQH�WHUPLQDWHG�E\�DQHZOLQH��2I�FRXUVH��DGGLQJ�D�chomp�DURXQG�WKH�RXWVLGH�RI�WKDW�ZLOO�ULS�RII�WKRVH�QHZOLQHV�EXW�OHW¦V�JR�LQ�D�GLIIHUHQW�GLUHFWLRQ��,I�ZH�SXW�WKDW�DV�SDUW�RI�WKH�YDOXH�IRU�D�foreach��ZH¦OOLWHUDWH�RYHU�WKH�OLQHV�DXWRPDWLFDOO\��SODFLQJ�HDFK�RQH�LQ�$_�

foreach (`who`) { my($user, $tty, $date) = /(\S+)\s+(\S+)\s+(.*)/; $ttys{$user} .= "$tty at $date\n";}

240 | Chapter 16:ಗProcess Management

7KLV�ORRS�ZLOO�LWHUDWH�WKUHH�WLPHV�IRU�WKH�GDWD�DERYH���<RXU�V\VWHP�ZLOO�SUREDEO\�KDYHPRUH� WKDQ� WKUHH� DFWLYH� ORJLQV� DW� DQ\� JLYHQ� WLPH��� 1RWLFH� WKDW� ZH¦YH� JRW� D� UHJXODUH[SUHVVLRQ�PDWFK��DQG� LQ� WKH�DEVHQFH�RI� WKH�ELQGLQJ�RSHUDWRU� �=~��� WKDW¦V�PDWFKLQJDJDLQVW�$_��ZKLFK�LV�JRRG�EHFDXVH�WKDW¦V�ZKHUH�WKH�GDWD�LV�

$OVR�QRWLFH�WKH�UHJXODU�H[SUHVVLRQ�LV�ORRNLQJ�IRU�D�QRQEODQN�ZRUG��VRPH�ZKLWHVSDFH��DQRQEODQN�ZRUG��VRPH�ZKLWHVSDFH��DQG�WKHQ�WKH�UHVW�RI�WKH�OLQH�XS�WR��EXW�QRW�LQFOXGLQJ�WKH�QHZOLQH��VLQFH�GRW�GRHVQ¦W�PDWFK�QHZOLQH�E\�GHIDXOW�� �7KDW¦V�DOVR�JRRG�EHFDXVHWKDW¦V�ZKDW�WKH�GDWD�ORRNV�OLNH�HDFK�WLPH�LQ�$_��7KDW¦OO�PDNH�$1�EH�"merlyn"��$2�EH�"tty/42"��DQG�$3�EH�"Dec 7 19:41"��DV�D�VXFFHVVIXO�PDWFK�RQ�WKH�ILUVW�WLPH�WKURXJK�WKH�ORRS�

+RZHYHU��WKLV�UHJXODU�H[SUHVVLRQ�PDWFK�LV�LQ�D�OLVW�FRQWH[W��VR�ZH¦OO�JHW�WKH�OLVW�RI�PHP�RULHV� LQVWHDG�RI� WKH� WUXH�IDOVH� £GLG� LW�PDWFK¤� YDOXH�� DV� GHVFULEHG� LQ�&KDSWHU� ��� 6R�$user�HQGV�XS�EHLQJ�"merlyn"��DQG�VR�RQ�

7KH�VHFRQG�VWDWHPHQW�LQVLGH�WKH�ORRS�VLPSO\�VWRUHV�DZD\�WKH�WW\�DQG�GDWH�LQIRUPDWLRQ�DSSHQGLQJ�WR�D��SRVVLEO\�undef��YDOXH�LQ�WKH�KDVK�EHFDXVH�D�XVHU�PLJKW�EH�ORJJHG�LQPRUH�WKDQ�RQFH��DV�XVHU�"rootbeer" ZDV�LQ�RXU�H[DPSOH�

Processes as Filehandles6R�IDU��ZH¦YH�EHHQ�ORRNLQJ�DW�ZD\V�WR�GHDO�ZLWK�V\QFKURQRXV�SURFHVVHV��ZKHUH�3HUO�VWD\VLQ�FKDUJH��ODXQFKHV�D�FRPPDQG���XVXDOO\��ZDLWV�IRU�LW�WR�ILQLVK��WKHQ�SRVVLEO\�JUDEV�LWVRXWSXW��%XW�3HUO�FDQ�DOVR�ODXQFK�D�FKLOG�SURFHVV�WKDW�VWD\V�DOLYH��FRPPXQLFDWLQJ��WR3HUO�RQ�DQ�RQJRLQJ�EDVLV�XQWLO�WKH�WDVN�LV�FRPSOHWH�

7KH�V\QWD[�IRU�ODXQFKLQJ�D�FRQFXUUHQW��SDUDOOHO��FKLOG�SURFHVV�LV�WR�SXW�WKH�FRPPDQGDV�WKH�£ILOHQDPH¤�IRU�DQ�open�FDOO��DQG�HLWKHU�SUHFHGH�RU�IROORZ�WKH�FRPPDQG�ZLWK�D�YHUWLFDO�EDU��ZKLFK�LV�WKH�£SLSH¤�FKDUDFWHU��)RU�WKDW�UHDVRQ��WKLV�LV�RIWHQ�FDOOHG�D�SLSHGRSHQ�

open DATE, "date|" or die "cannot pipe from date: $!";open MAIL, "|mail merlyn" or die "cannot pipe to mail: $!";

,Q�WKH�ILUVW�H[DPSOH��ZLWK�WKH�YHUWLFDO�EDU�RQ�WKH�ULJKW��WKH�FRPPDQG�LV�ODXQFKHG�ZLWKLWV�VWDQGDUG�RXWSXW�FRQQHFWHG�WR�WKH�DATE�ILOHKDQGOH�RSHQHG�IRU�UHDGLQJ��VLPLODU�WR�WKHZD\�WKDW�WKH�FRPPDQG�GDWH�_�\RXUBSURJUDP�ZRXOG�ZRUN�IURP�WKH�VKHOO��,Q�WKH�VHFRQGH[DPSOH��ZLWK�WKH�YHUWLFDO�EDU�RQ�WKH�OHIW��WKH�FRPPDQG¦V�VWDQGDUG�LQSXW�LV�FRQQHFWHGWR�WKH�MAIL�ILOHKDQGOH�RSHQHG�IRU�ZULWLQJ��VLPLODU�WR�ZKDW�KDSSHQV�ZLWK�WKH�FRPPDQG\RXUBSURJUDP�_�PDLO�PHUO\Q��,Q�HLWKHU�FDVH��WKH�FRPPDQG�LV�QRZ�ODXQFKHG�DQG�FRQ�WLQXHV�LQGHSHQGHQWO\�RI�WKH�3HUO�SURFHVV�®�7KH�RSHQ�IDLOV�LI�WKH�FKLOG�SURFHVV�FDQQRW�EH

1RZ�\RX�FDQ�VHH�ZK\�GRW�GRHVQ¦W�PDWFK�QHZOLQH�E\�GHIDXOW��,W�PDNHV�LW�HDV\�WR�ZULWH�SDWWHUQV�OLNH�WKLV�RQH�LQ�ZKLFK�ZH�GRQ¦W�KDYH�WR�ZRUU\�DERXW�D�QHZOLQH�DW�WKH�HQG�RI�WKH�VWULQJ�

� 9LD�SLSHV��RU�ZKDWHYHU�\RXU�RSHUDWLQJ�V\VWHP�SURYLGHV�IRU�VLPSOH�LQWHUSURFHVV�FRPPXQLFDWLRQ�

® ,I�WKH�3HUO�SURFHVV�H[LWV�EHIRUH�WKH�FRPPDQG�LV�FRPSOHWH��D�FRPPDQG�WKDW¦V�EHHQ�UHDGLQJ�ZLOO�VHH�HQG�RI�ILOH�ZKLOH�D�FRPPDQG�WKDW¦V�EHHQ�ZULWLQJ�ZLOO�JHW�D�£EURNHQ�SLSH¤�HUURU�VLJQDO�RQ�WKH�QH[W�ZULWH��E\�GHIDXOW�

Processes as Filehandles | 241

FUHDWHG��,I�WKH�FRPPDQG�LWVHOI�GRHV�QRW�H[LVW�RU�H[LWV�HUURQHRXVO\��WKLV�ZLOO��JHQHUDOO\�QRW�EH�VHHQ�DV�DQ�HUURU�ZKHQ�RSHQLQJ��EXW�DV�DQ�HUURU�ZKHQ�FORVLQJ��:H¦OO�JHW�WR�WKDWLQ�D�PRPHQW�

)RU�DOO�LQWHQWV�DQG�SXUSRVHV��WKH�UHVW�RI�WKH�SURJUDP�GRHVQ¦W�NQRZ��GRHVQ¦W�FDUH��DQGZRXOG�KDYH�WR�ZRUN�SUHWW\�KDUG�WR�ILJXUH�RXW�WKDW�WKLV�LV�D�ILOHKDQGOH�RSHQHG�RQ�D�SURFHVVUDWKHU�WKDQ�RQ�D�ILOH��6R��WR�JHW�GDWD�IURP�D�ILOHKDQGOH�RSHQHG�IRU�UHDGLQJ��ZH¦OO�MXVW�GRWKH�QRUPDO�UHDG�

my $now = <DATE>;

$QG�WR�VHQG�GDWD�WR�WKH�PDLO�SURFHVV��ZDLWLQJ�IRU�WKH�ERG\�RI�D�PHVVDJH�WR�GHOLYHU�WRPHUO\Q�RQ�VWDQGDUG�LQSXW���D�VLPSOH�SULQW�ZLWK�D�ILOHKDQGOH�ZLOO�GR�

print MAIL "The time is now $now"; # presume $now ends in newline

,Q�VKRUW��\RX�FDQ�SUHWHQG�WKDW�WKHVH�ILOHKDQGOHV�DUH�KRRNHG�XS�WR�PDJLFDO�ILOHV��RQH�WKDWFRQWDLQV�WKH�RXWSXW�RI�WKH�GDWH�FRPPDQG��DQG�RQH�WKDW�ZLOO�DXWRPDWLFDOO\�EH�PDLOHGE\�WKH�PDLO�FRPPDQG�

,I�D�SURFHVV�LV�FRQQHFWHG�WR�D�ILOHKDQGOH�WKDW�LV�RSHQ�IRU�UHDGLQJ��DQG�WKHQ�H[LWV��WKHILOHKDQGOH�UHWXUQV�HQG�RI�ILOH��MXVW�OLNH�UHDGLQJ�XS�WR�WKH�HQG�RI�D�QRUPDO�ILOH��:KHQ�\RXFORVH�D�ILOHKDQGOH�RSHQ�IRU�ZULWLQJ�WR�D�SURFHVV��WKH�SURFHVV�ZLOO�VHH�HQG�RI�ILOH��6R��WRILQLVK�VHQGLQJ�WKH�HPDLO��FORVH�WKH�KDQGOH�

close MAIL;die "mail: non-zero exit of $?" if $?;

&ORVLQJ�D�ILOHKDQGOH�DWWDFKHG�WR�D�SURFHVV�ZDLWV�IRU�WKH�SURFHVV�WR�FRPSOHWH�VR�WKDW�3HUOFDQ�JHW� WKH�SURFHVV¦V�H[LW� VWDWXV��7KH�H[LW� VWDWXV� LV� WKHQ�DYDLODEOH� LQ� WKH�$?� YDULDEOH�UHPLQLVFHQW�RI�WKH�VDPH�YDULDEOH�LQ�WKH�%RXUQH�6KHOO��DQG�LV�WKH�VDPH�NLQG�RI�QXPEHUDV�WKH�YDOXH�UHWXUQHG�E\�WKH�system�IXQFWLRQ��]HUR�IRU�VXFFHVV��QRQ]HUR�IRU�IDLOXUH��(DFKQHZ�H[LWHG�SURFHVV�RYHUZULWHV�WKH�SUHYLRXV�YDOXH�WKRXJK��VR�VDYH�LW�TXLFNO\�LI�\RX�ZDQWLW���7KH�$?�YDULDEOH�DOVR�KROGV�WKH�H[LW�VWDWXV�RI�WKH�PRVW�UHFHQW�system�RU�EDFNTXRWHGFRPPDQG��LI�\RX¦UH�FXULRXV��

7KH�SURFHVVHV�DUH�V\QFKURQL]HG�MXVW�OLNH�D�SLSHOLQHG�FRPPDQG��,I�\RX�WU\�WR�UHDG�DQGQR�GDWD�LV�DYDLODEOH��WKH�SURFHVV�LV�VXVSHQGHG��ZLWKRXW�FRQVXPLQJ�DGGLWLRQDO�&38�WLPH�XQWLO�WKH�VHQGLQJ�SURJUDP�KDV�VWDUWHG�VSHDNLQJ�DJDLQ��6LPLODUO\��LI�D�ZULWLQJ�SURFHVV�JHWVDKHDG�RI�WKH�UHDGLQJ�SURFHVV��WKH�ZULWLQJ�SURFHVV�LV�VORZHG�GRZQ�XQWLO�WKH�UHDGHU�VWDUWVWR�FDWFK�XS��7KHUH¦V�D�EXIIHU��XVXDOO\���.%�RU�VR��LQ�EHWZHHQ��VR�WKH\�GRQ¦W�KDYH�WR�VWD\SUHFLVHO\�LQ�ORFN�VWHS�

:K\�XVH�SURFHVVHV�DV�ILOHKDQGOHV"�:HOO��LW¦V�WKH�RQO\�HDV\�ZD\�WR�ZULWH�WR�D�SURFHVVEDVHG�RQ�WKH�UHVXOWV�RI�D�FRPSXWDWLRQ��%XW�LI�\RX¦UH�MXVW�UHDGLQJ��EDFNTXRWHV�DUH�RIWHQPXFK�HDVLHU�WR�PDQDJH��XQOHVV�\RX�ZDQW�WR�KDYH�WKH�UHVXOWV�DV�WKH\�FRPH�LQ�

)RU�H[DPSOH��WKH�8QL[�ILQG�FRPPDQG�ORFDWHV�ILOHV�EDVHG�RQ�WKHLU�DWWULEXWHV��DQG�LW�FDQWDNH�TXLWH�D�ZKLOH�LI�XVHG�RQ�D�IDLUO\�ODUJH�QXPEHU�RI�ILOHV��VXFK�DV�VWDUWLQJ�IURP�WKH

242 | Chapter 16:ಗProcess Management

URRW�GLUHFWRU\���<RX�FDQ�SXW�D�ILQG�FRPPDQG�LQVLGH�EDFNTXRWHV��EXW�LW¦V�RIWHQ�QLFHU�WRVHH�WKH�UHVXOWV�DV�WKH\�DUH�IRXQG�

open F, "find / -atime +90 -size +1000 -print|" or die "fork: $!";while (<F>) { chomp; printf "%s size %dK last accessed on %s\n", $_, (1023 + -s $_)/1024, -A $_;}

7KH�ILQG�FRPPDQG�KHUH�LV�ORRNLQJ�IRU�DOO�WKH�ILOHV�WKDW�ZHUH�QRW�DFFHVVHG�ZLWKLQ�WKHSDVW����GD\V�DQG�WKDW�DUH�ODUJHU�WKDQ������EORFNV���7KHVH�DUH�JRRG�FDQGLGDWHV�WR�PRYHWR�ORQJHU�WHUP�VWRUDJH���:KLOH�ILQG�LV�VHDUFKLQJ�DQG�VHDUFKLQJ��3HUO�FDQ�ZDLW��$V�HDFKILOH�LV�IRXQG��3HUO�UHVSRQGV�WR�WKH�LQFRPLQJ�QDPH�DQG�GLVSOD\V�VRPH�LQIRUPDWLRQ�DERXWWKDW�ILOH�IRU�IXUWKHU�UHVHDUFK��+DG�WKLV�EHHQ�ZULWWHQ�ZLWK�EDFNTXRWHV��ZH¦G�QRW�VHH�DQ\RXWSXW�XQWLO�WKH�ILQG�FRPPDQG�KDG�ILQLVKHG��DQG�LW¦V�FRPIRUWLQJ�WR�VHH�WKDW�LW¦V�DFWXDOO\GRLQJ�WKH�MRE�HYHQ�EHIRUH�LW¦V�GRQH�

Getting Down and Dirty with Fork,Q�DGGLWLRQ�WR�WKH�KLJK�OHYHO�LQWHUIDFHV�DOUHDG\�GHVFULEHG��3HUO�SURYLGHV�QHDUO\�GLUHFWDFFHVV�WR�WKH�ORZ�OHYHO�SURFHVV�PDQDJHPHQW�V\VWHP�FDOOV�RI�8QL[�DQG�VRPH�RWKHU�V\V�WHPV��,I�\RX¦YH�QHYHU�GRQH�WKLV�EHIRUH� �\RX�ZLOO�SUREDEO\�ZDQW�WR�VNLS�WKLV�VHFWLRQ�:KLOH�LW¦V�D�ELW�PXFK�WR�FRYHU�DOO�WKDW�VWXII�LQ�D�FKDSWHU�OLNH�WKLV��OHW¦V�DW�OHDVW�ORRN�DW�DTXLFN�UHLPSOHPHQWDWLRQ�RI�WKLV�

system "date";

/HW¦V�ORRN�DW�KRZ�WKDW�ZRXOG�EH�GRQH�XVLQJ�WKH�ORZ�OHYHO�V\VWHP�FDOOV�

defined(my $pid = fork) or die "Cannot fork: $!";unless ($pid) { # Child process is here exec "date"; die "cannot exec date: $!";}# Parent process is herewaitpid($pid, 0);

+HUH��ZH¦YH�FKHFNHG�WKH�UHWXUQ�YDOXH�IURP�fork��ZKLFK�ZLOO�EH�undef�LI�LW�IDLOHG��8VXDOO\LW�ZLOO�VXFFHHG��FDXVLQJ�WZR�VHSDUDWH�SURFHVVHV�WR�FRQWLQXH�WR�WKH�QH[W�OLQH��EXW�KHUHRQO\�WKH�SDUHQW�SURFHVV�KDV�D�QRQ]HUR�YDOXH�LQ�$pid��VR�RQO\�WKH�FKLOG�SURFHVV�H[HFXWHVWKH�exec�IXQFWLRQ��7KH�SDUHQW�SURFHVV�VNLSV�RYHU�WKDW�DQG�H[HFXWHV�WKH�waitpid�IXQFWLRQ�ZDLWLQJ�IRU�WKDW�SDUWLFXODU�FKLOG�WR�ILQLVK��LI�RWKHUV� ILQLVK� LQ�WKH�PHDQWLPH��WKH\�DUHLJQRUHG���,I�WKDW�DOO�VRXQGV�OLNH�JREEOHG\JRRN��MXVW�UHPHPEHU�WKDW�\RX�FDQ�FRQWLQXH�WRXVH�WKH�system�IXQFWLRQ�ZLWKRXW�EHLQJ�ODXJKHG�DW�E\�\RXU�IULHQGV�

2U�\RX¦UH�QRW�UXQQLQJ�RQ�D�V\VWHP�WKDW�KDV�VXSSRUW�IRU�IRUNLQJ��%XW�WKH�3HUO�GHYHORSHUV�DUH�ZRUNLQJ�KDUG�WRDGG�IRUNLQJ�HYHQ�RQ�V\VWHPV�ZKRVH�XQGHUO\LQJ�SURFHVV�PRGHO�LV�YHU\�GLIIHUHQW�WKDQ�WKH�RQH�LQ�8QL[�

Getting Down and Dirty with Fork | 243

:KHQ�\RX�JR�WR�WKLV�H[WUD�WURXEOH��\RX�DOVR�KDYH�IXOO�FRQWURO�RYHU�DUELWUDU\�SLSH�FUHD�WLRQ��UHDUUDQJLQJ�ILOHKDQGOHV��DQG�QRWLFLQJ�\RXU�SURFHVV�,'�DQG�\RXU�SDUHQW¦V�SURFHVV,'��LI�NQRZDEOH���%XW�DJDLQ��WKDW¦V�DOO�D�ELW�FRPSOLFDWHG�IRU�WKLV�FKDSWHU��VR�VHH�WKH�GHWDLOVLQ�WKH�SHUOLSF�PDQSDJH��DQG�LQ�DQ\�JRRG�ERRN�RQ�DSSOLFDWLRQ�SURJUDPPLQJ�RQ�\RXUV\VWHP��IRU�IXUWKHU�LQIRUPDWLRQ�

Sending and Receiving Signals$�8QL[�VLJQDO�LV�D�WLQ\�PHVVDJH�VHQW�WR�D�SURFHVV��,W�FDQ¦W�VD\�PXFK��LW¦V�OLNH�D�FDU�KRUQKRQNLQJ¢GRHV�WKDW�KRQN�\RX�KHDU�PHDQ�£ORRN�RXW¢WKH�EULGJH�FROODSVHG¤�RU�£WKH�OLJKWKDV�FKDQJHG¢JHW�JRLQJ¤�RU�£VWRS�GULYLQJ¢\RX¦YH�JRW�D�EDE\�RQ�WKH�URRI¤�RU�£KHOOR�ZRUOG¤"�:HOO��IRUWXQDWHO\��8QL[�VLJQDOV�DUH�D�OLWWOH�HDVLHU�WR�LQWHUSUHW�WKDQ�WKDW�EHFDXVHWKHUH¦V�D�GLIIHUHQW�RQH�IRU�HDFK�RI�WKHVH�VLWXDWLRQV� �'LIIHUHQW�VLJQDOV�DUH�LGHQWLILHG�E\�DQDPH��VXFK�DV�SIGINT��PHDQLQJ�£LQWHUUXSW�VLJQDO¤��DQG�D�FRUUHVSRQGLQJ�VPDOO�LQWHJHU�LQ�WKH�UDQJH�IURP���WR�������WR�����RU���WR�����GHSHQGLQJ�RQ�\RXU�8QL[�IODYRU���6LJQDOVDUH�W\SLFDOO\�VHQW�ZKHQ�D�VLJQLILFDQW�HYHQW�KDSSHQV��VXFK�DV�SUHVVLQJ�WKH�LQWHUUXSW�FKDU�DFWHU��W\SLFDOO\�&RQWURO�&��RQ�WKH�WHUPLQDO��ZKLFK�VHQGV�D�SIGINT�WR�DOO�WKH�SURFHVVHVDWWDFKHG�WR�WKDW�WHUPLQDO���6RPH�VLJQDOV�DUH�VHQW�DXWRPDWLFDOO\�E\�WKH�V\VWHP��EXW�WKH\FDQ�DOVR�FRPH�IURP�DQRWKHU�SURFHVV�

<RX�FDQ�VHQG�VLJQDOV�IURP�\RXU�3HUO�SURFHVV�WR�DQRWKHU�SURFHVV��EXW�\RX�KDYH�WR�NQRZWKH�WDUJHW¦V�SURFHVV�,'�QXPEHU��+RZ�WR�ILJXUH�WKDW�RXW�LV�D�ELW�FRPSOLFDWHG�®�EXW�OHW¦VVD\�\RX�NQRZ�WKDW�\RX�ZDQW�WR�VHQG�D�SIGINT�WR�SURFHVV�������7KDW¦V�HDV\�HQRXJK�

kill 2, 4201 or die "Cannot signal 4201 with SIGINT: $!";

,W¦V�QDPHG�£NLOO¤�EHFDXVH�RQH�RI�WKH�SULPDU\�SXUSRVHV�RI�VLJQDOV�LV�WR�VWRS�D�SURFHVVWKDW¦V�JRQH�RQ�ORQJ�HQRXJK��<RX�FDQ�DOVR�XVH�WKH�VWULQJ�'INT'�LQ�SODFH�RI�WKH�2�WKHUHEHFDXVH�VLJQDO�QXPEHU�2�LV�SIGINT��,I�WKH�SURFHVV�QR�ORQJHU�H[LVWV��\RX¦OO�JHW�D�IDOVHUHWXUQ�YDOXH��VR�\RX�FDQ�DOVR�XVH�WKLV�WHFKQLTXH�WR�VHH�ZKHWKHU�D�SURFHVV�LV�VWLOO�DOLYH�$�VSHFLDO�VLJQDO�QXPEHU�RI�0�VD\V�£MXVW�FKHFN�WR�VHH�ZKHWKHU�,�FRXOG�VHQG�D�VLJQDO�LI�,ZDQWHG�WR��EXW�,�GRQ¦W�ZDQW�WR��VR�GRQ¦W�DFWXDOO\�VHQG�DQ\WKLQJ�¤�6R�D�SURFHVV�SUREHPLJKW�ORRN�OLNH�

:HOO��QRW�H[DFWO\�WKHVH�VLWXDWLRQV��EXW�DQDORJRXV�8QL[�OLNH�RQHV��)RU�WKHVH��WKH�VLJQDOV�DUH�SIGHUP��SIGCONT�SIGINT��DQG�WKH�IDNH�SIGZERO��VLJQDO�QXPEHU�]HUR��

� $QG�\RX�WKRXJKW�WKDW�SUHVVLQJ�&RQWURO�&�VWRSSHG�\RXU�SURJUDP��$FWXDOO\��LW�VLPSO\�VHQGV�WKH�SIGINT�VLJQDO�DQG�WKDW�VWRSV�WKH�SURJUDP�E\�GHIDXOW��$V�\RX¦OO�VHH�ODWHU�LQ�WKLV�FKDSWHU��\RX�FDQ�PDNH�D�SURJUDP�WKDW�GRHVVRPHWKLQJ�GLIIHUHQW�ZKHQ�SIGINT�FRPHV�LQ��UDWKHU�WKDQ�VWRSSLQJ�DW�RQFH�

® 8VXDOO\�\RX�KDYH�WKH�SURFHVV�,'�EHFDXVH�LW¦V�D�FKLOG�SURFHVV�\RX�SURGXFHG�ZLWK�fork��RU�\RX�IRXQG�LW�LQ�D�ILOHRU�JRW�LW�IURP�DQ�H[WHUQDO�SURJUDP��8VLQJ�DQ�H[WHUQDO�SURJUDP�FDQ�EH�GLIILFXOW�DQG�SUREOHPDWLF��ZKLFK�LV�ZK\PDQ\�ORQJ�UXQQLQJ�SURJUDPV�VDYH�WKHLU�RZQ�FXUUHQW�SURFHVV�,'�LQWR�D�ILOH��XVXDOO\�GHVFULEHG�LQ�WKH�SURJUDP¦VGRFXPHQWDWLRQ�

6HQGLQJ�D�VLJQDO�ZLOO�DOVR�IDLO�LI�\RX¦UH�QRW�WKH�VXSHUXVHU�DQG�LW¦V�VRPHRQH�HOVH¦V�SURFHVV��,W�ZRXOG�EH�UXGH�WRVHQG�SIGINT�WR�VRPHRQH�HOVH¦V�SURJUDPV��DQ\ZD\�

244 | Chapter 16:ಗProcess Management

unless (kill 0, $pid) { warn "$pid has gone away!";}

3HUKDSV�D�OLWWOH�PRUH�LQWHUHVWLQJ�WKDQ�VHQGLQJ�VLJQDOV�LV�FDWFKLQJ�VLJQDOV��:K\�PLJKW\RX�ZDQW�WR�GR�WKLV"�:HOO��VXSSRVH�\RX�KDYH�D�SURJUDP�WKDW�FUHDWHV�ILOHV�LQ��WPS��DQG\RX�QRUPDOO\�GHOHWH�WKRVH�ILOHV�DW�WKH�HQG�RI�WKH�SURJUDP��,I�VRPHRQH�SUHVVHV�&RQWURO�&�GXULQJ�WKH�H[HFXWLRQ��WKDW�OHDYHV�WUDVK�LQ��WPS��D�YHU\�XQSROLWH�WKLQJ�WR�GR��7R�IL[WKLV��FUHDWH�D�VLJQDO�KDQGOHU�WKDW�WDNHV�FDUH�RI�WKH�FOHDQXS�

my $temp_directory = "/tmp/myprog.$$"; # create files below heremkdir $temp_directory, 0700 or die "Cannot create $temp_directory: $!";

sub clean_up { unlink glob "$temp_directory/*"; rmdir $temp_directory;}

sub my_int_handler { &clean_up; die "interrupted, exiting...\n";}

$SIG{'INT'} = 'my_int_handler';.. # Time passes, the program runs, creates some temporary. # files in the temp directory, maybe someone presses Control-C.# Now it's the end of normal execution&clean_up;

7KH�DVVLJQPHQW�LQWR�WKH�VSHFLDO�%SIG�KDVK�DFWLYDWHV�WKH�KDQGOHU��XQWLO�UHYRNHG���7KHNH\� LV� WKH�QDPH�RI� WKH� VLJQDO� �ZLWKRXW� WKH� FRQVWDQW�6,*�SUHIL[��� DQG� WKH�YDOXH� LV� DVWULQJ �QDPLQJ�WKH�VXEURXWLQH��ZLWKRXW�WKH�DPSHUVDQG��)URP�WKHQ�RQ��LI�D�SIGINT�FRPHVDORQJ��3HUO�VWRSV�ZKDWHYHU�LW¦V�GRLQJ�DQG�MXPSV�LPPHGLDWHO\�WR�WKH�VXEURXWLQH��2XUVXEURXWLQH�FOHDQV�XS�WKH�WHPS�ILOHV�DQG�WKHQ�H[LWV���$QG�LI�QRERG\�SUHVVHV�&RQWURO�&�ZH¦OO�VWLOO�FDOO�&clean_up�DW�WKH�HQG�RI�QRUPDO�H[HFXWLRQ��

,I�WKH�VXEURXWLQH�UHWXUQV�UDWKHU�WKDQ�H[LWV��H[HFXWLRQ�UHVXPHV�ULJKW�ZKHUH�LW�ZDV�LQWHU�UXSWHG��7KLV�FDQ�EH�XVHIXO�LI�WKH�LQWHUUXSW�DFWXDOO\�QHHGV�WR�LQWHUUXSW�VRPHWKLQJ�UDWKHUWKDQ�FDXVH�LW�WR�VWRS��)RU�H[DPSOH��VXSSRVH�SURFHVVLQJ�HDFK�OLQH�RI�D�ILOH�WDNHV�D�IHZVHFRQGV��ZKLFK�LV�SUHWW\�VORZ��DQG�\RX�ZDQW�WR�DERUW�WKH�RYHUDOO�SURFHVVLQJ�ZKHQ�DQLQWHUUXSW�LV�SURFHVVHG��EXW�QRW�LQ�WKH�PLGGOH�RI�SURFHVVLQJ�D�OLQH��-XVW�VHW�D�IODJ�LQ�WKHLQWHUUXSW�SURFHGXUH��DQG�FKHFN�LW�DW�WKH�HQG�RI�HDFK�OLQH¦V�SURFHVVLQJ�

my $int_count;sub my_int_handler { $int_count++ }$SIG{'INT'} = 'my_int_handler';...$int_count = 0;

7KH�YDOXH�FDQ�DOVR�EH�D�VXEURXWLQH�UHIHUHQFH��EXW�ZH¦UH�QRW�GRLQJ�WKRVH�KHUH�

Sending and Receiving Signals | 245

while (<SOMEFILE>) { ... some processing that takes a few seconds ... if ($int_count) { # interrupt was seen! print "[processing interrupted...]\n"; last; }}

1RZ�DV�HDFK�OLQH�LV�SURFHVVHG��WKH�YDOXH�RI�$int_count�ZLOO�EH�0�LI�QR�RQH�KDV�SUHVVHG&RQWURO�&��DQG�VR�WKH�ORRS�ZLOO�FRQWLQXH�WR�WKH�QH[W�LWHP��+RZHYHU��LI�DQ�LQWHUUXSWFRPHV�LQ��WKH�LQWHUUXSW�KDQGOHU�LQFUHPHQWV�WKH�$int_count�IODJ��EUHDNLQJ�RXW�RI�WKH�ORRSZKHQ�FKHFNHG�DW�WKH�HQG�

6R��\RX�FDQ�HLWKHU�VHW�D�IODJ�RU�EUHDN�RXW�RI�WKH�SURJUDP��DQG�WKDW�FRYHUV�PRVW�RI�ZKDW\RX¦OO�QHHG�IURP�FDWFKLQJ�VLJQDOV��7KH�FXUUHQW�LPSOHPHQWDWLRQ�RI�VLJQDO�KDQGOHUV�LV�QRWHQWLUHO\�ZLWKRXW�IDXOWV� �KRZHYHU��VR�NHHS�WKH�VWXII�\RX¦UH�GRLQJ�LQ�WKHUH�WR�DQ�DEVROXWHPLQLPXP��RU�\RXU�SURJUDP�PD\�HQG�XS�EORZLQJ�XS�VRPHWLPH�ZKHQ�\RX�OHDVW�H[SHFW�LW�

Exercises6HH�$SSHQGL[�$�IRU�DQVZHUV�WR�WKH�IROORZLQJ�H[HUFLVHV�

�� >�@�:ULWH�D�SURJUDP�WKDW�FKDQJHV�WR�VRPH�SDUWLFXODU��KDUGFRGHG��GLUHFWRU\��OLNHWKH�V\VWHP¦V�URRW�GLUHFWRU\��WKHQ�H[HFXWHV�WKH�OV��O�FRPPDQG�WR�JHW�D�ORQJ�IRUPDWGLUHFWRU\�OLVWLQJ�LQ�WKDW�GLUHFWRU\���,I�\RX�XVH�D�QRQ�8QL[�V\VWHP��XVH�\RXU�RZQV\VWHP¦V�FRPPDQG�WR�JHW�D�GHWDLOHG�GLUHFWRU\�OLVWLQJ��

�� >��@�0RGLI\�WKH�SUHYLRXV�SURJUDP�WR�VHQG�WKH�RXWSXW�RI�WKH�FRPPDQG�WR�D�ILOHFDOOHG�OV�RXW�LQ�WKH�FXUUHQW�GLUHFWRU\��7KH�HUURU�RXWSXW�VKRXOG�JR�WR�D�ILOH�FDOOHGOV�HUU���<RX�GRQ¦W�QHHG�WR�GR�DQ\WKLQJ�VSHFLDO�DERXW�WKH�IDFW�WKDW�HLWKHU�RI�WKHVHILOHV�PD\�HQG�XS�EHLQJ�HPSW\��

�� >�@�:ULWH�D�SURJUDP�WR�SDUVH�WKH�RXWSXW�RI�WKH�GDWH�FRPPDQG�WR�GHWHUPLQH�WKHFXUUHQW�GD\�RI�WKH�ZHHN��,I�WKH�GD\�RI�WKH�ZHHN�LV�D�ZHHNGD\��SULQW�get to work�RWKHUZLVH�SULQW�go play��7KH�RXWSXW�RI�WKH�GDWH�FRPPDQG�EHJLQV�ZLWK�Mon�RQ�D0RQGD\���,I�\RX�GRQ¦W�KDYH�D�GDWH�FRPPDQG�RQ�\RXU�QRQ�8QL[�V\VWHP��PDNH�DIDNH�OLWWOH�SURJUDP�WKDW�VLPSO\�SULQWV�D�VWULQJ�OLNH�GDWH�PLJKW�SULQW��:H¦OO�HYHQ�JLYH\RX�WKLV�WZR�OLQH�SURJUDP�LI�\RX�SURPLVH�QRW�WR�DVN�XV�KRZ�LW�ZRUNV�

7KLV�LV�RQH�RI�WKH�WRS�LWHPV�RQ�WKH�3HUO�GHYHORSHUV¦�OLVW�RI�WKLQJV�WR�IL[��VR�ZH�H[SHFW�UHOLDEOH�VLJQDO�KDQGOLQJWR�EH�RQH�RI�WKH�ILUVW�LWHPV�RQ�WKH�QHZ�IHDWXUH�OLVW�IRU�3HUO����7KH�SUREOHP�LV�WKDW�D�VLJQDO�PD\�FRPH�LQ�DW�DQ\WLPH��HYHQ�ZKHQ�3HUO�LVQ¦W�UHDG\�IRU�RQH��,I�3HUO�LV��IRU�H[DPSOH��LQ�WKH�PLGGOH�RI�DOORFDWLQJ�VRPH�PHPRU\ZKHQ�D�VLJQDO�FRPHV�LQ��WKH�VLJQDO�KDQGOHU�FDQ�DFFLGHQWDOO\�WU\�WR�DOORFDWH�VRPH�PHPRU\¢DQG�\RXU�SURJUDPLV�GHDG��<RX�FDQ¦W�FRQWURO�ZKHQ�\RXU�3HUO�FRGH�ZLOO�DOORFDWH�PHPRU\��EXW�;68%�FRGH��XVXDOO\�ZULWWHQ�LQ�&�FDQ�VDIHO\�KDQGOH�VLJQDOV��6HH�WKH�3HUO�GRFXPHQWDWLRQ�IRU�PRUH�LQIRUPDWLRQ�DERXW�WKLV�DGYDQFHG�WRSLF�

� $W�OHDVW�ZKHQ�WKH�GD\V�RI�WKH�ZHHN�DUH�EHLQJ�JLYHQ�LQ�(QJOLVK��<RX�PLJKW�KDYH�WR�DGMXVW�DFFRUGLQJO\�LI�WKDW¦VQRW�WKH�FDVH�RQ�\RXU�V\VWHP�

246 | Chapter 16:ಗProcess Management

#!/usr/bin/perlprint localtime( ) . "\n";

Exercises | 247

CHAPTER 17

Some Advanced Perl Techniques

:KDW�ZH¦YH�SXW�LQ�WKLV�ERRN�VR�IDU�LV�WKH�FRUH�RI�3HUO��WKH�SDUW�WKDW�HYHU\�3HUO�XVHU�VKRXOGXQGHUVWDQG��%XW�WKHUH�DUH�D�IHZ�RWKHU�WHFKQLTXHV�WKDW��ZKLOH�QRW�REOLJDWRU\��DUH�VWLOOYDOXDEOH�WRROV�WR�KDYH�LQ�\RXU�WRROER[��:H¦YH�JDWKHUHG�WKH�PRVW�LPSRUWDQW�RI�WKRVH�IRUWKLV�FKDSWHU�

'RQ¦W�EH�PLVOHG�E\�WKH�WLWOH�RI�WKH�FKDSWHU��WKRXJK��WKH�WHFKQLTXHV�KHUH�DUHQ¦W�QHFHV�VDULO\�PRUH�GLIILFXOW�WR�XQGHUVWDQG�WKDQ�ZKDW�ZH�KDYH�HOVHZKHUH��7KH\�DUH�£DGYDQFHG¤PHUHO\�LQ�WKH�VHQVH�WKDW�WKH\�DUHQ¦W�QHFHVVDU\�IRU�EHJLQQHUV��7KH�ILUVW�WLPH�\RX�UHDG�WKLVERRN��\RX�PD\�ZDQW�WR�VNLS��RU�VNLP��WKLV�FKDSWHU��VR�\RX�FDQ�JHW�ULJKW�WR�XVLQJ�3HUO�&RPH�EDFN�WR�LW�D�PRQWK�RU�WZR�ODWHU��ZKHQ�\RX¦UH�UHDG\�WR�JHW�HYHQ�PRUH�RXW�RI�3HUO�&RQVLGHU�WKLV�HQWLUH�FKDSWHU�D�KXJH�IRRWQRWH�

Trapping Errors with eval6RPHWLPHV��\RXU�RUGLQDU\��HYHU\GD\�FRGH�FDQ�FDXVH�D�IDWDO�HUURU�LQ�\RXU�SURJUDP��(DFKRI�WKHVH�W\SLFDO�VWDWHPHQWV�FRXOG�FUDVK�D�SURJUDP�

$barney = $fred / $dino; # divide-by-zero error?

print "match\n" if /^($wilma)/; # illegal regular expression error?

open CAVEMAN, $fred # user-generated error from die? or die "Can't open file '$fred' for input: $!";

<RX�FRXOG�JR�WR�VRPH�WURXEOH�WR�FDWFK�VRPH�RI�WKHVH��EXW�LW¦V�KDUG�WR�JHW�WKHP�DOO���+RZFRXOG�\RX�FKHFN�WKH�VWULQJ�$wilma�IURP�WKDW�H[DPSOH�WR�HQVXUH�WKDW�LW�PDNHV�D�YDOLGUHJXODU�H[SUHVVLRQ"��)RUWXQDWHO\��3HUO�SURYLGHV�D�VLPSOH�ZD\�WR�FDWFK�IDWDO�HUURUV¢ZUDSWKH�FRGH�LQ�DQ�eval�EORFN�

eval { $barney = $fred / $dino } ;

:H�FRQWHPSODWHG�GRLQJ�WKDW�LQ�RQH�RI�WKH�GUDIWV�EXW�JRW�ILUPO\�UHMHFWHG�E\�2¦5HLOO\¦V�HGLWRUV�

249

1RZ��HYHQ�LI�$dino�LV�]HUR��WKDW�OLQH�ZRQ¦W�FUDVK�WKH�SURJUDP��7KH�eval�LV�DFWXDOO\�DQH[SUHVVLRQ��QRW�D�FRQWURO�VWUXFWXUH��OLNH�while�RU�foreach���VR�WKDW�VHPLFRORQ�LV�UHTXLUHGDW�WKH�HQG�RI�WKH�EORFN�

:KHQ�D�QRUPDOO\�IDWDO�HUURU�KDSSHQV�GXULQJ�WKH�H[HFXWLRQ�RI�DQ�eval�EORFN��WKH�EORFNLV� GRQH� UXQQLQJ�� EXW� WKH� SURJUDP�GRHVQ¦W� FUDVK�� 6R� WKDW�PHDQV� WKDW� ULJKW� DIWHU� DQeval�ILQLVKHV��\RX¦OO�ZDQW�WR�NQRZ�ZKHWKHU�LW�H[LWHG�QRUPDOO\�RU�ZKHWKHU�LW�FDXJKW�DIDWDO�HUURU�IRU�\RX��7KH�DQVZHU�LV�LQ�WKH�VSHFLDO�$@�YDULDEOH��,I�WKH�eval�FDXJKW�D�IDWDOHUURU��$@�ZLOO�KROG�ZKDW�ZRXOG�KDYH�EHHQ�WKH�SURJUDP¦V�G\LQJ�ZRUGV��SHUKDSV�VRPH�WKLQJ�OLNH��Illegal division by zero at my_program line 12��,I�WKHUH�ZDV�QR�HUURU�$@�ZLOO�EH�HPSW\��2I�FRXUVH��WKDW�PHDQV�WKDW�$@�LV�D�XVHIXO�%RROHDQ��WUXH�IDOVH��YDOXH�WUXH�LI�WKHUH�ZDV�DQ�HUURU���VR�\RX¦OO�VRPHWLPHV�VHH�FRGH�OLNH�WKLV�DIWHU�DQ�eval�EORFN�

print "An error occurred: $@" if $@;

7KH�eval�EORFN�LV�D�WUXH�EORFN��VR�LW�PDNHV�D�QHZ�VFRSH�IRU�OH[LFDO��my��YDULDEOHV��7KLVSLHFH�RI�D�SURJUDP�VKRZV�DQ�eval�EORFN�KDUG�DW�ZRUN�

foreach my $person (qw/ fred wilma betty barney dino pebbles /) { eval { open FILE, "<$person" or die "Can't open file '$person': $!";

my($total, $count);

while (<FILE>) { $total += $_; $count++; }

my $average = $total/$count; print "Average for file $person was $average\n";

&do_something($person, $average); };

if ($@) { print "An error occurred ($@), continuing\n"; }}

+RZ�PDQ\�SRVVLEOH�IDWDO�HUURUV�DUH�EHLQJ�WUDSSHG�KHUH"�,I�WKHUH�LV�DQ�HUURU�LQ�RSHQLQJWKH�ILOH��WKDW�HUURU�LV�WUDSSHG��&DOFXODWLQJ�WKH�DYHUDJH�PD\�GLYLGH�E\�]HUR�VR�WKDW�HUURULV�WUDSSHG��(YHQ�WKH�FDOO�WR�WKH�P\VWHULRXVO\�QDPHG�&do_something�VXEURXWLQH�ZLOO�EHSURWHFWHG�DJDLQVW�IDWDO�HUURUV�EHFDXVH�DQ�eval�EORFN�WUDSV�DQ\�RWKHUZLVH�IDWDO�HUURUV�WKDWRFFXU�GXULQJ�WKH�WLPH�WKDW�LW¦V�DFWLYH���7KLV�IHDWXUH�LV�KDQG\�LI�\RX�KDYH�WR�FDOO�D�VXE�URXWLQH�ZULWWHQ�E\�VRPHRQH�HOVH��DQG�\RX�GRQ¦W�NQRZ�ZKHWKHU�WKH\¦YH�FRGHG�GHIHQ�VLYHO\�HQRXJK�WR�DYRLG�FUDVKLQJ�\RXU�SURJUDP��

,I�DQ�HUURU�RFFXUV�GXULQJ�WKH�SURFHVVLQJ�RI�RQH�RI�WKH�ILOHV��ZH¦OO�JHW�DQ�HUURU�PHVVDJH�EXW�WKH�SURJUDP�ZLOO�JR�RQ�WR�WKH�QH[W�ILOH�ZLWKRXW�IXUWKHU�FRPSODLQW�

250 | Chapter 17:ಗSome Advanced Perl Techniques

<RX�FDQ�QHVW�eval�EORFNV�LQVLGH�RWKHU�eval�EORFNV��7KH�LQQHU�RQH�WUDSV�HUURUV�ZKLOH�LWUXQV��NHHSLQJ�WKHP�IURP�UHDFKLQJ�WKH�RXWHU�EORFNV���2I�FRXUVH��DIWHU�WKH�LQQHU�evalILQLVKHV��LI�LW�FDXJKW�DQ�HUURU��\RX�PD\�ZLVK�WR�UHSRVW�WKH�HUURU�E\�XVLQJ�die��WKHUHE\OHWWLQJ�WKH�RXWHU�eval�FDWFK�LW���$Q�eval�EORFN�WUDSV�DQ\�HUURUV�WKDW�RFFXU�GXULQJ�LWVH[HFXWLRQ�� LQFOXGLQJ� HUURUV� WKDW�KDSSHQ�GXULQJ� VXEURXWLQH� FDOOV� �DV� \RX� VDZ� LQ� WKHH[DPSOH�HDUOLHU��

:H�PHQWLRQHG�HDUOLHU�WKDW�WKH�eval�LV�DQ�H[SUHVVLRQ��ZKLFK�LV�ZK\�WKH�WUDLOLQJ�VHPLFRORQLV�QHHGHG�DIWHU�WKH�FORVLQJ�FXUO\�EUDFH��%XW�VLQFH�LW¦V�DQ�H[SUHVVLRQ��LW�KDV�D�UHWXUQ�YDOXH�,I�WKHUH¦V�QR�HUURU��LW¦V�OLNH�D�VXEURXWLQH��WKH�UHWXUQ�YDOXH�LV�WKH�ODVW�H[SUHVVLRQ�HYDOXDWHG�RU�LW¦V�UHWXUQHG�HDUO\�ZLWK�DQ�RSWLRQDO�return�NH\ZRUG��+HUH¦V�DQRWKHU�ZD\�WR�GR�WKHPDWK�ZLWKRXW�KDYLQJ�WR�ZRUU\�DERXW�GLYLGH�E\�]HUR�

my $barney = eval { $fred / $dino };

,I�WKH�eval�WUDSV�D�IDWDO�HUURU��WKH�UHWXUQ�YDOXH�LV�HLWKHU�undef�RU�DQ�HPSW\�OLVW��GHSHQGLQJXSRQ�WKH�FRQWH[W��6R�LQ�WKH�SUHYLRXV�H[DPSOH��$barney�LV�HLWKHU�WKH�FRUUHFW�UHVXOW�IURPGLYLGLQJ��RU�LW¦V�undef��ZH�GRQ¦W�UHDOO\�QHHG�WR�FKHFN�$@��DOWKRXJK�LW¦V�SUREDEO\�D�JRRGLGHD�WR�FKHFN�defined($barney)�EHIRUH�ZH�XVH�LW�IXUWKHU��

7KHUH�DUH�IRXU�NLQGV�RI�SUREOHPV�WKDW�eval�FDQ¦W�WUDS��7KH�ILUVW�JURXS�DUH�WKH�YHU\�VHULRXVHUURUV�WKDW�FUDVK�3HUO�LWVHOI��VXFK�DV�UXQQLQJ�RXW�RI�PHPRU\�RU�JHWWLQJ�DQ�XQWUDSSHGVLJQDO��6LQFH�3HUO�LWVHOI�LVQ¦W�UXQQLQJ��WKHUH¦V�QR�ZD\�LW�FDQ�WUDS�WKHVH�HUURUV� �2I�FRXUVH�V\QWD[�HUURUV�LQVLGH�WKH�eval�EORFN�DUH�FDXJKW�DW�FRPSLOH�WLPH¢WKH\¦UH�QHYHU�UHWXUQHGLQ�$@�

7KH�exit�RSHUDWRU�WHUPLQDWHV�WKH�SURJUDP�DW�RQFH��HYHQ�LI�LW¦V�FDOOHG�IURP�D�VXEURXWLQHLQVLGH�DQ�eval�EORFN���7KLV�FRUUHFWO\�LPSOLHV�WKDW�ZKHQ�ZULWLQJ�D�VXEURXWLQH��\RX�VKRXOGXVH�die�UDWKHU�WKDQ�exit�WR�VLJQDO�ZKHQ�VRPHWKLQJ�JRHV�ZURQJ��

7KH�IRXUWK�DQG�ILQDO�NLQG�RI�SUREOHP�WKDW�DQ�eval�EORFN�FDQ¦W�WUDS�DUH�ZDUQLQJV��HLWKHUXVHU�JHQHUDWHG�RQHV��IURP�warn��RU�3HUO¦V�LQWHUQDOO\�JHQHUDWHG�ZDUQLQJV��UHTXHVWHG�ZLWKWKH�-w�FRPPDQG�OLQH�RSWLRQ�RU�WKH�use warnings�SUDJPD���7KHUH¦V�D�VHSDUDWH�PHFKD�QLVP�IURP�eval�IRU�WUDSSLQJ�ZDUQLQJV��VHH�WKH�GLVFXVVLRQ�RI�WKHBBWARNBB�SVHXGRVLJQDOLQ�WKH�3HUO�GRFXPHQWDWLRQ�IRU�WKH�GHWDLOV�

:H�VKRXOG�DOVR�PHQWLRQ�WKDW�WKHUH¦V�DQRWKHU�IRUP�RI�eval�WKDW�FDQ�EH�GDQJHURXV�LI�LW¦VPLVKDQGOHG�� ,Q� IDFW�� \RX¦OO� VRPHWLPHV� UXQ� DFURVV� VRPHRQH� ZKR� ZLOO� VD\� WKDW� \RXVKRXOGQ¦W�XVH�eval�LQ�\RXU�FRGH�IRU�VHFXULW\�UHDVRQV��7KH\¦UH��PRVWO\��ULJKW�WKDW�evalVKRXOG�EH�XVHG�RQO\�ZLWK�JUHDW�FDUH��EXW�WKH\¦UH�WDONLQJ�DERXW�WKH�RWKHU�IRUP�RI�eval�VRPHWLPHV�FDOOHG�£eval�RI�D�VWULQJ�¤�,I�WKH�NH\ZRUG�eval�LV�IROORZHG�GLUHFWO\�E\�D�EORFNRI�FRGH�LQ�FXUO\�EUDFHV��DV�ZH¦UH�GRLQJ�KHUH��WKHUH¦V�QR�QHHG�WR�ZRUU\¢WKDW¦V�WKH�VDIHNLQG�RI�eval�

6RPH�RI�WKHVH�HUURUV�DUH�OLVWHG�ZLWK�DQ�(X)�FRGH�RQ�WKH�SHUOGLDJ�PDQSDJH��LI�\RX¦UH�FXULRXV�

Trapping Errors with eval | 251

Picking Items from a List with grep6RPHWLPHV�\RX¦OO�ZDQW�RQO\�FHUWDLQ�LWHPV�IURP�D�OLVW��0D\EH�\RX¦OO�ZDQW�RQO\�WKH�RGGQXPEHUV�VHOHFWHG�IURP�D�OLVW�RI�QXPEHUV��RU�PD\EH�RQO\�WKH�OLQHV�PHQWLRQLQJ�Fred�IURPD�ILOH�RI�WH[W��$V�\RX¦OO�VHH�LQ�WKLV�VHFWLRQ��SLFNLQJ�VRPH�LWHPV�IURP�D�OLVW�FDQ�EH�GRQHVLPSO\�ZLWK�WKH�grep�RSHUDWRU�

/HW¦V�WU\�WKDW�ILUVW�RQH�DQG�JHW�WKH�RGG�QXPEHUV�IURP�D�ODUJH�OLVW�RI�QXPEHUV��:H�GRQ¦WQHHG�DQ\WKLQJ�QHZ�WR�GR�WKDW�

my @odd_numbers;

foreach (1..1000) { push @odd_numbers, $_ if $_ % 2;}

7KDW�FRGH�XVHV�WKH�PRGXOXV�RSHUDWRU��%���ZKLFK�\RX�VDZ�LQ�&KDSWHU����,I�D�QXPEHU�LVHYHQ��WKDW�QXPEHU�£PRG�WZR¤�JLYHV�]HUR��ZKLFK�LV�IDOVH��%XW�DQ�RGG�QXPEHU�ZLOO�JLYHRQH��VLQFH�WKDW¦V�WUXH��RQO\�WKH�RGG�QXPEHUV�ZLOO�EH�SXVKHG�RQWR�WKH�DUUD\�

1RZ��WKHUH¦V�QRWKLQJ�ZURQJ�ZLWK�WKDW�FRGH�DV�LW�VWDQGV¢H[FHSW�WKDW�LW¦V�D�OLWWOH�ORQJHUWR�ZULWH�DQG�VORZHU�WR�UXQ�WKDQ�LW�PLJKW�EH��VLQFH�3HUO�SURYLGHV�WKH�grep�RSHUDWRU�

my @odd_numbers = grep { $_ % 2 } 1..1000;

7KDW�OLQH�JHWV�D�OLVW�RI�����RGG�QXPEHUV�LQ�RQH�TXLFN�OLQH�RI�FRGH��+RZ�GRHV�LW�ZRUN"7KH�ILUVW�DUJXPHQW�WR�grep�LV�D�EORFN�WKDW�XVHV�$_�DV�D�SODFHKROGHU�IRU�HDFK�LWHP�LQ�WKHOLVW��DQG�UHWXUQV�D�%RROHDQ��WUXH�IDOVH��YDOXH��7KH�UHPDLQLQJ�DUJXPHQWV�DUH�WKH�OLVW�RILWHPV�WR�VHDUFK�WKURXJK��7KH�grep�RSHUDWRU�ZLOO�HYDOXDWH�WKH�H[SUHVVLRQ�RQFH�IRU�HDFKLWHP�LQ�WKH� OLVW��PXFK�DV�RXU�RULJLQDO�foreach� ORRS�GLG��)RU�WKH�RQHV�ZKHUH�WKH� ODVWH[SUHVVLRQ�RI�WKH�EORFN�UHWXUQV�D�WUXH�YDOXH��WKDW�HOHPHQW�LV�LQFOXGHG�LQ�WKH�OLVW�WKDWUHVXOWV�IURP�grep�

:KLOH�WKH�grep�LV�UXQQLQJ��$_�LV�DOLDVHG�WR�RQH�HOHPHQW�RI�WKH�OLVW�DIWHU�DQRWKHU��<RX¦YHVHHQ�WKLV�EHKDYLRU�EHIRUH��LQ�WKH�foreach�ORRS��,W¦V�JHQHUDOO\�D�EDG�LGHD�WR�PRGLI\�$_LQVLGH�WKH�grep�H[SUHVVLRQ�EHFDXVH�WKLV�ZLOO�GDPDJH�WKH�RULJLQDO�GDWD�

7KH�grep�RSHUDWRU�VKDUHV�LWV�QDPH�ZLWK�D�FODVVLF�8QL[�XWLOLW\�WKDW�SLFNV�PDWFKLQJ�OLQHVIURP�D�ILOH�E\�XVLQJ�UHJXODU�H[SUHVVLRQV��:H�FDQ�GR�WKDW�ZLWK�3HUO¦V�grep��ZKLFK�LV�PXFKPRUH�SRZHUIXO��+HUH�ZH�SXOO�RQO\�WKH�OLQHV�PHQWLRQLQJ�fred�IURP�D�ILOH�

my @matching_lines = grep { /\bfred\b/i } <FILE>;

7KHUH¦V�D�VLPSOHU�V\QWD[�IRU�grep��WRR��,I�DOO�\RX�QHHG�IRU�WKH�VHOHFWRU�LV�D�VLPSOH�H[�SUHVVLRQ��UDWKHU�WKDQ�D�ZKROH�EORFN���\RX�FDQ�MXVW�XVH�WKDW�H[SUHVVLRQ��IROORZHG�E\�DFRPPD��LQ�SODFH�RI�WKH�EORFN��+HUH¦V�WKH�VLPSOHU�ZD\�WR�ZULWH�WKDW�ODWHVW�H[DPSOH�

my @matching_lines = grep /\bfred\b/i, <FILE>;

252 | Chapter 17:ಗSome Advanced Perl Techniques

Transforming Items from a List with map$QRWKHU�FRPPRQ�WDVN�LV�WUDQVIRUPLQJ�LWHPV�IURP�D�OLVW��)RU�H[DPSOH��VXSSRVH�ZH�KDYHD�OLVW�RI�QXPEHUV�WKDW�VKRXOG�EH�IRUPDWWHG�DV�£PRQH\�QXPEHUV¤�IRU�RXWSXW��DV�ZLWK�WKHVXEURXWLQH�&big_money��IURP�&KDSWHU������%XW�ZH�GRQ¦W�ZDQW�WR�PRGLI\�WKH�RULJLQDOGDWD��ZH�QHHG�D�PRGLILHG�FRS\�RI�WKH�OLVW�MXVW�IRU�RXWSXW��+HUH¦V�RQH�ZD\�WR�GR�WKDW�

my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);my @formatted_data;

foreach (@data) { push @formatted_data, &big_money($_);}

7KDW�ORRNV�VLPLODU�LQ�IRUP�WR�WKH�H[DPSOH�FRGH�XVHG�DW�WKH�EHJLQQLQJ�RI�WKH�VHFWLRQ�RQgrep��GRHVQ¦W�LW"�6R�LW�PD\�QRW�VXUSULVH�\RX�WKDW�WKH�UHSODFHPHQW�FRGH�UHVHPEOHV�WKHILUVW�grep�H[DPSOH�

my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);

my @formatted_data = map { &big_money($_) } @data;

7KH�map�RSHUDWRU�ORRNV�PXFK�OLNH�grep�EHFDXVH�LW�KDV�WKH�VDPH�NLQG�RI�DUJXPHQWV��DEORFN� WKDW�XVHV�$_��DQG�D� OLVW�RI� LWHPV� WR�SURFHVV��$QG� LW�RSHUDWHV� LQ�D� VLPLODU�ZD\�HYDOXDWLQJ�WKH�EORFN�RQFH�IRU�HDFK�LWHP�LQ�WKH�OLVW��ZLWK�$_�DOLDVHG�WR�D�GLIIHUHQW�RULJLQDOOLVW�HOHPHQW�HDFK�WLPH��%XW�WKH�ODVW�H[SUHVVLRQ�RI�WKH�EORFN�LV�XVHG�GLIIHUHQWO\��LQVWHDGRI�JLYLQJ�D�%RROHDQ�YDOXH��WKH�ILQDO�YDOXH�DFWXDOO\�EHFRPHV�SDUW�RI�WKH�UHVXOWLQJ�OLVW�

$Q\�grep�RU�map�VWDWHPHQW�FRXOG�EH�UHZULWWHQ�DV�D�foreach�ORRS�SXVKLQJ�LWHPV�RQWR�DWHPSRUDU\�DUUD\��%XW�WKH�VKRUWHU�ZD\�LV�W\SLFDOO\�PRUH�HIILFLHQW�DQG�PRUH�FRQYHQLHQW�6LQFH�WKH�UHVXOW�RI�map�RU�grep�LV�D�OLVW��LW�FDQ�EH�SDVVHG�GLUHFWO\�WR�DQRWKHU�IXQFWLRQ�+HUH�ZH�FDQ�SULQW�WKDW�OLVW�RI�IRUPDWWHG�£PRQH\�QXPEHUV¤�DV�DQ�LQGHQWHG�OLVW�XQGHU�DKHDGLQJ�

print "The money numbers are:\n", map { sprintf("%25s\n", $_) } @formatted_data;

2I�FRXUVH��ZH�FRXOG�KDYH�GRQH�WKDW�SURFHVVLQJ�DOO�DW�RQFH��ZLWKRXW�HYHQ�WKH�WHPSRUDU\DUUD\�@formatted_data�

my @data = (4.75, 1.5, 2, 1234, 6.9456, 12345678.9, 29.95);print "The money numbers are:\n", map { sprintf("%25s\n", &big_money($_) ) } @data;

$V�ZH�VDZ�ZLWK�grep��WKHUH¦V�DOVR�D�VLPSOHU�V\QWD[�IRU�map��,I�DOO�\RX�QHHG�IRU�WKH�VHOHFWRULV�D�VLPSOH�H[SUHVVLRQ��UDWKHU�WKDQ�D�ZKROH�EORFN���\RX�FDQ�MXVW�XVH�WKDW�H[SUHVVLRQ�IROORZHG�E\�D�FRPPD��LQ�SODFH�RI�WKH�EORFN�

print "Some powers of two are:\n", map "\t" . ( 2 ** $_ ) . "\n", 0..15;

2QH�RWKHU�LPSRUWDQW�GLIIHUHQFH�LV�WKDW�WKH�H[SUHVVLRQ�XVHG�E\�map�LV�HYDOXDWHG�LQ�D�OLVW�FRQWH[W�DQG�PD\�UHWXUQDQ\�QXPEHU�RI�LWHPV��QRW�QHFHVVDULO\�RQH�HDFK�WLPH�

Transforming Items from a List with map | 253

Unquoted Hash Keys3HUO�RIIHUV�PDQ\�VKRUWFXWV�WKDW�FDQ�KHOS�SURJUDPPHUV��+HUH¦V�D�KDQG\�RQH��\RX�PD\RPLW�WKH�TXRWH�PDUNV�RQ�VRPH�KDVK�NH\V�

2I�FRXUVH��\RX�FDQ¦W�RPLW�WKH�TXRWH�PDUNV�RQ�MXVW�DQ\�NH\��VLQFH�D�KDVK�NH\�PD\�EHDQ\�DUELWUDU\�VWULQJ��%XW�NH\V�DUH�RIWHQ�VLPSOH��,I�WKH�KDVK�NH\�LV�PDGH�XS�RI�QRWKLQJEXW�OHWWHUV��GLJLWV��DQG�XQGHUVFRUHV�ZLWKRXW�VWDUWLQJ�ZLWK�D�GLJLW��\RX�PD\�EH�DEOH�WRRPLW� WKH� TXRWH�PDUNV�� 7KLV� NLQG� RI� VLPSOH� VWULQJ�ZLWKRXW� TXRWH�PDUNV� LV� FDOOHG� DEDUHZRUG��VLQFH�LW�VWDQGV�DORQH�ZLWKRXW�TXRWHV�

2QH�SODFH�\RX�DUH�SHUPLWWHG�WR�XVH�WKLV�VKRUWFXW�LV�WKH�PRVW�FRPPRQ�SODFH�D�KDVK�NH\DSSHDUV�� LQ� WKH� FXUO\� EUDFHV� RI� D� KDVK� HOHPHQW� UHIHUHQFH�� )RU� H[DPSOH�� LQVWHDG� RI$score{"fred"}��\RX�FRXOG�ZULWH�VLPSO\�$score{fred}��6LQFH�PDQ\�KDVK�NH\V�DUH�VLPSOHOLNH�WKLV��QRW�XVLQJ�TXRWHV�LV�D�UHDO�FRQYHQLHQFH��%XW�EHZDUH��LI�WKHUH¦V�DQ\WKLQJ�LQVLGHWKH�FXUO\�EUDFHV�EHVLGHV�D�EDUHZRUG��3HUO�ZLOO�LQWHUSUHW�LW�DV�DQ�H[SUHVVLRQ�

$QRWKHU�SODFH�ZKHUH�KDVK�NH\V�DSSHDU�LV�ZKHQ�DVVLJQLQJ�DQ�HQWLUH�KDVK�XVLQJ�D�OLVW�RINH\�YDOXH�SDLUV��7KH�ELJ�DUURZ��=>��LV�HVSHFLDOO\�XVHIXO�EHWZHHQ�D�NH\�DQG�D�YDOXH�EHFDXVH�DJDLQ��RQO\�LI�WKH�NH\�LV�D�EDUHZRUG��WKH�ELJ�DUURZ�TXRWHV�LW�IRU�\RX�

# Hash containing bowling scoresmy %score = ( barney => 195, fred => 205, dino => 30,);

7KLV�LV�WKH�RQH�LPSRUWDQW�GLIIHUHQFH�EHWZHHQ�WKH�ELJ�DUURZ�DQG�D�FRPPD��D�EDUHZRUGWR�WKH�OHIW�RI�WKH�ELJ�DUURZ�LV�LPSOLFLWO\�TXRWHG���:KDWHYHU�LV�RQ�WKH�ULJKW�LV�OHIW�DORQH�WKRXJK���<RX�GRQ¦W�KDYH�WR�XVH�WKLV�IHDWXUH�RI�WKH�ELJ�DUURZ�RQO\�IRU�KDVKHV��DOWKRXJKWKDW¦V�WKH�PRVW�IUHTXHQW�XVH�

Slices,W�RIWHQ�KDSSHQV�WKDW�ZH�QHHG�WR�ZRUN�ZLWK�RQO\�D�IHZ�HOHPHQWV�IURP�D�JLYHQ�OLVW��)RUH[DPSOH��WKH�%HGURFN�/LEUDU\�NHHSV�LQIRUPDWLRQ�DERXW�WKHLU�SDWURQV�LQ�D�ODUJH�ILOH�

(DFK�OLQH�LQ�WKH�ILOH�GHVFULEHV�RQH�SDWURQ�ZLWK�VL[�FRORQ�VHSDUDWHG�ILHOGV��D�SHUVRQ¦VQDPH��OLEUDU\�FDUG�QXPEHU��KRPH�DGGUHVV��KRPH�SKRQH�QXPEHU��ZRUN�SKRQH�QXPEHU�DQG�QXPEHU�RI�LWHPV�FXUUHQWO\�FKHFNHG�RXW��$�OLWWOH�ELW�RI�WKH�ILOH�ORRNV�VRPHWKLQJ�OLNHWKLV�

fred flintstone:2168:301 Cobblestone Way:555-1212:555-2121:3barney rubble:709918:3128 Granite Blvd:555-3333:555-3438:0

,W�VKRXOG�UHDOO\�EH�D�IXOO�IHDWXUHG�GDWDEDVH�UDWKHU�WKDQ�D�IODW�ILOH��7KH\�SODQ�WR�XSJUDGH�WKHLU�V\VWHP��ULJKWDIWHU�WKH�QH[W�,FH�$JH�

254 | Chapter 17:ಗSome Advanced Perl Techniques

2QH�RI�WKH�OLEUDU\¦V�DSSOLFDWLRQV�QHHGV�RQO\�WKH�FDUG�QXPEHUV�DQG�QXPEHU�RI�LWHPVFKHFNHG�RXW��LW�GRHVQ¦W�XVH�DQ\�RI�WKH�RWKHU�GDWD��,W�FRXOG�XVH�FRGH�VRPHWKLQJ�OLNH�WKLVWR�JHW�RQO\�WKH�ILHOGV�LW�QHHGV�

while (<FILE>) { chomp; my @items = split /:/; my($card_num, $count) = ($items[1], $items[5]); ... # now work with those two variables}

%XW�WKH�DUUD\�@items� LVQ¦W�QHHGHG�IRU�DQ\WKLQJ�HOVH�� LW�VHHPV�OLNH�D�ZDVWH� �0D\EH�LWZRXOG�EH�EHWWHU�WR�DVVLJQ�WKH�UHVXOW�RI�split�WR�D�OLVW�RI�VFDODUV��OLNH�WKLV�

my($name, $card_num, $addr, $home, $work, $count) = split /:/;

:HOO��WKDW�DYRLGV�WKH�XQQHHGHG�DUUD\�@items¢EXW�QRZ�ZH�KDYH�IRXU�VFDODU�YDULDEOHVWKDW�ZH�GLGQ¦W�UHDOO\�QHHG��)RU�WKLV�VLWXDWLRQ��VRPH�SHRSOH�XVHG�WR�PDNH�XS�D�QXPEHURI�GXPP\�YDULDEOH�QDPHV��OLNH�$dummy_1��WKDW�VKRZHG�WKDW�WKH\�UHDOO\�GLGQ¦W�FDUH�DERXWWKDW�HOHPHQW�IURP�WKH�split��%XW�/DUU\�WKRXJKW�WKDW�WKDW�ZDV�WRR�PXFK�WURXEOH��VR�KHDGGHG�D�VSHFLDO�XVH�RI�undef��,I�DQ�LWHP�LQ�D�OLVW�EHLQJ�DVVLJQHG�WR�LV�undef��WKDW�PHDQVVLPSO\�WR�LJQRUH�WKH�FRUUHVSRQGLQJ�HOHPHQW�RI�WKH�VRXUFH�OLVW�

my(undef, $card_num, undef, undef, undef, $count) = split /:/;

,V�WKLV�DQ\�EHWWHU"�:HOO��LW�KDV�WKH�DGYDQWDJH�WKDW�WKHUH�DUHQ¦W�DQ\�XQQHHGHG�YDULDEOHV�%XW� LW� KDV� WKH�GLVDGYDQWDJH� WKDW� \RX�KDYH� WR� FRXQW�undefV� WR� WHOO�ZKLFK� HOHPHQW� LV$count��$QG�WKLV�EHFRPHV�TXLWH�XQZLHOG\�LI�WKHUH�DUH�PRUH�HOHPHQWV� LQ�WKH�OLVW��)RUH[DPSOH��VRPH�SHRSOH�ZKR�ZDQWHG�MXVW�WKH�PWLPH�YDOXH�IURP�stat�ZHUH�ZULWLQJ�FRGHOLNH�WKLV�

my(undef, undef, undef, undef, undef, undef, undef, undef, undef, $mtime) = stat $some_file;

,I�\RX�XVH�WKH�ZURQJ�QXPEHU�RI�undefV��\RX¦OO�JHW�WKH�DWLPH�RU�FWLPH�E\�PLVWDNH��DQGWKDW¦V�D�WRXJK�RQH�WR�GHEXJ��7KHUH¦V�D�EHWWHU�ZD\��3HUO�FDQ�LQGH[�LQWR�D�OLVW�DV�LI�LW�ZHUHDQ�DUUD\��7KLV� LV� D� OLVW� VOLFH��+HUH�� VLQFH� WKH�PWLPH� LV� LWHP�9� LQ� WKH� OLVW� UHWXUQHG�E\stat���ZH�FDQ�JHW�LW�ZLWK�D�VXEVFULSW�

my $mtime = (stat $some_file)[9];

7KRVH�SDUHQWKHVHV�DUH�UHTXLUHG�DURXQG�WKH�OLVW�RI�LWHPV��LQ�WKLV�FDVH��WKH�UHWXUQ�YDOXHIURP�stat���,I�\RX�ZURWH�LW�OLNH�WKLV��LW�ZRXOGQ¦W�ZRUN�

my $mtime = stat($some_file)[9]; # Syntax error!

$�OLVW�VOLFH�KDV�WR�KDYH�D�VXEVFULSW�H[SUHVVLRQ�LQ�VTXDUH�EUDFNHWV�DIWHU�D�OLVW�LQ�SDUHQ�WKHVHV��7KH�SDUHQWKHVHV�KROGLQJ�WKH�DUJXPHQWV�WR�D�IXQFWLRQ�FDOO�GRQ¦W�FRXQW�

,W¦V�QRW�PXFK�RI�D�ZDVWH��UHDOO\��%XW�VWD\�ZLWK�XV��$OO�RI�WKHVH�WHFKQLTXHV�DUH�XVHG�E\�SURJUDPPHUV�ZKR�GRQ¦WXQGHUVWDQG�VOLFHV��VR�LW¦V�ZRUWKZKLOH�WR�VHH�DOO�RI�WKHP�KHUH�

� ,W¦V�WKH�WHQWK�LWHP��EXW�WKH�LQGH[�QXPEHU�LV�9��VLQFH�WKH�ILUVW�LWHP�LV�DW�LQGH[�0��7KLV�LV�WKH�VDPH�NLQG�RI�]HUR�EDVHG�LQGH[LQJ�WKDW�ZH¦YH�XVHG�DOUHDG\�ZLWK�DUUD\V�

Slices | 255

*RLQJ�EDFN�WR�WKH�%HGURFN�/LEUDU\��WKH�OLVW�ZH¦UH�ZRUNLQJ�ZLWK�LV�WKH�UHWXUQ�YDOXH�IURPsplit��:H�FDQ�QRZ�XVH�D�VOLFH�WR�SXOO�RXW�LWHP�1�DQG�LWHP�5�ZLWK�VXEVFULSWV�

my $card_num = (split /:/)[1];my $count = (split /:/)[5];

8VLQJ�D�VFDODU�FRQWH[W�VOLFH�OLNH�WKLV��SXOOLQJ�MXVW�D�VLQJOH�HOHPHQW�IURP�WKH�OLVW��LVQ¦WEDG��EXW�LW�ZRXOG�EH�PRUH�HIILFLHQW�DQG�VLPSOHU�LI�ZH�GLGQ¦W�KDYH�WR�GR�WKH�split�WZLFH�6R�OHW¦V�QRW�GR�LW�WZLFH��OHW¦V�JHW�ERWK�YDOXHV�DW�RQFH�E\�XVLQJ�D�OLVW�VOLFH�LQ�OLVW�FRQWH[W�

my($card_num, $count) = (split /:/)[1, 5];

7KH�LQGLFHV�SXOO�RXW�HOHPHQW�1�DQG�HOHPHQW�5�IURP�WKH�OLVW��UHWXUQLQJ�WKRVH�DV�D�WZR�HOHPHQW� OLVW��:KHQ� WKDW¦V�DVVLJQHG� WR� WKH� WZR�my� YDULDEOHV��ZH�JHW�H[DFWO\�ZKDW�ZHZDQWHG��:H�GR�WKH�slice�MXVW�RQFH��DQG�ZH�VHW�WKH�WZR�YDULDEOHV�ZLWK�D�VLPSOH�QRWDWLRQ�

$�VOLFH�LV�RIWHQ�WKH�VLPSOHVW�ZD\�WR�SXOO�D�IHZ�LWHPV�IURP�D�OLVW��+HUH��ZH�FDQ�SXOO�MXVWWKH�ILUVW�DQG�ODVW�LWHPV�IURP�D�OLVW��XVLQJ�WKH�IDFW�WKDW�LQGH[�!1�PHDQV�WKH�ODVW�HOHPHQW�

my($first, $last) = (sort @names)[0, !1];

7KH�VXEVFULSWV�RI�D�VOLFH�PD\�EH�LQ�DQ\�RUGHU�DQG�PD\�HYHQ�UHSHDW�YDOXHV��7KLV�H[DPSOHSXOOV���LWHPV�IURP�D�OLVW�RI����

my @names = qw{ zero one two three four five six seven eight nine };my @numbers = ( @names )[ 9, 0, 2, 1, 0 ];print "Bedrock @numbers\n"; # says Bedrock nine zero two one zero

Array Slice7KDW�SUHYLRXV�H[DPSOH�FRXOG�EH�PDGH�HYHQ�VLPSOHU��:KHQ�VOLFLQJ�HOHPHQWV�IURP�DQDUUD\��DV�RSSRVHG�WR�D�OLVW���WKH�SDUHQWKHVHV�DUHQ¦W�QHHGHG��6R�ZH�FRXOG�KDYH�GRQH�WKHVOLFH�OLNH�WKLV�

my @numbers = @names[ 9, 0, 2, 1, 0 ];

7KLV�LVQ¦W�PHUHO\�D�PDWWHU�RI�RPLWWLQJ�WKH�SDUHQWKHVHV��WKLV�LV�DFWXDOO\�D�GLIIHUHQW�QRWD�WLRQ�IRU�DFFHVVLQJ�DUUD\�HOHPHQWV��DQ�DUUD\�VOLFH��(DUOLHU��LQ�&KDSWHU�����ZH�VDLG�WKDW�WKHDW�VLJQ�RQ�@names�PHDQW�£DOO�RI�WKH�HOHPHQWV�¤�$FWXDOO\��LQ�D�OLQJXLVWLF�VHQVH��LW¦V�PRUHOLNH�D�SOXUDO�PDUNHU��PXFK�OLNH�WKH�OHWWHU�£V¤�LQ�ZRUGV�OLNH�£FDWV¤�DQG�£GRJV�¤�,Q�3HUO�WKH�GROODU�VLJQ�PHDQV�WKHUH¦V�MXVW�RQH�RI�VRPHWKLQJ��EXW�WKH�DW�VLJQ�PHDQV�WKHUH¦V�D�OLVWRI�LWHPV�

$�VOLFH�LV�DOZD\V�D�OLVW��VR�WKH�DUUD\�VOLFH�QRWDWLRQ�XVHV�DQ�DW�VLJQ�WR�LQGLFDWH�WKDW��:KHQ\RX�VHH�VRPHWKLQJ�OLNH�@names[ ... ]�LQ�D�3HUO�SURJUDP��\RX¦OO�QHHG�WR�GR�MXVW�DV�3HUOGRHV�DQG�ORRN�DW�WKH�DW�VLJQ�DW�WKH�EHJLQQLQJ�DV�ZHOO�DV�WKH�VTXDUH�EUDFNHWV�DW�WKH�HQG�7KH�VTXDUH�EUDFNHWV�PHDQ�WKDW�\RX¦UH�LQGH[LQJ�LQWR�DQ�DUUD\��DQG�WKH�DW�VLJQ�PHDQV

6RUWLQJ�D�OLVW�PHUHO\�WR�ILQG�WKH�H[WUHPH�HOHPHQWV�LVQ¦W�OLNHO\�WR�EH�WKH�PRVW�HIILFLHQW�ZD\��%XW�3HUO¦V�VRUW�LVIDVW�HQRXJK�WKDW�WKLV�LV�JHQHUDOO\�DFFHSWDEOH��DV�ORQJ�DV�WKH�OLVW�GRHVQ¦W�KDYH�PRUH�WKDQ�D�IHZ�KXQGUHG�HOHPHQWV�

256 | Chapter 17:ಗSome Advanced Perl Techniques

WKDW�\RX¦UH�JHWWLQJ�D�ZKROH�OLVW �RI�HOHPHQWV��QRW�MXVW�D�VLQJOH�RQH��ZKLFK�LV�ZKDW�WKHGROODU�VLJQ�ZRXOG�PHDQ���6HH�)LJXUH������

7KH�SXQFWXDWLRQ�PDUN�DW�WKH�IURQW�RI�WKH�YDULDEOH�UHIHUHQFH��HLWKHU�WKH�GROODU�VLJQ�RU�DWVLJQ��GHWHUPLQHV�WKH�FRQWH[W�RI�WKH�VXEVFULSW�H[SUHVVLRQ��,I�WKHUH¦V�D�GROODU�VLJQ�LQ�IURQW�WKH�VXEVFULSW�H[SUHVVLRQ�LV�HYDOXDWHG�LQ�D�VFDODU�FRQWH[W�WR�JHW�DQ�LQGH[��%XW�LI�WKHUH¦VDQ�DW�VLJQ�LQ�IURQW��WKH�VXEVFULSW�H[SUHVVLRQ�LV�HYDOXDWHG�LQ�D�OLVW�FRQWH[W�WR�JHW�D�OLVW�RILQGLFHV�

6R�ZH�VHH�WKDW�@names[ 2, 5 ]�PHDQV�WKH�VDPH�OLVW�DV�($names[2], $names[5])�GRHV��,I\RX�ZDQW�WKDW�OLVW�RI�YDOXHV��\RX�FDQ�VLPSO\�XVH�WKH�DUUD\�VOLFH�QRWDWLRQ��$Q\�SODFH�\RXPLJKW�ZDQW�WR�ZULWH�WKH�OLVW��\RX�FDQ�LQVWHDG�XVH�WKH�VLPSOHU�DUUD\�VOLFH�

%XW�WKH�VOLFH�FDQ�EH�XVHG�LQ�RQH�SODFH�ZKHUH�WKH�OLVW�FDQ¦W¢D�VOLFH�PD\�EH�LQWHUSRODWHGGLUHFWO\�LQWR�D�VWULQJ�

my @names = qw{ zero one two three four five six seven eight nine };print "Bedrock @names[ 9, 0, 2, 1, 0 ]\n";

,I�ZH�ZHUH�WR�LQWHUSRODWH�@names��WKDW�ZRXOG�JLYH�DOO�RI�WKH�LWHPV�IURP�WKH�DUUD\��VHSD�UDWHG�E\�VSDFHV��,I�LQVWHDG�ZH�LQWHUSRODWH�@names[ 9, 0, 2, 1, 0 ]��WKDW�JLYHV�MXVW�WKRVHLWHPV�IURP�WKH�DUUD\��VHSDUDWHG�E\�VSDFHV���/HW¦V�JR�EDFN�WR�WKH�%HGURFN�/LEUDU\�IRU�DPRPHQW��0D\EH�QRZ�RXU�SURJUDP�LV�XSGDWLQJ�0U��6ODWH¦V�DGGUHVV�DQG�SKRQH�QXPEHULQ�WKH�SDWURQ�ILOH�EHFDXVH�KH�MXVW�PRYHG�LQWR�D�ODUJH�QHZ�SODFH�LQ�WKH�+ROO\URFN�+LOOV�,I�ZH¦YH�JRW�D�OLVW�RI�LQIRUPDWLRQ�DERXW�KLP�LQ�@items��ZH�FRXOG�GR�VRPHWKLQJ�OLNH�WKLVWR�XSGDWH�MXVW�WKRVH�WZR�HOHPHQWV�RI�WKH�DUUD\�

$names [ . . . ]

@names [ . . . ]

one element

a list of elements

from an array

)LJXUH�������$UUD\�VOLFHV�YHUVXV�VLQJOH�HOHPHQWV

2I�FRXUVH��ZKHQ�ZH�VD\�£D�ZKROH�OLVW�¤�WKDW�GRHVQ¦W�QHFHVVDULO\�PHDQ�PRUH�HOHPHQWV�WKDQ�RQH¢WKH�OLVW�FRXOGEH�HPSW\��DIWHU�DOO�

� 0RUH�DFFXUDWHO\��WKH�LWHPV�RI�WKH�OLVW�DUH�VHSDUDWHG�E\�WKH�FRQWHQWV�RI�3HUO¦V�$"�YDULDEOH��ZKRVH�GHIDXOW�LV�DVSDFH��7KLV�VKRXOG�QRW�QRUPDOO\�EH�FKDQJHG��:KHQ�LQWHUSRODWLQJ�D�OLVW�RI�YDOXHV��3HUO�LQWHUQDOO\�GRHV�join$", @list��ZKHUH�@list�VWDQGV�LQ�IRU�WKH�OLVW�H[SUHVVLRQ�

Slices | 257

my $new_home_phone = "555-6099";my $new_address = "99380 Red Rock West";@items[2, 3] = ($new_address, $new_home_phone);

2QFH�DJDLQ��WKH�DUUD\�VOLFH�PDNHV�D�PRUH�FRPSDFW�QRWDWLRQ�IRU�D�OLVW�RI�HOHPHQWV��,QWKLV�FDVH��WKDW�ODVW�OLQH�LV�WKH�VDPH�DV�DQ�DVVLJQPHQW�WR�($items[2], $items[3])��EXWPRUH�FRPSDFW�DQG�HIILFLHQW�

Hash Slice,Q�D�ZD\�H[DFWO\�DQDORJRXV�WR�DQ�DUUD\�VOLFH��ZH�FDQ�DOVR�VOLFH�VRPH�HOHPHQWV�IURP�DKDVK�LQ�D�KDVK�VOLFH��5HPHPEHU�ZKHQ�WKUHH�RI�RXU�FKDUDFWHUV�ZHQW�ERZOLQJ��DQG�ZHNHSW�WKHLU�ERZOLQJ�VFRUHV�LQ�WKH�%score�KDVK"�:H�FRXOG�SXOO�WKRVH�VFRUHV�ZLWK�D�OLVW�RIKDVK�HOHPHQWV�RU�ZLWK�D�VOLFH��7KHVH�WZR�WHFKQLTXHV�DUH�HTXLYDOHQW��DOWKRXJK�WKH�VHFRQGLV�PRUH�FRQFLVH�DQG�HIILFLHQW��

my @three_scores = ($score{"barney"}, $score{"fred"}, $score{"dino"});

my @three_scores = @score{ qw/ barney fred dino/ };

$�VOLFH�LV�DOZD\V�D�OLVW��VR�WKH�KDVK�VOLFH�QRWDWLRQ�XVHV�DQ�DW�VLJQ�WR�LQGLFDWH�WKDW� �:KHQ\RX�VHH�VRPHWKLQJ�OLNH�@score{ ... }�LQ�D�3HUO�SURJUDP��\RX¦OO�QHHG�WR�GR�MXVW�DV�3HUOGRHV�DQG�ORRN�DW�WKH�DW�VLJQ�DW�WKH�EHJLQQLQJ�DV�ZHOO�DV�WKH�FXUO\�EUDFHV�DW�WKH�HQG��7KHFXUO\�EUDFHV�PHDQ�WKDW�\RX¦UH�LQGH[LQJ�LQWR�D�KDVK��WKH�DW�VLJQ�PHDQV�WKDW�\RX¦UH�JHWWLQJD�ZKROH� OLVW�RI�HOHPHQWV��QRW� MXVW�D�VLQJOH�RQH��ZKLFK�LV�ZKDW�WKH�GROODU�VLJQ�ZRXOGPHDQ���6HH�)LJXUH������

$score { . . . }

@score { . . . }

one element

a list of elements

from a hash

)LJXUH�������+DVK�VOLFHV�YHUVXV�VLQJOH�HOHPHQWV

,I� LW� VRXQGV� DV� LI�ZH¦UH� UHSHDWLQJ�RXUVHOYHV�KHUH�� LW¦V� EHFDXVH�ZH�ZDQW� WR� HPSKDVL]H� WKDW�KDVK� VOLFHV� DUHDQDORJRXV� WR� DUUD\� VOLFHV�� ,I� LW� VRXQGV� DV� LI�ZH¦UH� QRW� UHSHDWLQJ� RXUVHOYHV� KHUH�� LW¦V� EHFDXVH�ZH�ZDQW� WRHPSKDVL]H�WKDW�KDVK�VOLFHV�DUH�DQDORJRXV�WR�DUUD\�VOLFHV�

258 | Chapter 17:ಗSome Advanced Perl Techniques

$V�\RX�VDZ�ZLWK�WKH�DUUD\�VOLFH��WKH�SXQFWXDWLRQ�PDUN�DW�WKH�IURQW�RI�WKH�YDULDEOH�UHI�HUHQFH� �HLWKHU� WKH� GROODU� VLJQ� RU� DW� VLJQ�� GHWHUPLQHV� WKH� FRQWH[W� RI� WKH� VXEVFULSWH[SUHVVLRQ��,I�WKHUH¦V�D�GROODU�VLJQ�LQ�IURQW��WKH�VXEVFULSW�H[SUHVVLRQ�LV�HYDOXDWHG�LQ�DVFDODU� FRQWH[W� WR� JHW� D� VLQJOH� NH\� � %XW� LI� WKHUH¦V� DQ� DW� VLJQ� LQ� IURQW�� WKH� VXEVFULSWH[SUHVVLRQ�LV�HYDOXDWHG�LQ�D�OLVW�FRQWH[W�WR�JHW�D�OLVW�RI�NH\V�

,W¦V�QRUPDO�DW�WKLV�SRLQW�WR�ZRQGHU�ZK\�WKHUH¦V�QR�SHUFHQW�VLJQ��%��KHUH��ZKHQ�ZH¦UHWDONLQJ�DERXW�D�KDVK��7KDW¦V�WKH�PDUNHU�WKDW�PHDQV�WKHUH¦V�D�ZKROH�KDVK��D�KDVK�VOLFH�OLNH�DQ\�RWKHU�VOLFH��LV�DOZD\V�D�OLVW��QRW�D�KDVK���,Q�3HUO��WKH�GROODU�VLJQ�PHDQV�WKHUH¦VMXVW�RQH�RI�VRPHWKLQJ��EXW�WKH�DW�VLJQ�PHDQV�WKHUH¦V�D�OLVW�RI�LWHPV��DQG�WKH�SHUFHQW�VLJQPHDQV�WKHUH¦V�DQ�HQWLUH�KDVK�

$V�\RX�VDZ�ZLWK�DUUD\�VOLFHV��D�KDVK�VOLFH�PD\�EH�XVHG�LQVWHDG�RI�WKH�FRUUHVSRQGLQJ�OLVWRI�HOHPHQWV�IURP�WKH�KDVK��DQ\ZKHUH�ZLWKLQ�3HUO��6R�ZH�FDQ�VHW�RXU�IULHQGV¦�ERZOLQJVFRUHV�LQ�WKH�KDVK��ZLWKRXW�GLVWXUELQJ�DQ\�RWKHU�HOHPHQWV�LQ�WKH�KDVK��OLNH�WKLV�

my @players = qw/ barney fred dino /;my @bowling_scores = (195, 205, 30);@score{ @players } = @bowling_scores;

7KDW� ODVW� OLQH� GRHV� WKH� VDPH� WKLQJ� DV� LI� ZH� KDG� DVVLJQHG� WR� WKH� WKUHH�HOHPHQW� OLVW($score{"barney"}, $score{"fred"}, $score{"dino"})�

$�KDVK�VOLFH�PD\�EH�LQWHUSRODWHG��WRR��+HUH��ZH�SULQW�RXW�WKH�VFRUHV�IRU�RXU�IDYRULWHERZOHUV�

print "Tonight's players were: @players\n";print "Their scores were: @score{@players}\n";

Exercise6HH�$SSHQGL[�$�IRU�DQ�DQVZHU�WR�WKH�IROORZLQJ�H[HUFLVH�

�� >��@�0DNH�D�SURJUDP�WKDW�UHDGV�D�OLVW�RI�VWULQJV�IURP�D�ILOH��RQH�VWULQJ�SHU�OLQH��DQGWKHQ�OHWV�WKH�XVHU�LQWHUDFWLYHO\�HQWHU�SDWWHUQV�WKDW�PD\�PDWFK�VRPH�RI�WKH�VWULQJV�)RU�HDFK�SDWWHUQ��WKH�SURJUDP�VKRXOG�WHOO�KRZ�PDQ\�VWULQJV�IURP�WKH�ILOH�PDWFKHG�WKHQ�ZKLFK�RQHV�WKRVH�ZHUH��'RQ¦W�UHUHDG�WKH�ILOH�IRU�HDFK�QHZ�SDWWHUQ��NHHS�WKHVWULQJV�LQ�PHPRU\��7KH�ILOHQDPH�PD\�EH�KDUGFRGHG�LQ�WKH�ILOH��,I�D�SDWWHUQ�LV�LQYDOLG�IRU�H[DPSOH��LI�LW�KDV�XQPDWFKHG�SDUHQWKHVHV���WKH�SURJUDP�VKRXOG�VLPSO\�UHSRUWWKDW�HUURU�DQG�OHW�WKH�XVHU�FRQWLQXH�WU\LQJ�SDWWHUQV��:KHQ�WKH�XVHU�HQWHUV�D�EODQNOLQH�LQVWHDG�RI�D�SDWWHUQ��WKH�SURJUDP�VKRXOG�TXLW���,I�\RX�QHHG�D�ILOH�IXOO�RI�LQWHU�HVWLQJ�VWULQJV� WR� WU\�PDWFKLQJ�� WU\� WKH� ILOH� VDPSOHBWH[W� LQ� WKH� ILOHV�\RX¦YH� VXUHO\GRZQORDGHG�E\�QRZ�IURP�WKH�2¦5HLOO\�ZHE�VLWH��VHH�WKH�3UHIDFH��

7KHUH¦V�DQ�H[FHSWLRQ�\RX¦UH�QRW�OLNHO\�WR�UXQ�DFURVV��VLQFH�LW�LVQ¦W�XVHG�PXFK�LQ�PRGHUQ�3HUO�FRGH��6HH�WKHHQWU\�IRU�$;�LQ�WKH�SHUOYDU�PDQSDJH�

� $�KDVK�VOLFH�LV�D�VOLFH��QRW�D�KDVK��LQ�WKH�VDPH�ZD\�WKDW�D�KRXVH�ILUH�LV�D�ILUH��QRW�D�KRXVH���ZKLOH�D�ILUH�KRXVHLV�D�KRXVH��QRW�D�ILUH���0RUH�RU�OHVV�

Exercise | 259

APPENDIX A

Exercise Answers

7KLV�DSSHQGL[�FRQWDLQV�WKH�DQVZHUV�WR�WKH�H[HUFLVHV�WKDW�DSSHDU�WKURXJKRXW�WKH�ERRN�

Answers to Chapter 2 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

#!/usr/bin/perl -w$pi = 3.141592654;$circ = 2 * $pi * 12.5;print "The circumference of a circle of radius 12.5 is $circ.\n";

$V�\RX�VHH��ZH�VWDUWHG�WKLV�SURJUDP�ZLWK�D�W\SLFDO�#!�OLQH��\RXU�SDWK�WR�3HUO�PD\YDU\��:H�DOVR�WXUQHG�RQ�ZDUQLQJV�

7KH�ILUVW�UHDO�OLQH�RI�FRGH�VHWV�WKH�YDOXH�RI�$pi�WR�RXU�YDOXH�RI�˭��7KHUH�DUH�VHYHUDOUHDVRQV�D�JRRG�SURJUDPPHU�ZLOO�SUHIHU�WR�XVH�D�FRQVWDQW �YDOXH�OLNH�WKLV��LW�WDNHVWLPH�WR�W\SH�3.141592654�LQWR�\RXU�SURJUDP�LI�\RX�HYHU�QHHG�LW�PRUH�WKDQ�RQFH��,WPD\�EH�D�PDWKHPDWLFDO�EXJ�LI�\RX�DFFLGHQWDOO\�XVHG�3.141592654�LQ�RQH�SODFH�DQG3.14159� LQ�DQRWKHU��7KHUH¦V�RQO\�RQH� OLQH� WR�FKHFN�RQ� WR�PDNH�VXUH�\RX�GLGQ¦WDFFLGHQWDOO\�W\SH�3.141952654�DQG�VHQG�\RXU�VSDFH�SUREH�WR�WKH�ZURQJ�SODQHW��,W¦VHDVLHU�WR�W\SH�$pi�WKDQ�˭��HVSHFLDOO\�LI�\RX�GRQ¦W�KDYH�8QLFRGH��$QG�LW�ZLOO�EH�HDV\WR�PDLQWDLQ�WKH�SURJUDP�LQ�FDVH�WKH�YDOXH�RI�˭�HYHU�FKDQJHV���1H[W�ZH�FDOFXODWHWKH�FLUFXPIHUHQFH��VWRULQJ�LW�LQWR�$circ��DQG�ZH�SULQW�LW�RXW�LQ�D�QLFH�PHVVDJH��7KHPHVVDJH�HQGV�ZLWK�D�QHZOLQH�FKDUDFWHU�EHFDXVH�HYHU\� OLQH�RI�D�JRRG�SURJUDP¦VRXWSXW� VKRXOG� HQG�ZLWK� D�QHZOLQH��:LWKRXW� LW�� \RX�PLJKW� HQG�XS�ZLWK�RXWSXWORRNLQJ�VRPHWKLQJ�OLNH�WKLV��GHSHQGLQJ�XSRQ�\RXU�VKHOO¦V�SURPSW�

The circumference of a circle of radius 12.5 is78.53981635.bash-2.01$[]

,I�\RX¦G�SUHIHU�D�PRUH�IRUPDO�VRUW�RI�FRQVWDQW��WKH�constant�SUDJPD�PD\�EH�ZKDW�\RX¦UH�ORRNLQJ�IRU�

� ,W�QHDUO\�GLG�FKDQJH�PRUH�WKDQ�D�FHQWXU\�DJR�E\�D�OHJLVODWLYH�DFW�LQ�WKH�VWDWH�RI�,QGLDQD��6HH�+RXVH�%LOO�1R������,QGLDQD�6WDWH�/HJLVODWXUH��������KWWS���ZZZ�FV�XZDWHUORR�FD�aDORSH]�R�PDWK�IDT�QRGH���KWPO�

261

7KH�ER[�UHSUHVHQWV�WKH�LQSXW�FXUVRU��EOLQNLQJ�DW�WKH�HQG�RI�WKH�OLQH��DQG�WKDW¦V�WKHVKHOO¦V� SURPSW� DW� WKH� HQG� RI� WKH�PHVVDJH� � 6LQFH� WKH� FLUFXPIHUHQFH� LVQ¦W� UHDOO\78.53981635.bash-2.01$��WKLV�VKRXOG�SUREDEO\�EH�FRQVWUXHG�DV�D�EXJ��6R�XVH�\n�DWWKH�HQG�RI�HDFK�OLQH�RI�RXWSXW�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

#!/usr/bin/perl -w$pi = 3.141592654;print "What is the radius? ";chomp($radius = <STDIN>);$circ = 2 * $pi * $radius;print "The circumference of a circle of radius $radius is $circ.\n";

7KLV�LV�MXVW�OLNH�WKH�ODVW�RQH��H[FHSW�WKDW�QRZ�ZH�DVN�WKH�XVHU�IRU�WKH�UDGLXV��DQGWKHQ�ZH�XVH�$radius�LQ�HYHU\�SODFH�ZKHUH�ZH�SUHYLRXVO\�XVHG�WKH�KDUGFRGHG�YDOXH12.5��,I�ZH�KDG�ZULWWHQ�WKH�ILUVW�SURJUDP�ZLWK�PRUH�IRUHVLJKW��LQ�IDFW��ZH�ZRXOGKDYH�KDG�D�YDULDEOH�QDPHG�$radius�LQ�WKDW�RQH�DV�ZHOO��1RWH�WKDW�ZH�chompHG�WKHOLQH�RI�LQSXW��,I�ZH�KDGQ¦W��WKH�PDWKHPDWLFDO�IRUPXOD�ZRXOG�VWLOO�KDYH�ZRUNHG�EH�FDXVH�D�VWULQJ�OLNH�12.5\n�LV�FRQYHUWHG�WR�WKH�QXPEHU�12.5�ZLWKRXW�DQ\�SUREOHP�%XW�ZKHQ�ZH�SULQW�RXW�WKH�PHVVDJH��LW�ZRXOG�ORRN�OLNH�WKLV�

The circumference of a circle of radius 12.5 is 78.53981635.

1RWLFH�WKDW�WKH�QHZOLQH�FKDUDFWHU�LV�VWLOO�LQ�$radius��HYHQ�WKRXJK�ZH¦YH�XVHG�WKDWYDULDEOH�DV�D�QXPEHU��6LQFH�ZH�KDG�D�VSDFH�EHWZHHQ�$radius�DQG�WKH�ZRUG�is�LQWKH�print�VWDWHPHQW��WKHUH¦V�D�VSDFH�DW�WKH�EHJLQQLQJ�RI�WKH�VHFRQG�OLQH�RI�RXWSXW�7KH�PRUDO�RI�WKH�VWRU\�LV��chomp�\RXU�LQSXW�XQOHVV�\RX�KDYH�D�UHDVRQ�QRW�WR�GR�WKDW�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

#!/usr/bin/perl -w$pi = 3.141592654;print "What is the radius? ";chomp($radius = <STDIN>);$circ = 2 * $pi * $radius;if ($radius < 0) { $circ = 0;}print "The circumference of a circle of radius $radius is $circ.\n";

+HUH�ZH�DGGHG�WKH�FKHFN�IRU�D�ERJXV�UDGLXV��(YHQ�LI�WKH�JLYHQ�UDGLXV�ZDV�LPSRV�VLEOH��WKH�UHWXUQHG�FLUFXPIHUHQFH�ZRXOG�DW�OHDVW�EH�QRQQHJDWLYH��<RX�FRXOG�KDYHFKDQJHG�WKH�JLYHQ�UDGLXV�WR�EH�]HUR��DQG�WKHQ�FDOFXODWHG�WKH�FLUFXPIHUHQFH��WRR�WKHUH¦V�PRUH�WKDQ�RQH�ZD\�WR�GR�LW��,Q�IDFW��WKDW¦V�WKH�3HUO�PRWWR��7KHUH�,V�0RUH7KDQ�2QH�:D\�7R�'R�,W��$QG�WKDW¦V�ZK\�HDFK�H[HUFLVH�DQVZHU�VWDUWV�ZLWK�£+HUH¦VRQH�ZD\�WR�GR�LW�¤

:H�DVNHG�2¦5HLOO\�WR�VSHQG�WKH�H[WUD�PRQH\�WR�SULQW�WKH�LQSXW�FXUVRU�ZLWK�EOLQNLQJ�LQN��EXW�WKH\�ZRXOGQ¦WGR�LW�IRU�XV�

262 | Appendix A:ಗExercise Answers

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

print "Enter first number: ";chomp($one = <STDIN>);print "Enter second number: ";chomp($two = <STDIN>);$result = $one * $two;print "The result is $result.\n";

1RWLFH�WKDW�ZH¦YH�OHIW�RII�WKH�#!�OLQH�IRU�WKLV�DQVZHU��,Q�IDFW��IURP�KHUH�RQ��ZH¦OODVVXPH�WKDW�\RX�NQRZ�LW¦V�WKHUH��VR�\RX�GRQ¦W�QHHG�WR�UHDG�LW�HDFK�WLPH�

3HUKDSV�WKRVH�DUH�SRRU�FKRLFHV�IRU�YDULDEOH�QDPHV��,Q�D�ODUJH�SURJUDP��D�PDLQWH�QDQFH�SURJUDPPHU�PLJKW�WKLQN�WKDW�$two�VKRXOG�KDYH�WKH�YDOXH�RI�2��,Q�WKLV�VKRUWSURJUDP��LW�SUREDEO\�GRHVQ¦W�PDWWHU��EXW�LQ�D�ODUJH�RQH�ZH�FRXOG�KDYH�FDOOHG�WKHPVRPHWKLQJ�PRUH�GHVFULSWLYH��ZLWK�QDPHV�OLNH�$first_response�

,Q� WKLV�SURJUDP�� LW�ZRXOGQ¦W�PDNH�DQ\�GLIIHUHQFH� LI�ZH� IRUJRW� WR�chomp� WKH� WZRYDULDEOHV�$one�DQG�$two��VLQFH�ZH�QHYHU�XVH�WKHP�DV�VWULQJV�RQFH�WKH\¦YH�EHHQ�VHW�%XW�LI�QH[W�ZHHN�RXU�PDLQWHQDQFH�SURJUDPPHU�HGLWV�WKH�SURJUDP�WR�SULQW�D�PHVVDJHOLNH��The result of multiplying $one by $two is $result.\n��WKRVH�SHVN\�QHZ�OLQHV�ZLOO�FRPH�EDFN�WR�KDXQW�XV��2QFH�DJDLQ��chomp�XQOHVV�\RX�KDYH�D�UHDVRQ�QRWWR�chomp ¢OLNH�LQ�WKH�QH[W�H[HUFLVH�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

print "Enter a string: ";$str = <STDIN>;print "Enter a number of times: ";chomp($num = <STDIN>);$result = $str x $num;print "The result is:\n$result";

7KLV�SURJUDP�LV�DOPRVW�WKH�VDPH�DV�WKH�ODVW�RQH��LQ�D�VHQVH��:H¦UH�£PXOWLSO\LQJ¤�DVWULQJ�E\�D�QXPEHU�RI�WLPHV��6R�ZH¦YH�NHSW�WKH�VWUXFWXUH�RI�WKH�SUHYLRXV�H[HUFLVH�,Q�WKLV�FDVH��WKRXJK��ZH�GLGQ¦W�ZDQW�WR�chomp�WKH�ILUVW�LQSXW�LWHP¢WKH�VWULQJ¢EHFDXVH�WKH�H[HUFLVH�DVNHG�IRU�WKH�VWULQJV�WR�DSSHDU�RQ�VHSDUDWH�OLQHV��VR�LI�WKH�XVHUHQWHUHG�fred�DQG�D�QHZOLQH�IRU�WKH�VWULQJ��DQG�3�IRU�WKH�QXPEHU��ZH¦G�JHW�D�QHZOLQHDIWHU�HDFK�fred�MXVW�DV�ZH�ZDQWHG�

,Q�WKH�print�VWDWHPHQW�DW�WKH�HQG��ZH�SXW�WKH�QHZOLQH�EHIRUH�$result�EHFDXVH�ZHZDQWHG�WR�KDYH�WKH�ILUVW�fred�SULQWHG�RQ�D�OLQH�RI�LWV�RZQ��7KDW�LV��ZH�GLGQ¦W�ZDQWRXWSXW�OLNH�WKLV��ZLWK�RQO\�WZR�RI�WKH�WKUHH�fredV�DOLJQHG�LQ�D�FROXPQ�

The result is: fredfredfred

$W�WKH�VDPH�WLPH��ZH�GLGQ¦W�QHHG�WR�SXW�DQRWKHU�QHZOLQH�DW�WKH�HQG�RI�WKH�printRXWSXW�EHFDXVH�$result�VKRXOG�DOUHDG\�HQG�ZLWK�D�QHZOLQH�

&KRPSLQJ�LV�OLNH�FKHZLQJ¢QRW�DOZD\V�QHHGHG��EXW��PRVW�RI�WKH�WLPH��LW�GRHVQ¦W�KXUW�

Answers to Chapter 2 Exercises | 263

,Q�PRVW�FDVHV��3HUO�ZRQ¦W�PLQG�ZKHUH�\RX�SXW�VSDFHV�LQ�\RXU�SURJUDP��\RX�FDQ�SXWLQ�VSDFHV�RU�OHDYH�WKHP�RXW��%XW�LW¦V�LPSRUWDQW�QRW�WR�DFFLGHQWDOO\�VSHOO�WKH�ZURQJWKLQJ�� ,I� WKH� x� UXQV� XS� DJDLQVW� WKH� SUHFHGLQJ� YDULDEOH� QDPH� $str�� 3HUO�ZLOO� VHH$strx��ZKLFK�ZRQ¦W�ZRUN�

Answers to Chapter 3 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

print "Enter some lines, then press Ctrl-D:\n"; # or maybe Ctrl-Z@lines = <STDIN>;@reverse_lines = reverse @lines;print @reverse_lines;

�RU��HYHQ�PRUH�VLPSO\�

print "Enter some lines, then press Ctrl-D:\n";print reverse <STDIN>;

0RVW�3HUO�SURJUDPPHUV�ZRXOG�SUHIHU�WKH�VHFRQG�RQH��DV�ORQJ�DV�WKH\�GRQ¦W�QHHGWR�NHHS�WKH�OLVW�RI�OLQHV�DURXQG�IRU�ODWHU�XVH�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

@names = qw/ fred betty barney dino wilma pebbles bamm-bamm /;print "Enter some numbers from 1 to 7, one per line, then press Ctrl-D:\n";chomp(@numbers = <STDIN>);foreach (@numbers) { print "$names[ $_ ! 1 ]\n";}

:H�KDYH�WR�VXEWUDFW�RQH�IURP�WKH�LQGH[�QXPEHU�VR�WKDW�WKH�XVHU�FDQ�FRXQW�IURP��WR���HYHQ�WKRXJK�WKH�DUUD\�LV�LQGH[HG�IURP���WR����$QRWKHU�ZD\�WR�DFFRPSOLVK�WKLVZRXOG�EH�WR�KDYH�D�GXPP\�LWHP�LQ�WKH�@names�DUUD\��OLNH�WKLV�

@names = qw/ dummy_item fred betty barney dino wilma pebbles bamm-bamm /;

*LYH�\RXUVHOI�H[WUD�FUHGLW� LI�\RX�FKHFNHG�WR�PDNH�VXUH�WKDW�WKH�XVHU¦V�FKRLFH�RILQGH[�ZDV�LQ�IDFW�LQ�WKH�UDQJH���WR���

�� +HUH¦V�RQH�ZD\�WR�GR�LW�LI�\RX�ZDQW�WKH�RXWSXW�DOO�RQ�RQH�OLQH�

chomp(@lines = <STDIN>);@sorted = sort @lines;print "@sorted\n";

�RU��WR�JHW�WKH�RXWSXW�RQ�VHSDUDWH�OLQHV�

print sort <STDIN>;

264 | Appendix A:ಗExercise Answers

Answers to Chapter 4 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

sub total { my $sum; # private variable foreach (@_) { $sum += $_; } $sum;}

7KLV�VXEURXWLQH�XVHV�$sum�WR�NHHS�D�UXQQLQJ�WRWDO��$W�WKH�VWDUW�RI�WKH�VXEURXWLQH�$sum�LV�undef��VLQFH�LW¦V�D�QHZ�YDULDEOH��7KHQ��WKH�foreach�ORRS�VWHSV�WKURXJK�WKHSDUDPHWHU�OLVW��IURP�@_���XVLQJ�$_�DV�WKH�FRQWURO�YDULDEOH���1RWH��RQFH�DJDLQ��WKHUH¦VQR�DXWRPDWLF�FRQQHFWLRQ�EHWZHHQ�@_��WKH�SDUDPHWHU�DUUD\��DQG�$_��WKH�GHIDXOW�YDU�LDEOH�IRU�WKH�foreach�ORRS��

7KH�ILUVW�WLPH�WKURXJK�WKH�foreach�ORRS��WKH�ILUVW�QXPEHU��LQ�$_��LV�DGGHG�WR�$sum�2I�FRXUVH��$sum�LV�undef��VLQFH�QRWKLQJ�KDV�EHHQ�VWRUHG�LQ�WKHUH��%XW�VLQFH�ZH¦UHXVLQJ�LW�DV�D�QXPEHU��ZKLFK�3HUO�VHHV�EHFDXVH�RI�WKH�QXPHULF�RSHUDWRU�+=��3HUO�DFWVDV�LI�LW¦V�DOUHDG\�LQLWLDOL]HG�WR�0��3HUO�WKXV�DGGV�WKH�ILUVW�SDUDPHWHU�WR�0��DQG�SXWV�WKHWRWDO�EDFN�LQWR�$sum�

1H[W�WLPH�WKURXJK�WKH�ORRS��WKH�QH[W�SDUDPHWHU�LV�DGGHG�WR�$sum��ZKLFK�LV�QR�ORQJHUundef��7KH�VXP�LV�SODFHG�EDFN�LQWR�$sum��DQG�RQ�WKURXJK�WKH�UHVW�RI�WKH�SDUDPHWHUV�)LQDOO\��WKH�ODVW�OLQH�UHWXUQV�$sum�WR�WKH�FDOOHU�

7KHUH¦V� D� SRWHQWLDO� EXJ� LQ� WKLV� VXEURXWLQH�� GHSHQGLQJ� XSRQ� KRZ� \RX� WKLQN� RIWKLQJV��6XSSRVH�WKDW�WKLV�VXEURXWLQH�ZDV�FDOOHG�ZLWK�DQ�HPSW\�SDUDPHWHU�OLVW��DVZH�FRQVLGHUHG�ZLWK�WKH�UHZULWWHQ�VXEURXWLQH�&max�LQ�WKH�FKDSWHU�WH[W���,Q�WKDW�FDVH�$sum�ZRXOG�EH�undef��DQG�WKDW�ZRXOG�EH�WKH�UHWXUQ�YDOXH��%XW�LQ�WKLV�VXEURXWLQH��LWZRXOG�SUREDEO\�EH�£PRUH�FRUUHFW¤�WR�UHWXUQ�0�DV�WKH�VXP�RI�WKH�HPSW\�OLVW��UDWKHUWKDQ�undef���2I�FRXUVH��LI�\RX�ZLVK�WR�GLVWLQJXLVK�WKH�VXP�RI�DQ�HPSW\�OLVW�IURP�WKHVXP�RI��VD\��(3, !5, 2)��UHWXUQLQJ�undef�ZRXOG�EH�WKH�ULJKW�WKLQJ�WR�GR��

,I�\RX�GRQ¦W�ZDQW�D�SRVVLEO\�XQGHILQHG�UHWXUQ�YDOXH��WKRXJK��LW¦V�HDV\�WR�UHPHG\�6LPSO\�LQLWLDOL]H�$sum�WR�]HUR�UDWKHU�WKDQ�XVH�WKH�GHIDXOW�RI�undef�

my $sum = 0;

1RZ�WKH�VXEURXWLQH�ZLOO�DOZD\V�UHWXUQ�D�QXPEHU��HYHQ�LI�WKH�SDUDPHWHU�OLVW�ZHUHHPSW\�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

# Remember to include &total from previous exercise!print "The numbers from 1 to 1000 add up to ", total(1..1000), ".\n";

Answers to Chapter 4 Exercises | 265

1RWH�WKDW�ZH�FDQ¦W�FDOO�WKH�VXEURXWLQH�IURP�LQVLGH�WKH�GRXEOH�TXRWHG�VWULQJ� �VRWKH�VXEURXWLQH�FDOO�LV�DQRWKHU�VHSDUDWH�LWHP�EHLQJ�SDVVHG�WR�print��7KH�WRWDO�VKRXOGEH�500500��D�QLFH�URXQG�QXPEHU��$QG�LW�VKRXOGQ¦W�WDNH�DQ\�QRWLFHDEOH�WLPH�DW�DOOWR�UXQ�WKLV�SURJUDP��SDVVLQJ�D�SDUDPHWHU�OLVW�RI������YDOXHV�LV�DQ�HYHU\GD\�WDVN�IRU3HUO�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

sub average { if (@_ == 0) { return } my $count = @_; my $sum = total(@_); # from earlier exercise $sum/$count;}

sub above_average { my $average = average(@_); my @list; foreach my $element (@_) { if ($element > $average) { push @list, $element; } } @list;}

,Q�average��ZH�UHWXUQ�ZLWKRXW�JLYLQJ�DQ�H[SOLFLW�UHWXUQ�YDOXH�LI�WKH�SDUDPHWHU�OLVWLV�HPSW\��7KDW�JLYHV�WKH�FDOOHU�undef��WR�UHSRUW�WKDW�QR�DYHUDJH�FRPHV�IURP�DQ�HPSW\OLVW��,I�WKH�OLVW�ZDVQ¦W�HPSW\��XVLQJ�&total�PDNHV�LW�VLPSOH�WR�FDOFXODWH�WKH�DYHUDJH�:H�GLGQ¦W�HYHQ�QHHG�WR�XVH�WHPSRUDU\�YDULDEOHV�IRU�$sum�DQG�$count��EXW�GRLQJ�VRPDNHV�WKH�FRGH�HDVLHU�WR�UHDG�

7KH�VHFRQG�VXEURXWLQH��above_average��VLPSO\�EXLOGV�XS�DQG�UHWXUQV�D�OLVW�RI�WKHGHVLUHG�LWHPV���:K\�LV�WKH�FRQWURO�YDULDEOH�QDPHG�$element��LQVWHDG�RI�XVLQJ�3HUO¦VIDYRULWH�GHIDXOW��$_"��1RWH�WKDW�WKLV�VHFRQG�VXEURXWLQH�XVHV�D�GLIIHUHQW�WHFKQLTXHIRU�GHDOLQJ�ZLWK�DQ�HPSW\�SDUDPHWHU�OLVW�

�� 7R�UHPHPEHU�WKH�ODVW�SHUVRQ�WKDW�greet�VSRNH�WR��XVH�D�state�YDULDEOH��,W�VWDUWV�RXWDV�undef��ZKLFK�LV�KRZ�ZH�ILJXUH�RXW�Fred�LV�WKH�ILUVW�SHUVRQ�LW�JUHHWV��$W�WKH�HQG�RIWKH�VXEURXWLQH��ZH�VWRUH�WKH�FXUUHQW�$name�LQ�$last_name��VR�ZH�UHPHPEHU�ZKDW�LWLV�QH[W�WLPH�

use 5.010;

greet( 'Fred' );greet( 'Barney' );

sub greet {

:H�FDQ¦W�GR�WKLV�ZLWKRXW�DGYDQFHG�WULFNLQHVV��WKDW�LV��,W¦V�UDUH�WR�ILQG�DQ\WKLQJ�WKDW�\RX�DEVROXWHO\�FDQ¦W�GRLQ�3HUO�

� 2U�DQ�HPSW\�OLVW��LI�&average�LV�XVHG�LQ�D�OLVW�FRQWH[W�

266 | Appendix A:ಗExercise Answers

state $last_person;

my $name = shift;

print "Hi $name! ";

if( defined $last_person ) { print "$last_person is also here!\n"; } else { print "You are the first one here!\n"; }

$last_person = $name; }

�� 7KLV�DQVZHU�LV�VLPLODU�WR�WKDW�IRU�WKH�SUHFHGLQJ�H[HUFLVH��EXW�WKLV�WLPH�ZH�VWRUH�DOOWKH�QDPHV�ZH�KDYH�VHHQ��,QVWHDG�RI�XVLQJ�D�VFDODU�YDULDEOH��ZH�GHFODUH�@names�DV�DVWDWH�YDULDEOH�DQG�SXVK�HDFK�QDPH�RQWR�LW�

use 5.010;

greet( 'Fred' );greet( 'Barney' );greet( 'Wilma' );greet( 'Betty' );

sub greet { state @names;

my $name = shift;

print "Hi $name! ";

if( @names ) { print "I've seen: @names\n"; } else { print "You are the first one here!\n"; }

push @names, $name; }

Answers to Chapter 5 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

print reverse <>;

:HOO��WKDW¦V�SUHWW\�VLPSOH��%XW�LW�ZRUNV�EHFDXVH�print�LV�ORRNLQJ�IRU�D�OLVW�RI�VWULQJVWR�SULQW��ZKLFK�LW�JHWV�E\�FDOOLQJ�reverse�LQ�D�OLVW�FRQWH[W��$QG�reverse�LV�ORRNLQJIRU�D�OLVW�RI�VWULQJV�WR�UHYHUVH��ZKLFK�LW�JHWV�E\�XVLQJ�WKH�GLDPRQG�RSHUDWRU�LQ�OLVWFRQWH[W��6R��WKH�GLDPRQG�UHWXUQV�D�OLVW�RI�DOO�RI�WKH�OLQHV�IURP�DOO�RI�WKH�ILOHV�RI�WKH

Answers to Chapter 5 Exercises | 267

XVHU¦V�FKRLFH��7KDW�OLVW�RI�OLQHV�LV�MXVW�ZKDW�FDW�ZRXOG�SULQW�RXW��1RZ�reverse�UH�YHUVHV�WKH�OLVW�RI�OLQHV��DQG�print�SULQWV�WKHP�RXW�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

print "Enter some lines, then press Ctrl-D:\n"; # or Ctrl-Zchomp(my @lines = <STDIN>);

print "1234567890" x 7, "12345\n"; # ruler line to column 75

foreach (@lines) { printf "%20s\n", $_;}

+HUH��ZH�VWDUW�E\�UHDGLQJ�LQ�DQG�FKRPSLQJ�DOO�RI�WKH�OLQHV�RI�WH[W��7KHQ�ZH�SULQWWKH�UXOHU�OLQH��6LQFH�WKDW¦V�D�GHEXJJLQJ�DLG��ZH¦G�JHQHUDOO\�FRPPHQW�RXW�WKDW�OLQHZKHQ�WKH�SURJUDP�LV�GRQH��:H�FRXOG�KDYH�W\SHG�"1234567890"�DJDLQ�DQG�DJDLQ��RUHYHQ�XVHG�FRS\�DQG�SDVWH�WR�PDNH�D�UXOHU�OLQH�DV�ORQJ�DV�ZH�QHHGHG��EXW�ZH�FKRVHWR�GR�LW�WKLV�ZD\�EHFDXVH�LW¦V�NLQG�RI�FRRO�

1RZ��WKH�foreach� ORRS�LWHUDWHV�RYHU�WKH�OLVW�RI�OLQHV��SULQWLQJ�HDFK�RQH�ZLWK�WKH%20s�FRQYHUVLRQ��,I�\RX�FKRVH�WR�GR�VR��\RX�FRXOG�KDYH�FUHDWHG�D�IRUPDW�WR�SULQWWKH�OLVW�DOO�DW�RQFH��ZLWKRXW�WKH�ORRS�

my $format = "%20s\n" x @lines;printf $format, @lines;

,W¦V�D�FRPPRQ�PLVWDNH�WR�JHW����FKDUDFWHU�FROXPQV��7KDW�KDSSHQV�ZKHQ�\RX�VD\WR�\RXUVHOI� �£+H\��ZK\�GR�ZH�chomp�WKH�LQSXW�LI�ZH¦UH�RQO\�JRLQJ�WR�DGG�WKH�QHZOLQHVEDFN�RQ�ODWHU"¤�6R�\RX�OHDYH�RXW�WKH�chomp�DQG�XVH�D�IRUPDW�RI�%20s� �ZLWKRXW�DQHZOLQH����$QG�QRZ��P\VWHULRXVO\��WKH�RXWSXW�LV�RII�E\�RQH�VSDFH��6R��ZKDW�ZHQWZURQJ"

7KH�SUREOHP�KDSSHQV�ZKHQ�3HUO�WULHV�WR�FRXQW�WKH�VSDFHV�QHHGHG�WR�PDNH�WKH�ULJKWQXPEHU�RI�FROXPQV��,I�WKH�XVHU�HQWHUV�hello�DQG�D�QHZOLQH��3HUO�VHHV�VL[�FKDUDFWHUV�QRW�ILYH��VLQFH�QHZOLQH�LV�D�FKDUDFWHU��6R�LW�SULQWV����VSDFHV�DQG�D���FKDUDFWHU�VWULQJ�VXUH�WKDW�LW�JLYHV�WKH����FKDUDFWHUV�\RX�DVNHG�IRU�LQ�%20s��2RSV�

2I�FRXUVH��3HUO�LVQ¦W�ORRNLQJ�DW�WKH�FRQWHQWV�RI�WKH�VWULQJ�WR�GHWHUPLQH�WKH�ZLGWK�LW�PHUHO\�FKHFNV�WKH�UDZ�QXPEHU�RI�FKDUDFWHUV��$�QHZOLQH��RU�DQRWKHU�VSHFLDO�FKDU�DFWHU��VXFK�DV�D�WDE�RU�D�QXOO�FKDUDFWHU��ZLOO�WKURZ�WKLQJV�RII�®

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

print "What column width would you like? ";chomp(my $width = <STDIN>);

print "Enter some lines, then press Ctrl-D:\n"; # or Ctrl-Z

2U�WR�/DUU\��LI�KH¦V�VWDQGLQJ�QHDUE\�

� 8QOHVV�/DUU\�WROG�\RX�QRW�WR�GR�WKDW�

® $V�/DUU\�VKRXOG�KDYH�H[SODLQHG�WR�\RX�E\�QRZ�

268 | Appendix A:ಗExercise Answers

chomp(my @lines = <STDIN>);

print "1234567890" x (($width+9)/10), "\n"; # ruler line as needed

foreach (@lines) { printf "%${width}s\n", $_;}

7KLV�LV�PXFK�OLNH�WKH�SUHYLRXV�RQH��EXW�ZH�DVN�IRU�D�FROXPQ�ZLGWK�ILUVW��:H�DVNIRU�WKDW�ILUVW�EHFDXVH�ZH�FDQ¦W�DVN�IRU�PRUH�LQSXW�DIWHU�WKH�HQG�RI�ILOH�LQGLFDWRU��DWOHDVW�RQ�VRPH�V\VWHPV��2I�FRXUVH��LQ�WKH�UHDO�ZRUOG��\RX¦OO�JHQHUDOO\�KDYH�D�EHWWHUHQG�RI�LQSXW�LQGLFDWRU�ZKHQ�JHWWLQJ�LQSXW�IURP�WKH�XVHU��DV�ZH¦OO�VHH�LQ�ODWHU�H[HU�FLVH�DQVZHUV�

$QRWKHU�FKDQJH�IURP�WKH�SUHYLRXV�H[HUFLVH¦V�DQVZHU�LV�WKH�UXOHU�OLQH��:H�XVHG�VRPHPDWK�WR�FRRN�XS�D�UXOHU�OLQH�WKDW¦V�DW�OHDVW�DV�ORQJ�DV�ZH�QHHG��DV�VXJJHVWHG�DV�DQH[WUD�FUHGLW�SDUW�RI�WKH�H[HUFLVH��3URYLQJ�WKDW�RXU�PDWK�LV�FRUUHFW�LV�DQ�DGGLWLRQDOFKDOOHQJH���+LQW��FRQVLGHU�SRVVLEOH�ZLGWKV�RI�50�DQG�51��DQG�UHPHPEHU�WKDW�WKHULJKW�VLGH�RSHUDQG�WR�x�LV�WUXQFDWHG��QRW�URXQGHG��

7R�JHQHUDWH�WKH�IRUPDW�WKLV�WLPH��ZH�XVHG�WKH�H[SUHVVLRQ�"%${width}s\n"��ZKLFKLQWHUSRODWHV�$width��7KH�FXUO\�EUDFHV�DUH�UHTXLUHG�WR�£LQVXODWH¤�WKH�QDPH�IURP�WKHIROORZLQJ�s��ZLWKRXW�WKH�FXUO\�EUDFHV��ZH¦G�EH�LQWHUSRODWLQJ�$widths��WKH�ZURQJYDULDEOH��,I�\RX�IRUJRW�KRZ�WR�XVH�FXUO\�EUDFHV�WR�GR�WKLV��WKRXJK��\RX�FRXOG�KDYHZULWWHQ�DQ�H[SUHVVLRQ�OLNH�'%' . $width . "s\n"�WR�JHW�WKH�VDPH�IRUPDW�VWULQJ�

7KH�YDOXH�RI�$width�EULQJV�XS�DQRWKHU�FDVH�ZKHUH�chomp�LV�YLWDO��,I�WKH�ZLGWK�LVQ¦WFKRPSHG�� WKH� UHVXOWLQJ� IRUPDW� VWULQJ� ZRXOG� UHVHPEOH� "%30\ns\n"�� 7KDW¦V� QRWXVHIXO�

3HRSOH�ZKR�KDYH�VHHQ�printf�EHIRUH�PD\�KDYH�WKRXJKW�RI�DQRWKHU�VROXWLRQ��%HFDXVHprintf�FRPHV�WR�XV�IURP�&��ZKLFK�GRHVQ¦W�KDYH�VWULQJ�LQWHUSRODWLRQ��ZH�FDQ�XVHWKH�VDPH� WULFN� WKDW�&�SURJUDPPHUV�XVH�� ,I�DQ�DVWHULVN� �*��DSSHDUV� LQ�SODFH�RI�DQXPHULF�ILHOG�ZLGWK�LQ�D�FRQYHUVLRQ��D�YDOXH�IURP�WKH�OLVW�RI�SDUDPHWHUV�ZLOO�EH�XVHG�

printf "%*s\n", $width, $_;

Answers to Chapter 6 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

my %last_name = qw{ fred flintstone barney rubble wilma flintstone};print "Please enter a first name: ";chomp(my $name = <STDIN>);print "That's $name $last_name{$name}.\n";

Answers to Chapter 6 Exercises | 269

,Q�WKLV�RQH��ZH�XVHG�D�qw//�OLVW��ZLWK�FXUO\�EUDFHV�DV�WKH�GHOLPLWHU��WR�LQLWLDOL]H�WKHKDVK��7KDW¦V�ILQH�IRU�WKLV�VLPSOH�GDWD�VHW��DQG�LW¦V�HDV\�WR�PDLQWDLQ�EHFDXVH�HDFKGDWD�LWHP�LV�D�VLPSOH�JLYHQ�QDPH�DQG�VLPSOH�IDPLO\�QDPH��ZLWK�QRWKLQJ�WULFN\��%XWLI�\RXU�GDWD�PLJKW�FRQWDLQ�VSDFHV¢IRU�H[DPSOH�� LI�robert de niro�RU�mary kayplace�ZHUH�WR�YLVLW�%HGURFN¢WKLV�VLPSOH�PHWKRG�ZRXOGQ¦W�ZRUN�VR�ZHOO�

<RX�PLJKW�KDYH�FKRVHQ�WR�DVVLJQ�HDFK�NH\ YDOXH�SDLU�VHSDUDWHO\��VRPHWKLQJ�OLNHWKLV�

my %last_name;$last_name{"fred"} = "flintstone";$last_name{"barney"} = "rubble";$last_name{"wilma"} = "flintstone";

1RWH�WKDW��LI�\RX�FKRVH�WR�GHFODUH�WKH�KDVK�ZLWK�my��SHUKDSV�EHFDXVH�use strictZDV�LQ�HIIHFW���\RX�PXVW�GHFODUH�WKH�KDVK�EHIRUH�DVVLJQLQJ�DQ\�HOHPHQWV��<RX�FDQ¦WXVH�my�RQ�RQO\�SDUW�RI�D�YDULDEOH��OLNH�WKLV�

my $last_name{"fred"} = "flintstone"; # Oops!

7KH�my�RSHUDWRU�ZRUNV�RQO\�ZLWK�HQWLUH�YDULDEOHV��QHYHU�ZLWK�MXVW�RQH�HOHPHQW�RIDQ�DUUD\�RU�KDVK��6SHDNLQJ�RI�OH[LFDO�YDULDEOHV��\RX�PD\�KDYH�QRWLFHG�WKDW�WKH�OH[LFDOYDULDEOH�$name�LV�EHLQJ�GHFODUHG�LQVLGH�RI�WKH�chomp�IXQFWLRQ�FDOO��LW�LV�IDLUO\�FRPPRQWR�GHFODUH�HDFK�my�YDULDEOH�DV�LW�LV�QHHGHG��OLNH�WKLV�

7KLV�LV�DQRWKHU�FDVH�ZKHUH�chomp�LV�YLWDO��,I�VRPHRQH�HQWHUV�WKH�ILYH�FKDUDFWHU�VWULQJ"fred\n"�DQG�ZH�IDLO�WR�chomp�LW��ZH¦OO�EH�ORRNLQJ�IRU�"fred\n"�DV�DQ�HOHPHQW�RI�WKHKDVK¢DQG�LW¦V�QRW�WKHUH��2I�FRXUVH��chomp�DORQH�ZRQ¦W�PDNH�WKLV�EXOOHWSURRI��LIVRPHRQH�HQWHUV�"fred \n"��ZLWK�D�WUDLOLQJ�VSDFH���ZH�GRQ¦W�KDYH�D�ZD\�ZLWK�ZKDWZH¦YH�VHHQ�VR�IDU�WR�WHOO�WKDW�WKH\�PHDQW�fred�

,I�\RX�DGGHG�D�FKHFN�ZKHWKHU�WKH�JLYHQ�NH\�exists�LQ�WKH�KDVK�VR�WKDW�\RX¦OO�JLYHWKH�XVHU�DQ�H[SODQDWRU\�PHVVDJH�ZKHQ�WKH\�PLVVSHOO�D�QDPH��JLYH�\RXUVHOI�H[WUDSRLQWV�IRU�WKDW�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

my(@words, %count, $word); # (optionally) declare our variableschomp(@words = <STDIN>);

foreach $word (@words) { $count{$word} += 1; # or $count{$word} = $count{$word} + 1;}

foreach $word (keys %count) { # or sort keys %count print "$word was seen $count{$word} times.\n";}

,Q�WKLV�RQH��ZH�GHFODUHG�DOO�RI�WKH�YDULDEOHV�DW�WKH�WRS��3HRSOH�ZKR�FRPH�WR�3HUOIURP�D�EDFNJURXQG�LQ�ODQJXDJHV�OLNH�3DVFDO��ZKHUH�YDULDEOHV�DUH�DOZD\V�GHFODUHG£DW�WKH�WRS¤��PD\�ILQG�WKDW�ZD\�PRUH�IDPLOLDU�WKDQ�GHFODULQJ�YDULDEOHV�DV�WKH\�DUHQHHGHG�� 2I� FRXUVH�� ZH¦UH� GHFODULQJ� WKHVH� EHFDXVH� ZH¦UH� SUHWHQGLQJ� WKDW� usestrict�PD\�EH�LQ�HIIHFW��E\�GHIDXOW��3HUO�ZRQ¦W�UHTXLUH�VXFK�GHFODUDWLRQV�

270 | Appendix A:ಗExercise Answers

1H[W��ZH�XVH�WKH�OLQH�LQSXW�RSHUDWRU��<STDIN>��LQ�D�OLVW�FRQWH[W�WR�UHDG�DOO�RI�WKHLQSXW�OLQHV�LQWR�@words��DQG�WKHQ�ZH�chomp�WKRVH�DOO�DW�RQFH��6R�@words�LV�RXU�OLVW�RIZRUGV�IURP�WKH�LQSXW��LI�WKH�ZRUGV�ZHUH�DOO�RQ�VHSDUDWH�OLQHV��DV�WKH\�VKRXOG�KDYHEHHQ��RI�FRXUVH��

7KHQ��WKH�ILUVW�foreach�ORRS�JRHV�WKURXJK�DOO�RI�WKH�ZRUGV��7KDW�ORRS�FRQWDLQV�WKHPRVW�LPSRUWDQW�VWDWHPHQW�RI�WKH�HQWLUH�SURJUDP��WKH�VWDWHPHQW�WKDW�VD\V�WR�DGGRQH�WR�$count{$word}��DQG�SXW�WKH�UHVXOW�EDFN�LQWR�$count{$word}��$OWKRXJK�\RXFRXOG�ZULWH�LW�HLWKHU�WKH�VKRUW�ZD\��ZLWK�WKH�+=�RSHUDWRU��RU�WKH�ORQJ�ZD\��WKH�VKRUWZD\�LV�MXVW�D�OLWWOH�ELW�PRUH�HIILFLHQW��VLQFH�3HUO�KDV�WR�ORRN�XS�$word�LQ�WKH�KDVK�MXVWRQFH� �)RU�HDFK�ZRUG�LQ�WKH�ILUVW�foreach�ORRS��ZH�DGG�RQH�WR�$count{$word}��6R��LIWKH�ILUVW�ZRUG�LV�fred��ZH�DGG�RQH�WR�$count{"fred"}��2I�FRXUVH��VLQFH�WKLV�LV�WKHILUVW� WLPH�ZH¦YH� VHHQ�$count{"fred"}�� LW¦V�undef��%XW� VLQFH�ZH¦UH� WUHDWLQJ� LW� DV�DQXPEHU��ZLWK�WKH�QXPHULF�+=�RSHUDWRU��RU�ZLWK�+��LI�\RX�ZURWH�LW�WKH�ORQJ�ZD\���3HUOFRQYHUWV�undef�WR�0�IRU�XV��DXWRPDWLFDOO\��7KH�WRWDO�LV�1��ZKLFK�LV�WKHQ�VWRUHG�EDFNLQWR�$count{"fred"}�

7KH�QH[W�WLPH�WKURXJK�WKDW�foreach�ORRS��OHW¦V�VD\�WKH�ZRUG�LV�barney��6R��ZH�DGGRQH�WR�$count{"barney"}��EXPSLQJ�LW�XS�IURP�undef�WR�1��DV�ZHOO�

1RZ�OHW¦V�VD\�WKH�QH[W�ZRUG�LV�fred�DJDLQ��:KHQ�ZH�DGG�RQH�WR�$count{"fred"}�ZKLFK�LV�DOUHDG\�1��ZH�JHW�2��7KLV�JRHV�EDFN�LQWR�$count{"fred"}��PHDQLQJ�WKDWZH¦YH�QRZ�VHHQ�fred�WZLFH�

:KHQ�ZH�ILQLVK�WKH�ILUVW�foreach�ORRS��WKHQ��ZH¦YH�FRXQWHG�KRZ�PDQ\�WLPHV�HDFKZRUG�KDV�DSSHDUHG��7KH�KDVK�KDV�D�NH\�IRU�HDFK��XQLTXH��ZRUG�IURP�WKH�LQSXW��DQGWKH�FRUUHVSRQGLQJ�YDOXH�LV�WKH�QXPEHU�RI�WLPHV�WKDW�ZRUG�DSSHDUHG�

6R�QRZ��WKH�VHFRQG�foreach�ORRS�JRHV�WKURXJK�WKH�NH\V�RI�WKH�KDVK��ZKLFK�DUH�WKHXQLTXH�ZRUGV�IURP�WKH�LQSXW��,Q�WKLV�ORRS��ZH¦OO�VHH�HDFK�GLIIHUHQW�ZRUG�RQFH��)RUHDFK�RQH��LW�VD\V�VRPHWKLQJ�OLNH�£fred was seen 3 times¤�

,I�\RX�ZDQW�WKH�H[WUD�FUHGLW�RQ�WKLV�SUREOHP��\RX�FRXOG�SXW�sort�EHIRUH�keys�WRSULQW�RXW�WKH�NH\V�LQ�RUGHU��,I�WKHUH�ZLOO�EH�PRUH�WKDQ�D�GR]HQ�LWHPV�LQ�DQ�RXWSXWOLVW��LW¦V�JHQHUDOO\�D�JRRG�LGHD�IRU�WKHP�WR�EH�VRUWHG�VR�WKDW�D�KXPDQ�EHLQJ�ZKR�LVWU\LQJ�WR�GHEXJ�WKH�SURJUDP�ZLOO�IDLUO\�TXLFNO\�EH�DEOH�WR�ILQG�WKH�LWHP�VKH�ZDQWV�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

my $longest = 0;foreach my $key ( keys %ENV ) { my $key_length = length( $key ); $longest = $key_length if $key_length > $longest; }

foreach my $key ( sort keys %ENV ) {

$OVR��DW�OHDVW�LQ�VRPH�YHUVLRQV�RI�3HUO��WKH�VKRUWHU�ZD\�ZLOO�DYRLG�D�ZDUQLQJ�DERXW�XVLQJ�DQ�XQGHILQHG�YDOXHWKDW�PD\�FURS�XS�ZLWK�WKH�ORQJHU�RQH��7KH�ZDUQLQJ�PD\�DOVR�EH�DYRLGHG�E\�XVLQJ�WKH�++�RSHUDWRU�WR�LQFUHPHQWWKH�YDULDEOH��DOWKRXJK�ZH�KDYHQ¦W�VKRZQ�\RX�WKDW�RSHUDWRU�\HW�

Answers to Chapter 6 Exercises | 271

printf "%-${longest}s %s\n", $key, $ENV{$key}; }

,Q�WKH�ILUVW�foreach�ORRS��ZH�JR�WKURXJK�DOO�RI�WKH�NH\V�DQG�XVH�length�WR�JHW�WKHLUOHQJWK�� ,I� WKH� OHQJWK� ZH� MXVW� PHDVXUHG� LV� JUHDWHU� WKDQ� WKH� RQH� ZH� VWRUHG� LQ$longest��ZH�SXW�WKH�ORQJHU�YDOXH�LQ�$longer�

2QFH�ZH¦YH�JRQH�WKURXJK�DOO�RI�WKH�NH\V��ZH�XVH�printf�WR�SULQW�WKH�NH\V�DQG�YDOXHVLQ�WZR�FROXPQV��:H�XVH�WKH�VDPH�WULFN�ZH�XVHG�LQ�H[HUFLVH���IURP�&KDSWHU���E\LQWHUSRODWLQJ�$longest�LQWR�WKH�WHPSODWH�VWULQJ�

Answers to Chapter 7 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

while (<>) { if (/fred/) { print; }}

7KLV�LV�SUHWW\�VLPSOH��7KH�PRUH�LPSRUWDQW�SDUW�RI�WKLV�H[HUFLVH�LV�WU\LQJ�LW�RXW�RQWKH�VDPSOH�VWULQJV�� ,W�GRHVQ¦W�PDWFK�Fred�� VKRZLQJ�WKDW�UHJXODU�H[SUHVVLRQV�DUHFDVH�VHQVLWLYH���:H¦OO�VHH�KRZ�WR�FKDQJH�WKDW�ODWHU���,W�GRHV�PDWFK�frederick�DQGAlfred��VLQFH�ERWK�RI�WKRVH�VWULQJV�FRQWDLQ�WKH�IRXU�OHWWHU�VWULQJ�fred���0DWFKLQJZKROH�ZRUGV�RQO\��VR�WKDW�frederick�DQG�Alfred�ZRXOGQ¦W�PDWFK��LV�DQRWKHU�IHDWXUHZH¦OO�VHH�ODWHU��

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

&KDQJH�WKH�SDWWHUQ�XVHG�LQ�WKH�ILUVW�H[HUFLVH¦V�DQVZHU�WR�/[fF]red/��<RX�FRXOG�DOVRKDYH�WULHG�/(f|F)red/�RU�/fred|Fred/��EXW�WKH�FKDUDFWHU�FODVV�LV�PRUH�HIILFLHQW�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

&KDQJH�WKH�SDWWHUQ�XVHG�LQ�WKH�ILUVW�H[HUFLVH¦V�DQVZHU�WR�/\./��7KH�EDFNVODVK�LVQHHGHG�EHFDXVH� WKH�GRW� LV�D�PHWDFKDUDFWHU��RU�\RX�FRXOG�XVH�D�FKDUDFWHU�FODVV�/[.]/�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

&KDQJH�WKH�SDWWHUQ�XVHG�LQ�WKH�ILUVW�H[HUFLVH¦V�DQVZHU�WR�/[A-Z][a-z]+/�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

&KDQJH�WKH�SDWWHUQ�XVHG�LQ�WKH�ILUVW�H[HUFLVH¦V�DQVZHU�WR�/(\S)\1/��7KH�\S�FKDUDFWHUFODVV�PDWFKHV�WKH�QRQZKLWHVSDFH�FKDUDFWHU��DQG�WKH�SDUHQWKHVHV�DOORZ�\RX�WR�XVHWKH�EDFN�UHIHUHQFH�\1�WR�PDWFK�WKH�VDPH�FKDUDFWHU�LPPHGLDWHO\�IROORZLQJ�LW�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

while (<>) { if (/wilma/) { if (/fred/) { print;

272 | Appendix A:ಗExercise Answers

} }}

7KLV�WHVWV�/fred/�RQO\�DIWHU�ZH�ILQG�/wilma/�PDWFKHV��EXW�fred�FRXOG�DSSHDU�EHIRUHRU�DIWHU�wilma�LQ�WKH�OLQH��HDFK�WHVW�LV�LQGHSHQGHQW�RI�WKH�RWKHU�

,I�\RX�ZDQWHG�WR�DYRLG�WKH�H[WUD�QHVWHG�if�WHVW��\RX�PLJKW�KDYH�ZULWWHQ�VRPHWKLQJOLNH�WKLV�

while (<>) { if (/wilma.*fred|fred.*wilma/) { print; }}

7KLV�ZRUNV�EHFDXVH�ZH¦OO�HLWKHU�KDYH�wilma�EHIRUH�fred��RU�fred�EHIRUH�wilma��,I�ZHKDG�ZULWWHQ�MXVW�/wilma.*fred/��WKDW�ZRXOGQ¦W�KDYH�PDWFKHG�D�OLQH�OLNH�fred andwilma flintstone��HYHQ�WKRXJK�WKDW�OLQH�PHQWLRQV�ERWK�RI�WKHP�

:H�PDGH�WKLV�DQ�H[WUD�FUHGLW�H[HUFLVH�EHFDXVH�PDQ\�IRONV�KDYH�D�PHQWDO�EORFN�KHUH�:H�VKRZHG�\RX�DQ�£RU¤�RSHUDWLRQ��ZLWK�WKH�YHUWLFDO�EDU��|���EXW�ZH�QHYHU�VKRZHG\RX�DQ�£DQG¤�RSHUDWLRQ��7KDW¦V�EHFDXVH�WKHUH�LVQ¦W�RQH�LQ�UHJXODU�H[SUHVVLRQV���,I\RX�ZDQW�WR�NQRZ�ZKHWKHU�RQH�SDWWHUQ�DQG�DQRWKHU�DUH�ERWK�VXFFHVVIXO��MXVW�WHVWERWK�RI�WKHP�

Answers to Chapter 8 Exercises�� 7KHUH¦V�RQH�HDV\�ZD\�WR�GR�LW��DQG�ZH�VKRZHG�LW�EDFN�LQ�WKH�FKDSWHU�ERG\��%XW�LI

\RXU�RXWSXW�LVQ¦W�VD\LQJ�before<match>after�DV�LW�VKRXOG��\RX¦YH�FKRVHQ�D�KDUG�ZD\WR�GR�LW�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

/a\b/

�2I�FRXUVH��WKDW¦V�D�SDWWHUQ�IRU�XVH�LQVLGH�WKH�SDWWHUQ�WHVW�SURJUDP���,I�\RXU�SDWWHUQPLVWDNHQO\�PDWFKHV�barney��\RX�SUREDEO\�QHHGHG�WKH�ZRUG�ERXQGDU\�DQFKRU�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

#!/usr/bin/perlwhile (<STDIN>) { chomp; if (/(\b\w*a\b)/) {

)RONV�ZKR�NQRZ�DERXW�WKH�ORJLFDO�DQG�RSHUDWRU��ZKLFK�ZH¦OO�VHH�LQ�&KDSWHU�����FRXOG�GR�ERWK�WHVWV�/fred/DQG�/wilma/�LQ�WKH�VDPH�if�FRQGLWLRQDO��7KDW¦V�PRUH�HIILFLHQW��PRUH�VFDODEOH��DQG�DQ�DOO�DURXQG�EHWWHU�ZD\WKDQ�WKH�RQHV�JLYHQ�KHUH��%XW�ZH�KDYHQ¦W�VHHQ�ORJLFDO�DQG�\HW�

� %XW�WKHUH�DUH�VRPH�WULFN\�DQG�DGYDQFHG�ZD\V�RI�GRLQJ�ZKDW�VRPH�IRONV�ZRXOG�FDOO�DQ�£DQG¤�RSHUDWLRQ��7KHVHDUH�JHQHUDOO\�OHVV�HIILFLHQW�WKDQ�XVLQJ�3HUO¦V�ORJLFDO�DQG��WKRXJK��GHSHQGLQJ�XSRQ�ZKDW�RSWLPL]DWLRQV�3HUO�DQGLWV�UHJXODU�H[SUHVVLRQ�HQJLQH�FDQ�PDNH�

Answers to Chapter 8 Exercises | 273

print "Matched: |$`<$&>$'|\n"; print "\$1 contains '$1'\n"; # The new output line } else { print "No match: |$_|\n"; }}

7KLV�LV�WKH�VDPH�WHVW�SURJUDP��ZLWK�D�QHZ�SDWWHUQ���H[FHSW�WKDW�WKH�RQH�PDUNHGOLQH�KDV�EHHQ�DGGHG�WR�SULQW�RXW�$1�

7KH� SDWWHUQ� XVHV� D� SDLU� RI� \b� ZRUG�ERXQGDU\� DQFKRUV � LQVLGH� WKH� SDUHQWKHVHV�DOWKRXJK�WKH�SDWWHUQ�ZRUNV�WKH�VDPH�ZD\�ZKHQ�WKH\�DUH�SODFHG�RXWVLGH��7KDW¦VEHFDXVH�DQFKRUV�FRUUHVSRQG�WR�D�SODFH�LQ�WKH�VWULQJ��EXW�QRW�WR�DQ\�FKDUDFWHUV�LQWKH�VWULQJ��DQFKRUV�KDYH�£]HUR�ZLGWK�¤

�� 7KLV�H[HUFLVH�DQVZHU�LV�WKH�VDPH�DV�WKH�SUHYLRXV�H[HUFLVH�ZLWK�D�VOLJKWO\�GLIIHUHQWUHJXODU�H[SUHVVLRQ�

#!/usr/bin/perl

use 5.010;

while (<STDIN>) { chomp; if (/(?<word>\b\w*a\b)/) { print "Matched: |$`<$&>$'|\n"; print "'word' contains '$+{word}'\n"; # The new output line } else { print "No match: |$_|\n"; }}

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

m! (\b\w*a\b) # $1: a word ending in a (.{0,5}) # $2: up to five characters following!xs # /x and /s modifiers

�'RQ¦W�IRUJHW�WR�DGG�FRGH�WR�GLVSOD\�$2��QRZ�WKDW�\RX�KDYH�WZR�PHPRU\�YDULDEOHV�,I�\RX�FKDQJH�WKH�SDWWHUQ�WR�KDYH�MXVW�RQH�DJDLQ��\RX�FDQ�VLPSO\�FRPPHQW�RXW�WKHH[WUD�OLQH���,I�\RXU�SDWWHUQ�GRHVQ¦W�PDWFK�MXVW�SODLQ�wilma�DQ\PRUH��SHUKDSV�\RXUHTXLUH�RQH�RU�PRUH�FKDUDFWHUV��LQVWHDG�RI�]HUR�RU�PRUH��<RX�PD\�KDYH�RPLWWHGWKH�/s�PRGLILHU��VLQFH�WKHUH�VKRXOGQ¦W�EH�QHZOLQHV�LQ�WKH�GDWD���2I�FRXUVH��LI�WKHUHDUH�QHZOLQHV�LQ�WKH�GDWD��WKH�/s�PRGLILHU�FRXOG�PDNH�IRU�GLIIHUHQW�RXWSXW��

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

while (<>) { chomp; if (/\s+$/) { print "$_#\n";

$GPLWWHGO\��WKH�ILUVW�DQFKRU�LVQ¦W�UHDOO\�QHHGHG��GXH�WR�GHWDLOV�DERXW�JUHHGLQHVV�WKDW�ZH�ZRQ¦W�JR�LQWR�KHUH�%XW�LW�PD\�KHOS�D�WLQ\�ELW�ZLWK�HIILFLHQF\��DQG�LW�FHUWDLQO\�KHOSV�ZLWK�FODULW\��DQG�LQ�WKH�HQG�WKDW�RQH�ZLQV�RXW�

274 | Appendix A:ಗExercise Answers

}}

:H�XVHG�WKH�SRXQG�VLJQ��#��DV�WKH�PDUNHU�FKDUDFWHU�

Answers to Chapter 9 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

/($what){3}/

2QFH�$what�KDV�EHHQ�LQWHUSRODWHG��WKLV�JLYHV�D�SDWWHUQ�UHVHPEOLQJ�/(fred|barney){3}/�� :LWKRXW� WKH� SDUHQWKHVHV�� WKH� SDWWHUQ� ZRXOG� EH� VRPHWKLQJOLNH�/fred|barney{3}/��ZKLFK�LV�WKH�VDPH�DV�/fred|barneyyy/��6R��WKH�SDUHQWKHVHVDUH�UHTXLUHG�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

my $in = $ARGV[0];unless (defined $in) { die "Usage: $0 filename";}

my $out = $in;$out =~ s/(\.\w+)?$/.out/;

unless (open IN, "<$in") { die "Can't open '$in': $!";}

unless (open OUT, ">$out") { die "Can't write '$out': $!";}

while (<IN>) { s/Fred/Larry/gi; print OUT $_;}

7KLV�SURJUDP�EHJLQV�E\�QDPLQJ�LWV�RQH�DQG�RQO\�FRPPDQG�OLQH�SDUDPHWHU��DQGFRPSODLQLQJ�LI�LW�GLGQ¦W�JHW�LW��7KHQ�LW�FRSLHV�WKDW�WR�$out�DQG�GRHV�D�VXEVWLWXWLRQWR�FKDQJH� WKH� ILOH�H[WHQVLRQ�� LI�DQ\�� WR�.out�� �,W�ZRXOG�EH�VXIILFLHQW�� WKRXJK�� WRPHUHO\�DSSHQG�.out�WR�WKH�ILOHQDPH��

2QFH�WKH�ILOHKDQGOHV�IN�DQG�OUT�DUH�RSHQHG��WKH�UHDO�SURJUDP�FDQ�EHJLQ��,I�\RXGLGQ¦W�XVH�ERWK�RSWLRQV�/g�DQG�/i��WDNH�RII�KDOI�D�SRLQW��VLQFH�HYHU\�fred�DQG�HYHU\Fred�VKRXOG�EH�FKDQJHG�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

while (<IN>) { chomp; s/Fred/\n/gi; # Replace all FREDs s/Wilma/Fred/gi; # Replace all WILMAs

Answers to Chapter 9 Exercises | 275

s/\n/Wilma/g; # Replace the placeholder print OUT "$_\n";}

7KLV�UHSODFHV�WKH�ORRS�IURP�WKH�SUHYLRXV�SURJUDP��RI�FRXUVH��7R�GR�WKLV�NLQG�RI�DVZDS��ZH�QHHG�WR�KDYH�VRPH�£SODFHKROGHU¤�VWULQJ��ZKLFK�GRHVQ¦W�RWKHUZLVH�DSSHDULQ�WKH�GDWD��%\�XVLQJ�chomp��DQG�DGGLQJ�WKH�QHZOLQH�EDFN�IRU�WKH�RXWSXW��ZH�HQVXUHWKDW�D�QHZOLQH��\n��FDQ�EH�WKH�SODFHKROGHU���<RX�FRXOG�FKRRVH�VRPH�RWKHU�XQOLNHO\VWULQJ�DV�WKH�SODFHKROGHU��$QRWKHU�JRRG�FKRLFH�ZRXOG�EH�WKH�18/�FKDUDFWHU��£?�¤��

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

$^I = ".bak"; # make backupswhile (<>) { if (/^#!/) { # is it the shebang line? $_ .= "## Copyright (C) 20XX by Yours Truly\n"; } print;}

,QYRNH�WKLV�SURJUDP�ZLWK�WKH�ILOHQDPHV�\RX�ZDQW�WR�XSGDWH��)RU�H[DPSOH��LI�\RX¦YHEHHQ�QDPLQJ�\RXU�H[HUFLVHV�H[������H[������DQG�VR�RQ��VR�WKDW�WKH\�DOO�EHJLQ�ZLWKex...��\RX�ZRXOG�XVH�

./fix_my_copyright ex*

�� 7R�NHHS�IURP�DGGLQJ�WKH�FRS\ULJKW�WZLFH��ZH�KDYH�WR�PDNH�WZR�SDVVHV�RYHU�WKHILOHV��)LUVW��ZH�PDNH�D�£VHW¤�ZLWK�D�KDVK�ZKHUH�WKH�NH\V�DUH�WKH�ILOHQDPHV�DQG�WKHYDOXHV�GRQ¦W�PDWWHU��DOWKRXJK�ZH¦OO�XVH�1�IRU�FRQYHQLHQFH��

my %do_these;foreach (@ARGV) { $do_these{$_} = 1;}

1H[W��ZH¦OO�H[DPLQH�WKH�ILOHV��DQG�UHPRYH�IURP�RXU�WR�GR�OLVW�DQ\�ILOH�WKDW�DOUHDG\FRQWDLQV�WKH�FRS\ULJKW��7KH�FXUUHQW�ILOHQDPH�LV�LQ�$ARGV��VR�ZH�FDQ�XVH�WKDW�DV�WKHKDVK�NH\�

while (<>) { if (/^## Copyright/) { delete $do_these{$ARGV}; }}

)LQDOO\��LW¦V�WKH�VDPH�SURJUDP�DV�EHIRUH��RQFH�ZH¦YH�UHHVWDEOLVKHG�D�UHGXFHG�OLVW�RIQDPHV�LQ�@ARGV�

@ARGV = sort keys %do_these;$^I = ".bak"; # make backupswhile (<>) { if (/^#!/) { # is it the shebang line? $_ .= "## Copyright (c) 20XX by Yours Truly\n"; }

276 | Appendix A:ಗExercise Answers

print;}

Answers to Chapter 10 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

my $secret = int(1 + rand 100);# This next line may be uncommented during debugging# print "Don't tell anyone, but the secret number is $secret.\n";

while (1) { print "Please enter a guess from 1 to 100: "; chomp(my $guess = <STDIN>); if ($guess =~ /quit|exit|^\s*$/i) { print "Sorry you gave up. The number was $secret.\n"; last; } elsif ($guess < $secret) { print "Too small. Try again!\n"; } elsif ($guess == $secret) { print "That was it!\n"; last; } else { print "Too large. Try again!\n"; }}

7KH�ILUVW�OLQH�SLFNV�RXW�RXU�VHFUHW�QXPEHU�IURP�1�WR�100��+HUH¦V�KRZ�LW�ZRUNV��)LUVW�rand�LV�3HUO¦V�UDQGRP�QXPEHU�IXQFWLRQ��VR�rand 100�JLYHV�XV�D�UDQGRP�QXPEHU�LQWKH�UDQJH�IURP���XS�WR��EXW�QRW�LQFOXGLQJ�������7KDW�LV��WKH�ODUJHVW�SRVVLEOH�YDOXHRI�WKDW�H[SUHVVLRQ�LV�VRPHWKLQJ�OLNH�99.999� �$GGLQJ�RQH�JLYHV�D�QXPEHU�IURP�1�WR100.999��WKHQ�WKH�int�IXQFWLRQ�WUXQFDWHV�WKDW��JLYLQJ�D�UHVXOW�IURP�1�WR�100��DV�ZHQHHGHG�

7KH�FRPPHQWHG�RXW�OLQH�FDQ�EH�KHOSIXO�GXULQJ�GHYHORSPHQW�DQG�GHEXJJLQJ��RU�LI\RX�OLNH�WR�FKHDW��7KH�PDLQ�ERG\�RI�WKLV�SURJUDP�LV�WKH�LQILQLWH�while�ORRS��7KDWZLOO�NHHS�DVNLQJ�IRU�JXHVVHV�XQWLO�ZH�H[HFXWH�last�

,W¦V�LPSRUWDQW�WKDW�ZH�WHVW�WKH�SRVVLEOH�VWULQJV�EHIRUH�WKH�QXPEHUV��,I�ZH�GLGQ¦W��GR\RX�VHH�ZKDW�ZRXOG�KDSSHQ�ZKHQ�WKH�XVHU�W\SHV�quit"�7KDW�ZRXOG�EH�LQWHUSUHWHGDV�D�QXPEHU��SUREDEO\�JLYLQJ�D�ZDUQLQJ�PHVVDJH��LI�ZDUQLQJV�ZHUH�WXUQHG�RQ���DQGVLQFH�WKH�YDOXH�DV�D�QXPEHU�ZRXOG�EH�]HUR��WKH�SRRU�XVHU�ZRXOG�JHW�WKH�PHVVDJHWKDW�KLV�JXHVV�ZDV�WRR�VPDOO��:H�PLJKW�QHYHU�JHW�WR�WKH�VWULQJ�WHVWV��LQ�WKDW�FDVH�

$QRWKHU�ZD\�WR�PDNH�WKH�LQILQLWH�ORRS�KHUH�ZRXOG�EH�WR�XVH�D�QDNHG�EORFN�ZLWKredo��,W¦V�QR�PRUH�RU�OHVV�HIILFLHQW��LW¦V�PHUHO\�DQRWKHU�ZD\�WR�ZULWH�LW��*HQHUDOO\��LI

7KH�DFWXDO�ODUJHVW�SRVVLEOH�YDOXH�GHSHQGV�XSRQ�\RXU�V\VWHP��VHH�KWWS���ZZZ�FSDQ�RUJ�GRF�)07(<(:7.�UDQGRP�LI�\RX�UHDOO\�QHHG�WR�NQRZ�

Answers to Chapter 10 Exercises | 277

\RX�H[SHFW�WR�PRVWO\�ORRS��LW¦V�JRRG�WR�ZULWH�while��VLQFH�WKDW�ORRSV�E\�GHIDXOW��,IORRSLQJ�ZLOO�EH�WKH�H[FHSWLRQ��D�QDNHG�EORFN�PD\�EH�D�EHWWHU�FKRLFH�

�� 7KLV�SURJUDP�LV�D�VOLJKW�PRGLILFDWLRQ�WR�WKH�SUHYLRXV�DQVZHU��:H�ZDQW�WR�SULQW�WKHVHFUHW�QXPEHU�ZKLOH�ZH�DUH�GHYHORSLQJ�WKH�SURJUDP��VR�ZH�print�WKH�VHFUHW�QXPEHULI�WKH�YDULDEOH�$Debug�KDV�D�WUXH�YDOXH��7KH�YDOXH�RI�$Debug�LV�HLWKHU�WKH�YDOXH�WKDWZH�DOUHDG\�VHW�DV�DQ�HQYLURQPHQW�YDULDEOH��RU�1�E\�GHIDXOW��%\�XVLQJ�WKH�//�RSHUDWRU�ZH�ZRQ¦W�VHW�LW�WR�1�XQOHVV�WKH�$ENV{DEBUG}�LV�XQGHILQHG�

use 5.010;

my $Debug = $ENV{DEBUG} // 1;

my $secret = int(1 + rand 100);

print "Don't tell anyone, but the secret number is $secret.\n" if $Debug;

7R�GR�WKLV�ZLWKRXW�D�3HUO������IHDWXUH��ZH�MXVW�KDYH�WR�GR�D�OLWWOH�PRUH�ZRUN�

my $Debug = defined $ENV{DEBUG} ? $ENV{DEBUG} : 1;

�� +HUH¦V�RQH�ZD\�WR�GR�LW��ZKLFK�VWHDOV�IURP�WKH�DQVZHU�WR�H[HUFLVH���LQ�&KDSWHU���

$W�WKH�WRS�RI�WKH�SURJUDP��ZH�VHW�VRPH�HQYLURQPHQW�YDULDEOHV��7KH�NH\V�ZERO�DQGEMPTY�KDYH�IDOVH�EXW�GHILQHG�YDOXHV��DQG�WKH�NH\�UNDEFINED�KDV�QR�YDOXH�

/DWHU�� LQ� WKH� printf� DUJXPHQW� OLVW�� ZH� XVH� WKH� //� RSHUDWRU� WR� VHOHFW� WKH� VWULQJ(undefined)�RQO\�ZKHQ�$ENV{$key}�LV�QRW�D�GHILQHG�YDOXH�

use 5.010;

$ENV{ZERO} = 0;$ENV{EMPTY} = '';$ENV{UNDEFINED} = undef;

my $longest = 0;foreach my $key ( keys %ENV ) { my $key_length = length( $key ); $longest = $key_length if $key_length > $longest; }

foreach my $key ( sort keys %ENV ) { printf "%-${longest}s %s\n", $key, $ENV{$key} // "(undefined)"; }

%\�XVLQJ�//�KHUH��ZH�GRQ¦W�GLVWXUE�IDOVH�YDOXHV�VXFK�DV�WKRVH�LQ�WKH�NH\V�ZERO�DQGEMPTY�

7R�GR�WKLV�ZLWKRXW�3HUO�������ZH�XVH�WKH�WHUQDU\�RSHUDWRU�LQVWHDG�

printf "%-${longest}s %s\n", $key, $ENV{$key} ? $ENV{$key} : "(undefined)";

278 | Appendix A:ಗExercise Answers

Answer to Chapter 11 Exercise�� 7KLV�DQVZHU�XVHV�D�KDVK�UHIHUHQFH��ZKLFK�\RX¦OO�KDYH�WR�UHDG�DERXW�LQ�,QWHUPHGLDWH

3HUO��2¦5HLOO\���EXW�ZH�JDYH�\RX�WKH�SDUW�WR�JHW�DURXQG�WKDW��<RX�GRQ¦W�KDYH�WRNQRZ�KRZ�LW�DOO�ZRUNV�DV�ORQJ�DV�\RX�NQRZ�LW�GRHV�ZRUN��<RX�FDQ�JHW�WKH�MRE�GRQHDQG�OHDUQ�WKH�GHWDLOV�ODWHU�

+HUH¦V�RQH�ZD\�WR�GR�LW�

#!/usr/bin/perl

use Module::CoreList;

my %modules = %{ $Module::CoreList::version{5.006} };

print join "\n", keys %modules;

Answers to Chapter 12 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

foreach my $file (@ARGV) { my $attribs = &attributes($file); print "'$file' $attribs.\n";}

sub attributes { # report the attributes of a given file my $file = shift @_; return "does not exist" unless -e $file;

my @attrib; push @attrib, "readable" if -r $file; push @attrib, "writable" if -w $file; push @attrib, "executable" if -x $file; return "exists" unless @attrib; 'is ' . join " and ", @attrib; # return value}

,Q�WKLV�RQH��RQFH�DJDLQ�LW¦V�FRQYHQLHQW�WR�XVH�D�VXEURXWLQH��7KH�PDLQ�ORRS�SULQWVRQH� OLQH� RI� DWWULEXWHV� IRU� HDFK� ILOH�� SHUKDSV� WHOOLQJ� XV� WKDW� 'cereal-killer' LVH[HFXWDEOH�RU�WKDW�'sasquatch' GRHV�QRW�H[LVW�

7KH�VXEURXWLQH�WHOOV�XV�WKH�DWWULEXWHV�RI�WKH�JLYHQ�ILOHQDPH��2I�FRXUVH��LI�WKH�ILOHGRHVQ¦W�HYHQ�H[LVW��WKHUH¦V�QR�QHHG�IRU�WKH�RWKHU�WHVWV��VR�ZH�WHVW�IRU�WKDW�ILUVW��,IWKHUH¦V�QR�ILOH��ZH¦OO�UHWXUQ�HDUO\�

,I�WKH�ILOH�GRHV�H[LVW��ZH¦OO�EXLOG�D�OLVW�RI�DWWULEXWHV���*LYH�\RXUVHOI�H[WUD�FUHGLW�SRLQWVLI�\RX�XVHG�WKH�VSHFLDO�_�ILOHKDQGOH�LQVWHDG�RI�$file�RQ�WKHVH�WHVWV��WR�NHHS�IURPFDOOLQJ�WKH�V\VWHP�VHSDUDWHO\�IRU�HDFK�QHZ�DWWULEXWH���,W�ZRXOG�EH�HDV\�WR�DGG�DG�GLWLRQDO�WHVWV�OLNH�WKH�WKUHH�ZH�VKRZ�KHUH��%XW�ZKDW�KDSSHQV�LI�QRQH�RI�WKH�DWWULEXWHVLV�WUXH"�:HOO��LI�ZH�FDQ¦W�VD\�DQ\WKLQJ�HOVH��DW�OHDVW�ZH�FDQ�VD\�WKDW�WKH�ILOH�H[LVWV�

Answer to Chapter 11 Exercise | 279

VR�ZH�GR��7KH�unless�FODXVH�XVHV�WKH�IDFW�WKDW�@attrib�ZLOO�EH�WUXH��LQ�D�%RROHDQFRQWH[W��ZKLFK�LV�D�VSHFLDO�FDVH�RI�D�VFDODU�FRQWH[W��LI�LW¦V�JRW�DQ\�HOHPHQWV�

%XW�LI�ZH¦YH�JRW�VRPH�DWWULEXWHV��ZH¦OO�MRLQ�WKHP�ZLWK�"and"�DQG�SXW�"is "�LQ�IURQW�WR�PDNH�D�GHVFULSWLRQ�OLNH�is readable and writable��7KLV�LVQ¦W�SHUIHFW�KRZHYHU�LI� WKHUH� DUH� WKUHH� DWWULEXWHV�� LW� VD\V� WKDW� WKH� ILOH�is readable and writable andexecutable��ZKLFK�KDV�WRR�PDQ\�andV��EXW�ZH�FDQ�JHW�DZD\�ZLWK�LW��,I�\RX�ZDQWHGWR�DGG�PRUH�DWWULEXWHV�WR�WKH�RQHV�WKLV�SURJUDP�FKHFNV�IRU��\RX�VKRXOG�SUREDEO\IL[�LW�WR�VD\�VRPHWKLQJ�OLNH�is readable, writable, executable, and nonempty��,IWKDW�PDWWHUV�WR�\RX�

1RWH�WKDW� LI�\RX�VRPHKRZ�GLGQ¦W�SXW�DQ\� ILOHQDPHV�RQ�WKH�FRPPDQG�OLQH�� WKLVSURGXFHV�QR�RXWSXW��7KLV�PDNHV�VHQVH��LI�\RX�DVN�IRU�LQIRUPDWLRQ�RQ�]HUR�ILOHV��\RXVKRXOG�JHW�]HUR�OLQHV�RI�RXWSXW��%XW�OHW¦V�FRPSDUH�WKDW�WR�ZKDW�WKH�QH[W�SURJUDPGRHV�LQ�D�VLPLODU�FDVH��LQ�WKH�GLVFXVVLRQ�EHORZ�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

die "No file names supplied!\n" unless @ARGV;my $oldest_name = shift @ARGV;my $oldest_age = -M $oldest_name;

foreach (@ARGV) { my $age = -M; ($oldest_name, $oldest_age) = ($_, $age) if $age > $oldest_age;}

printf "The oldest file was %s, and it was %.1f days old.\n", $oldest_name, $oldest_age;

7KLV�RQH�VWDUWV�ULJKW�RXW�E\�FRPSODLQLQJ�LI�LW�GLGQ¦W�JHW�DQ\�ILOHQDPHV�RQ�WKH�FRP�PDQG�OLQH��7KDW¦V�EHFDXVH�LW¦V�VXSSRVHG�WR�WHOO�XV�WKH�ROGHVW�ILOHQDPH¢DQG�WKHUHDLQ¦W�RQH�LI�WKHUH�DUHQ¦W�DQ\�ILOHV�WR�FKHFN�

2QFH�DJDLQ��ZH¦UH�XVLQJ�WKH�£KLJK�ZDWHU�PDUN¤�DOJRULWKP��7KH�ILUVW�ILOH�LV�FHUWDLQO\WKH�ROGHVW�RQH�VHHQ�VR�IDU��:H�KDYH�WR�NHHS�WUDFN�RI�LWV�DJH�DV�ZHOO��VR�WKDW¦V�LQ$oldest_age�

)RU�HDFK�RI�WKH�UHPDLQLQJ�ILOHV��ZH¦OO�GHWHUPLQH�WKH�DJH�ZLWK�WKH�-M�ILOH�WHVW��MXVW�DVZH�GLG�IRU�WKH�ILUVW�RQH��H[FHSW�WKDW�KHUH��ZH¦OO�XVH�WKH�GHIDXOW�DUJXPHQW�RI�$_�IRUWKH�ILOH�WHVW���7KH�ODVW�PRGLILHG�WLPH�LV�JHQHUDOO\�ZKDW�SHRSOH�PHDQ�E\�WKH�£DJH¤�RID�ILOH��DOWKRXJK�\RX�FRXOG�PDNH�D�FDVH�IRU�XVLQJ�D�GLIIHUHQW�RQH��,I�WKH�DJH�LV�PRUHWKDQ�$oldest_age��ZH¦OO�XVH�D�OLVW�DVVLJQPHQW�WR�XSGDWH�ERWK�WKH�QDPH�DQG�DJH��:HGLGQ¦W�KDYH�WR�XVH�D�OLVW�DVVLJQPHQW��EXW�LW¦V�D�FRQYHQLHQW�ZD\�WR�XSGDWH�VHYHUDOYDULDEOHV�DW�RQFH�

:H�VWRUHG�WKH�DJH�IURP�-M� LQWR�WKH�WHPSRUDU\�YDULDEOH�$age��:KDW�ZRXOG�KDYHKDSSHQHG�LI�ZH�KDG�VLPSO\�XVHG�-M�HDFK�WLPH��UDWKHU�WKDQ�XVLQJ�D�YDULDEOH"�:HOO�ILUVW��XQOHVV�ZH�XVHG�WKH�VSHFLDO�_�ILOHKDQGOH��ZH�ZRXOG�KDYH�EHHQ�DVNLQJ�WKH�RS�HUDWLQJ�V\VWHP�IRU�WKH�DJH�RI�WKH�ILOH�HDFK�WLPH��D�SRWHQWLDOO\�VORZ�RSHUDWLRQ��QRW

280 | Appendix A:ಗExercise Answers

WKDW�\RX¦G�QRWLFH�XQOHVV�\RX�KDYH�KXQGUHGV�RU�WKRXVDQGV�RI�ILOHV��DQG�PD\EH�QRWHYHQ�WKHQ���0RUH�LPSRUWDQWO\��WKRXJK��ZH�VKRXOG�FRQVLGHU�ZKDW�ZRXOG�KDSSHQ�LIVRPHRQH�XSGDWHG�D�ILOH�ZKLOH�ZH�ZHUH�FKHFNLQJ�LW��7KDW�LV��ILUVW�ZH�VHH�WKH�DJH�RIVRPH�ILOH��DQG�LW¦V�WKH�ROGHVW�RQH�VHHQ�VR�IDU��%XW�EHIRUH�ZH�FDQ�JHW�EDFN�WR�XVH�-MD�VHFRQG�WLPH��VRPHRQH�PRGLILHV�WKH�ILOH�DQG�UHVHWV�WKH�WLPHVWDPS�WR�WKH�FXUUHQWWLPH��1RZ�WKH�DJH�WKDW�ZH�VDYH�LQWR�$oldest_age�LV�DFWXDOO\�WKH�\RXQJHVW�DJH�SRV�VLEOH��7KH�UHVXOW�ZRXOG�EH�WKDW�ZH¦G�JHW�WKH�ROGHVW�ILOH�DPRQJ�WKH�ILOHV�WHVWHG�IURPWKDW�SRLQW�RQ��UDWKHU�WKDQ�WKH�ROGHVW�RYHUDOO�� WKLV�ZRXOG�EH�D�WRXJK�SUREOHP�WRGHEXJ�

)LQDOO\��DW�WKH�HQG�RI�WKH�SURJUDP��ZH�XVH�printf�WR�SULQW�RXW�WKH�QDPH�DQG�DJH�ZLWK�WKH�DJH�URXQGHG�RII�WR�WKH�QHDUHVW�WHQWK�RI�D�GD\��*LYH�\RXUVHOI�H[WUD�FUHGLW�LI\RX�ZHQW�WR�WKH�WURXEOH�WR�FRQYHUW�WKH�DJH�WR�D�QXPEHU�RI�GD\V��KRXUV��DQG�PLQXWHV�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

use 5.010;

say "Looking for my files that are readable and writable";

die "No files specified!\n" unless @ARGV;

foreach my $file ( @ARGV ) { say "$file is readable and writable" if -o -r -w $file; }

7R�XVH�VWDFNHG�ILOH�WHVW�RSHUDWRUV��ZH�QHHG�WR�XVH�3HUO�������VR�ZH�VWDUW�ZLWK�WKHuse�VWDWHPHQW�WR�HQVXUH�WKDW�ZH�KDYH�WKH�ULJKW�YHUVLRQ�RI�3HUO��:H�die�LI�WKHUH�DUHQR�HOHPHQWV�LQ�@ARGV��DQG�JR�WKURXJK�WKHP�ZLWK�foreach�RWKHUZLVH�

:H�KDYH�WR�XVH�WKUHH�ILOH�WHVW�RSHUDWRUV��-o�WR�FKHFN�ZKHWKHU�ZH�RZQ�WKH�ILOH��-r�WRFKHFN�WKDW�LW¦V�UHDGDEOH��DQG�-w�WR�FKHFN�ZKHWKHU�LW�LV�ZULWDEOH��6WDFNLQJ�WKHP�DV�-o -r -w�FUHDWHV�D�FRPSRVLWH�WHVW�WKDW�RQO\�SDVVHV�LI�DOO�WKUHH�RI�WKHP�DUH�WUXH��ZKLFKLV�H[DFWO\�ZKDW�ZH�ZDQW�

,I�ZH�ZDQWHG�WR�GR�WKLV�ZLWK�D�YHUVLRQ�EHIRUH�3HUO�������LW¦V�MXVW�D�OLWWOH�PRUH�FRGH�7KH�sayV�EHFRPH�printV�ZLWK�DGGHG�QHZOLQHV��DQG�WKH�VWDFNHG�ILOH�WHVWV�EHFRPHVHSDUDWH�WHVWV�FRPELQHG�ZLWK�WKH�&&�VKRUW�FLUFXLW�RSHUDWRU�

print "Looking for my files that are readable and writable\n";

die "No files specified!\n" unless @ARGV;

foreach my $file ( @ARGV ) { print "$file is readable and writable\n" if( -w $file && -r _ && -o _ ); }

Answers to Chapter 12 Exercises | 281

Answers to Chapter 13 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW��ZLWK�D�JORE�

print "Which directory? (Default is your home directory) ";chomp(my $dir = <STDIN>);if ($dir =~ /^\s*$/) { # A blank line chdir or die "Can't chdir to your home directory: $!";} else { chdir $dir or die "Can't chdir to '$dir': $!";}

my @files = <*>;foreach (@files) { print "$_\n";}

)LUVW��ZH�VKRZ�D�VLPSOH�SURPSW�DQG�UHDG�WKH�GHVLUHG�GLUHFWRU\��FKRPSLQJ�LW�DVQHHGHG���:LWKRXW�D�FKRPS��ZH¦G�EH�WU\LQJ�WR�KHDG�IRU�D�GLUHFWRU\�WKDW�HQGV�LQ�DQHZOLQH¢OHJDO�LQ�8QL[��DQG�WKHUHIRUH�FDQQRW�EH�SUHVXPHG�WR�VLPSO\�EH�H[WUDQHRXVE\�WKH�chdir�IXQFWLRQ��

7KHQ��LI�WKH�GLUHFWRU\�QDPH�LV�QRQHPSW\��ZH¦OO�FKDQJH�WR�WKDW�GLUHFWRU\��DERUWLQJRQ�D�IDLOXUH��,I�HPSW\��WKH�KRPH�GLUHFWRU\�LV�VHOHFWHG�LQVWHDG�

)LQDOO\��D�JORE�RQ�£VWDU¤�SXOOV�XS�DOO�WKH�QDPHV�LQ�WKH��QHZ��ZRUNLQJ�GLUHFWRU\�DXWRPDWLFDOO\�VRUWHG�LQ�DOSKDEHWLFDO�RUGHU��DQG�WKH\¦UH�SULQWHG�RQH�DW�D�WLPH�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

print "Which directory? (Default is your home directory) ";chomp(my $dir = <STDIN>);if ($dir =~ /^\s*$/) { # A blank line chdir or die "Can't chdir to your home directory:$!";} else { chdir $dir or die "Can't chdir to '$dir': $!";}

my @files = <.* *>; ## now includes .*foreach (sort @files) { ## now sorts print "$_\n";}

7ZR�GLIIHUHQFHV�IURP�WKH�SUHYLRXV�RQH�� ILUVW�� WKH�JORE�QRZ�LQFOXGHV�£GRW�VWDU¤�ZKLFK�PDWFKHV�DOO�WKH�QDPHV�WKDW�GR�EHJLQ�ZLWK�D�GRW��$QG�VHFRQG��ZH�QRZ�PXVWVRUW�WKH�UHVXOWLQJ�OLVW�EHFDXVH�VRPH�RI�WKH�QDPHV�WKDW�EHJLQ�ZLWK�D�GRW�PXVW�EHLQWHUOHDYHG�DSSURSULDWHO\��HLWKHU�EHIRUH�RU�DIWHU�WKH�OLVW�RI�WKLQJV��ZLWKRXW�D�EHJLQ�QLQJ�GRW�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

print "Which directory? (Default is your home directory) ";chomp(my $dir = <STDIN>);if ($dir =~ /^\s*$/) { # A blank line

282 | Appendix A:ಗExercise Answers

chdir or die "Can't chdir to your home directory:$!";} else { chdir $dir or die "Can't chdir to '$dir': $!";}

opendir DOT, "." or die "Can't opendir dot: $!";foreach (sort readdir DOT) { # next if /^\./; ## if we were skipping dot files print "$_\n";}

$JDLQ��VDPH�VWUXFWXUH�DV�WKH�SUHYLRXV�WZR�SURJUDPV��EXW�QRZ�ZH¦YH�FKRVHQ�WR�RSHQD�GLUHFWRU\�KDQGOH��2QFH�ZH¦YH�FKDQJHG�WKH�ZRUNLQJ�GLUHFWRU\��ZH�ZDQW�WR�RSHQWKH�FXUUHQW�GLUHFWRU\��DQG�ZH¦YH�VKRZQ�WKDW�DV�WKH�DOT�GLUHFWRU\�KDQGOH�

:K\�DOT"�:HOO��LI�WKH�XVHU�DVNV�IRU�DQ�DEVROXWH�GLUHFWRU\�QDPH��OLNH�/etc��WKHUH¦VQR�SUREOHP�RSHQLQJ�LW��%XW�LI�WKH�QDPH�LV�UHODWLYH��OLNH�fred��OHW¦V�VHH�ZKDW�ZRXOGKDSSHQ��)LUVW��ZH�chdir�WR�fred��DQG�WKHQ�ZH�ZDQW�WR�XVH�opendir�WR�RSHQ�LW��%XWWKDW�ZRXOG�RSHQ�fred�LQ�WKH�QHZ�GLUHFWRU\��QRW�fred�LQ�WKH�RULJLQDO�GLUHFWRU\��7KHRQO\�QDPH�ZH�FDQ�EH�VXUH�ZLOO�PHDQ�£WKH�FXUUHQW�GLUHFWRU\¤�LV�£.¤��ZKLFK�DOZD\VKDV�WKDW�PHDQLQJ��RQ�8QL[�DQG�VLPLODU�V\VWHPV��DW�OHDVW��

7KH�readdir�IXQFWLRQ�SXOOV�XS�DOO�WKH�QDPHV�RI�WKH�GLUHFWRU\��ZKLFK�DUH�WKHQ�VRUWHGDQG�GLVSOD\HG��,I�ZH�KDG�GRQH�WKH�ILUVW�H[HUFLVH�WKLV�ZD\��ZH�ZRXOG�KDYH�VNLSSHGRYHU�WKH�GRW�ILOHV��DQG�WKDW¦V�KDQGOHG�E\�XQFRPPHQWLQJ�WKH�FRPPHQWHG�RXW�OLQHLQ�WKH�foreach�ORRS�

<RX�PD\�ILQG�\RXUVHOI�DVNLQJ��£:K\�GLG�ZH�chdir�ILUVW"�<RX�FDQ�XVH�readdir�DQGIULHQGV�RQ�DQ\�GLUHFWRU\��QRW�PHUHO\�RQ�WKH�FXUUHQW�GLUHFWRU\�¤�3ULPDULO\��ZH�ZDQWHGWR�JLYH�XVHUV�WKH�FRQYHQLHQFH�RI�EHLQJ�DEOH�WR�JHW�WR�WKHLU�KRPH�GLUHFWRU\�ZLWK�DVLQJOH�NH\VWURNH��%XW�WKLV�FRXOG�EH�WKH�VWDUW�RI�D�JHQHUDO�ILOH�PDQDJHPHQW�XWLOLW\SURJUDP��PD\EH�WKH�QH[W�VWHS�ZRXOG�EH�WR�DVN�WKH�XVHUV�ZKLFK�RI�WKH�ILOHV�LQ�WKLVGLUHFWRU\�VKRXOG�EH�PRYHG�WR�RIIOLQH�WDSH�VWRUDJH��VD\�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

unlink @ARGV;

�RU��LI�\RX�ZDQW�WR�ZDUQ�WKH�XVHU�RI�DQ\�SUREOHPV�

foreach (@ARGV) { unlink $_ or warn "Can't unlink '$_': $!, continuing...\n";}

+HUH��HDFK�LWHP�IURP�WKH�FRPPDQG�LQYRFDWLRQ�OLQH�LV�SODFHG�LQGLYLGXDOO\�LQWR�$_�ZKLFK�LV�WKHQ�XVHG�DV�WKH�DUJXPHQW�WR�unlink��,I�VRPHWKLQJ�JRHV�ZURQJ��WKH�ZDUQLQJJLYHV�WKH�FOXH�DERXW�ZK\�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

use File::Basename;use File::Spec;

Answers to Chapter 13 Exercises | 283

my($source, $dest) = @ARGV;

if (-d $dest) { my $basename = basename $source; $dest = File::Spec->catfile($dest, $basename);}

rename $source, $dest or die "Can't rename '$source' to '$dest': $!\n";

7KH�ZRUNKRUVH� LQ� WKLV�SURJUDP� LV� WKH� ODVW� VWDWHPHQW��EXW� WKH� UHPDLQGHU�RI� WKHSURJUDP�LV�QHFHVVDU\�ZKHQ�ZH�DUH�UHQDPLQJ�LQWR�D�GLUHFWRU\��)LUVW��DIWHU�GHFODULQJWKH� PRGXOHV� ZH¦UH� XVLQJ�� ZH� QDPH� WKH� FRPPDQG�OLQH� DUJXPHQWV� VHQVLEO\�� ,I$dest�LV�D�GLUHFWRU\��ZH�QHHG�WR�H[WUDFW�WKH�EDVHQDPH�IURP�WKH�$source�QDPH�DQGDSSHQG�LW�WR�WKH�GLUHFWRU\��$dest���)LQDOO\��RQFH�$dest�LV�SDWFKHG�XS�LI�QHHGHG��WKHrename�GRHV�WKH�GHHG�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

use File::Basename;use File::Spec;

my($source, $dest) = @ARGV;

if (-d $dest) { my $basename = basename $source; $dest = File::Spec->catfile($dest, $basename);}

link $source, $dest or die "Can't link '$source' to '$dest': $!\n";

$V�WKH�KLQW�LQ�WKH�H[HUFLVH�GHVFULSWLRQ�VDLG��WKLV�SURJUDP�LV�PXFK�OLNH�WKH�SUHYLRXVRQH��7KH�GLIIHUHQFH�LV�WKDW�ZH¦OO�link�UDWKHU�WKDQ�rename��,I�\RXU�V\VWHP�GRHVQ¦WVXSSRUW�KDUG�OLQNV��\RX�PLJKW�KDYH�ZULWWHQ�WKLV�DV�WKH�ODVW�VWDWHPHQW�

print "Would link '$source' to '$dest'.\n";

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

use File::Basename;use File::Spec;

my $symlink = $ARGV[0] eq '-s';shift @ARGV if $symlink;

my($source, $dest) = @ARGV;if (-d $dest) { my $basename = basename $source; $dest = File::Spec->catfile($dest, $basename);}

if ($symlink) { symlink $source, $dest or die "Can't make soft link from '$source' to '$dest': $!\n";} else {

284 | Appendix A:ಗExercise Answers

link $source, $dest or die "Can't make hard link from '$source' to '$dest': $!\n";}

7KH�ILUVW�IHZ�OLQHV�RI�FRGH��DIWHU�WKH�WZR�use�GHFODUDWLRQV��ORRN�DW�WKH�ILUVW�FRPPDQG�OLQH�DUJXPHQW��DQG�LI�LW¦V�-s��ZH¦UH�PDNLQJ�D�V\PEROLF�OLQN��VR�ZH�QRWH�WKDW�DV�D�WUXHYDOXH�IRU�$symlink��,I�ZH�VHH�-s��ZH�WKHQ�QHHG�WR�JHW�ULG�RI�LW��LQ�WKH�QH[W�OLQH���7KHQH[W�IHZ�OLQHV�DUH�FXW�DQG�SDVWHG�IURP�WKH�SUHYLRXV�H[HUFLVH�DQVZHUV��)LQDOO\��EDVHGRQ�WKH�WUXWK�RI�$symlink��ZH¦OO�FKRRVH�HLWKHU�WR�FUHDWH�D�V\PEROLF�OLQN�RU�D�KDUG�OLQN�:H�DOVR�XSGDWHG�WKH�G\LQJ�ZRUGV� WR�PDNH� LW�FOHDU�ZKLFK�NLQG�RI� OLQN�ZH�ZHUHDWWHPSWLQJ�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

foreach (<.* *>) { my $dest = readlink $_; print "$_ -> $dest\n" if defined $dest;}

(DFK�LWHP�UHVXOWLQJ�IURP�WKH�JORE�HQGV�XS�LQ�$_�RQH�E\�RQH��,I�WKH�LWHP�LV�D�V\PEROLFOLQN��WKHQ�readlink�UHWXUQV�D�GHILQHG�YDOXH��DQG�WKH�ORFDWLRQ�LV�GLVSOD\HG��,I�QRW�WKHQ�WKH�FRQGLWLRQ�IDLOV��DQG�ZH�VNLS�RYHU�LW�

Answers to Chapter 14 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

my @numbers;push @numbers, split while <>;foreach (sort { $a <=> $b } @numbers) { printf "%20g\n", $_;}

7KDW�VHFRQG�OLQH�RI�FRGH�LV�WRR�FRQIXVLQJ��LVQ¦W�LW"�:HOO��ZH�GLG�WKDW�RQ�SXUSRVH�$OWKRXJK�ZH�UHFRPPHQG�WKDW�\RX�ZULWH�FOHDU�FRGH��VRPH�SHRSOH�OLNH�ZULWLQJ�FRGHWKDW¦V�DV�KDUG�WR�XQGHUVWDQG�DV�SRVVLEOH� �VR�ZH�ZDQW�\RX�WR�EH�SUHSDUHG�IRU�WKHZRUVW��6RPHGD\��\RX¦OO�QHHG�WR�PDLQWDLQ�FRQIXVLQJ�FRGH�OLNH�WKLV�

6LQFH�WKDW�OLQH�XVHV�WKH�while�PRGLILHU��LW¦V�WKH�VDPH�DV�LI�LW�ZHUH�ZULWWHQ�LQ�D�ORRSOLNH�WKLV�

while (<>) { push @numbers, split;}

:HOO��ZH�GRQ¦W�UHFRPPHQG�LW�IRU�QRUPDO�FRGLQJ�SXUSRVHV��EXW�LW�FDQ�EH�D�IXQ�JDPH�WR�ZULWH�FRQIXVLQJ�FRGH�DQG�LW�FDQ�EH�HGXFDWLRQDO�WR�WDNH�VRPHRQH�HOVH¦V�REIXVFDWHG�FRGH�H[DPSOHV�DQG�VSHQG�D�ZHHNHQG�RU�WZRILJXULQJ�RXW�MXVW�ZKDW�WKH\�GR��,I�\RX�ZDQW�WR�VHH�VRPH�IXQ�VQLSSHWV�RI�VXFK�FRGH�DQG�PD\EH�JHW�D�OLWWOH�KHOSZLWK�GHFRGLQJ�WKHP��DVN�DURXQG�DW�WKH�QH[W�3HUO�0RQJHUV¦�PHHWLQJ��2U�VHDUFK�IRU�-$3+V�RQ�WKH�:HE��RU�VHHKRZ�ZHOO�\RX�FDQ�GHFLSKHU�WKH�H[DPSOH�REIXVFDWHG�FRGH�EORFN�QHDU�WKH�HQG�RI�WKLV�FKDSWHU¦V�DQVZHUV�

Answers to Chapter 14 Exercises | 285

7KDW¦V�EHWWHU��EXW�PD\EH�LW¦V�VWLOO�D�OLWWOH�XQFOHDU���1HYHUWKHOHVV��ZH�GRQ¦W�KDYH�DTXLEEOH�DERXW�ZULWLQJ�LW�WKLV�ZD\��7KLV�RQH�LV�RQ�WKH�FRUUHFW�VLGH�RI�WKH�£WRR�KDUGWR�XQGHUVWDQG�DW�D�JODQFH¤�OLQH���7KH�while�ORRS�LV�UHDGLQJ�WKH�LQSXW�D�OLQH�DW�D�WLPH�IURP�WKH�XVHU¦V�FKRLFH�RI�LQSXW�VRXUFHV��DV�VKRZQ�E\�WKH�GLDPRQG�RSHUDWRU���DQGsplit�LV��E\�GHIDXOW��VSOLWWLQJ�WKDW�RQ�ZKLWHVSDFH�WR�PDNH�D�OLVW�RI�ZRUGV¢RU��LQWKLV�FDVH��D�OLVW�RI�QXPEHUV��7KH�LQSXW�LV�MXVW�D�VWUHDP�RI�QXPEHUV�VHSDUDWHG�E\ZKLWHVSDFH��DIWHU�DOO��(LWKHU�ZD\�WKDW�\RX�ZULWH�LW��WKHQ��WKDW�while�ORRS�ZLOO�SXW�DOORI�WKH�QXPEHUV�IURP�WKH�LQSXW�LQWR�@numbers�

7KH�foreach�ORRS�WDNHV�WKH�VRUWHG�OLVW�DQG�SULQWV�HDFK�RQH�RQ�LWV�RZQ�OLQH��XVLQJWKH�%20g�QXPHULF�IRUPDW�WR�SXW�WKHP�LQ�D�ULJKW�MXVWLILHG�FROXPQ��<RX�FRXOG�KDYHXVHG�%20s�LQVWHDG��:KDW�GLIIHUHQFH�ZRXOG�WKDW�PDNH"�:HOO��WKDW¦V�D�VWULQJ�IRUPDW�VR�LW�ZRXOG�KDYH�OHIW�WKH�VWULQJV�XQWRXFKHG�LQ�WKH�RXWSXW��'LG�\RX�QRWLFH�WKDW�RXUVDPSOH�GDWD�LQFOXGHG�ERWK�1.50�DQG�1.5��DQG�ERWK�04�DQG�4"�,I�\RX�SULQWHG�WKRVHDV�VWULQJV��WKH�H[WUD�]HUR�FKDUDFWHUV�ZLOO�VWLOO�EH�LQ�WKH�RXWSXW��EXW�%20g�LV�D�QXPHULFIRUPDW��VR�HTXDO�QXPEHUV�ZLOO�DSSHDU�LGHQWLFDOO\�LQ�WKH�RXWSXW��(LWKHU�IRUPDW�FRXOGSRWHQWLDOO\�EH�FRUUHFW��GHSHQGLQJ�XSRQ�ZKDW�\RX¦UH�WU\LQJ�WR�GR�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

# don't forget to incorporate the hash %last_name,# either from the exercise text or the downloaded file

my @keys = sort { "\L$last_name{$a}" cmp "\L$last_name{$b}" # by last name or "\L$a" cmp "\L$b" # by first name} keys %last_name;

foreach (@keys) { print "$last_name{$_}, $_\n"; # Rubble,Bamm-Bamm}

7KHUH¦V�QRW�PXFK�WR�VD\�DERXW�WKLV�RQH��ZH�SXW�WKH�NH\V�LQ�RUGHU�DV�QHHGHG��WKHQSULQW�WKHP�RXW��:H�FKRVH�WR�SULQW�WKHP�LQ�ODVW�QDPH�FRPPD�ILUVW�QDPH�RUGHU�MXVWIRU�IXQ��WKH�H[HUFLVH�GHVFULSWLRQ�OHIW�WKDW�XS�WR�\RX��

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

print "Please enter a string: ";chomp(my $string = <STDIN>);print "Please enter a substring: ";chomp(my $sub = <STDIN>);

my @places;

for (my $pos = !1; ; ) { # tricky use of three-part for loop $pos = index($string, $sub, $pos + 1); # find next position last if $pos == !1; push @places, $pos;}

print "Locations of '$sub' in '$string' were: @places\n";

286 | Appendix A:ಗExercise Answers

7KLV�RQH�VWDUWV�RXW�VLPSO\�HQRXJK��DVNLQJ�WKH�XVHU�IRU�WKH�VWULQJV�DQG�GHFODULQJ�DQDUUD\�WR�KROG�WKH�OLVW�RI�VXEVWULQJ�SRVLWLRQV��%XW�RQFH�DJDLQ��DV�ZH�VHH�LQ�WKH�forORRS��WKH�FRGH�VHHPV�WR�KDYH�EHHQ�£RSWLPL]HG�IRU�FOHYHUQHVV�¤�ZKLFK�VKRXOG�EHGRQH�RQO\�IRU�IXQ��QHYHU�LQ�SURGXFWLRQ�FRGH��%XW�WKLV�DFWXDOO\�VKRZV�D�YDOLG�WHFK�QLTXH��ZKLFK�FRXOG�EH�XVHIXO�LQ�VRPH�FDVHV��VR�OHW¦V�VHH�KRZ�LW�ZRUNV�

7KH�my�YDULDEOH�$pos�LV�GHFODUHG�SULYDWH�WR�WKH�VFRSH�RI�WKH�for�ORRS��DQG�LW�VWDUWVZLWK�D�YDOXH�RI�!1��6R�DV�QRW�WR�NHHS�\RX�LQ�VXVSHQVH�DERXW�WKLV�YDULDEOH��ZH¦OO�WHOO\RX�ULJKW�QRZ�WKDW�LW¦V�JRLQJ�WR�KROG�D�SRVLWLRQ�RI�WKH�VXEVWULQJ�LQ�WKH�ODUJHU�VWULQJ�7KH�WHVW�DQG�LQFUHPHQW�VHFWLRQV�RI�WKH�for�ORRS�DUH�HPSW\��VR�WKLV�LV�DQ�LQILQLWHORRS���2I�FRXUVH��ZH¦OO�HYHQWXDOO\�EUHDN�RXW�RI�LW��LQ�WKLV�FDVH�ZLWK�last��

7KH�ILUVW�VWDWHPHQW�RI�WKH�ORRS�ERG\�ORRNV�IRU�WKH�ILUVW�RFFXUUHQFH�RI�WKH�VXEVWULQJDW�RU�DIWHU�SRVLWLRQ�$pos + 1��7KDW�PHDQV�WKDW�RQ�WKH�ILUVW�LWHUDWLRQ��ZKHQ�$pos�LVVWLOO�!1��WKH�VHDUFK�ZLOO�VWDUW�DW�SRVLWLRQ�0��WKH�VWDUW�RI�WKH�VWULQJ��7KH�ORFDWLRQ�RI�WKHVXEVWULQJ�LV�VWRUHG�EDFN�LQWR�$pos��1RZ��LI�WKDW�ZDV�!1��ZH¦UH�GRQH�ZLWK�WKH�forORRS��VR�last�EUHDNV�RXW�RI�WKH�ORRS�LQ�WKDW�FDVH��,I�LW�ZDVQ¦W�!1��WKHQ�ZH�VDYH�WKHSRVLWLRQ�LQWR�@places�DQG�JR�DURXQG�WKH�ORRS�DJDLQ��7KLV�WLPH��$pos + 1�PHDQVWKDW�ZH¦OO� VWDUW� ORRNLQJ� IRU� WKH�VXEVWULQJ� MXVW�DIWHU� WKH�SUHYLRXV�SODFH�ZKHUH�ZHIRXQG�LW��$QG�VR�ZH�JHW�WKH�DQVZHUV�ZH�ZDQWHG�DQG�WKH�ZRUOG�LV�RQFH�DJDLQ�D�KDSS\SODFH�

,I�\RX�GLGQ¦W�ZDQW�WKDW�WULFN\�XVH�RI�WKH�for�ORRS��\RX�FRXOG�DFFRPSOLVK�WKH�VDPHUHVXOW�DV�VKRZQ�KHUH�

{ my $pos = !1; while (1) { ... # Same loop body as the for loop used above }}

7KH�QDNHG�EORFN�RQ�WKH�RXWVLGH�UHVWULFWV�WKH�VFRSH�RI�$pos��<RX�GRQ¦W�KDYH�WR�GRWKDW��EXW� LW¦V�RIWHQ�D�JRRG�LGHD�WR�GHFODUH�HDFK�YDULDEOH� LQ�WKH�VPDOOHVW�SRVVLEOHVFRSH��7KLV�PHDQV�ZH�KDYH�IHZHU�YDULDEOHV�£DOLYH¤�DW�DQ\�JLYHQ�SRLQW�LQ�WKH�SUR�JUDP��PDNLQJ�LW�OHVV�OLNHO\�WKDW�ZH¦OO�DFFLGHQWDOO\�UHXVH�WKH�QDPH�$pos�IRU�VRPH�QHZSXUSRVH��)RU�WKH�VDPH�UHDVRQ��LI�\RX�GRQ¦W�GHFODUH�D�YDULDEOH�LQ�D�VPDOO�VFRSH��\RXVKRXOG�JHQHUDOO\�JLYH�LW�D� ORQJHU�QDPH�WKDW¦V�WKHUHE\�OHVV� OLNHO\�WR�EH�UHXVHG�E\DFFLGHQW��0D\EH�VRPHWKLQJ�OLNH�$substring_position�ZRXOG�EH�DSSURSULDWH�LQ�WKLVFDVH�

2Q�WKH�RWKHU�KDQG��LI�\RX�ZHUH�WU\LQJ�WR�REIXVFDWH�\RXU�FRGH��VKDPH�RQ�\RX����\RXFRXOG�FUHDWH�D�PRQVWHU�OLNH�WKLV��VKDPH�RQ�XV���

for (my $pos = !1; !1 != ($pos = index +$string, +$sub, +$pos +1 );

Answers to Chapter 14 Exercises | 287

push @places, ((((+$pos))))) { 'for ($pos != 1; # ;$pos++) { print "position $pos\n";#;';#' } pop @places;}

7KDW�HYHQ�WULFNLHU�FRGH�ZRUNV�LQ�SODFH�RI�WKH�RULJLQDO�WULFN\�for�ORRS��%\�QRZ��\RXVKRXOG�NQRZ�HQRXJK�WR�EH�DEOH�WR�GHFLSKHU�WKDW�RQH�RQ�\RXU�RZQ��RU�WR�REIXVFDWHFRGH�LQ�RUGHU�WR�DPD]H�\RXU�IULHQGV�DQG�FRQIRXQG�\RXU�HQHPLHV��%H�VXUH�WR�XVHWKHVH�SRZHUV�RQO\�IRU�JRRG��QHYHU�IRU�HYLO�

2K��DQG�ZKDW�GLG�\RX�JHW�ZKHQ�\RX�VHDUFKHG�IRU�t� LQ�This is a test."� ,W¦V�DWSRVLWLRQV�10�DQG�13��,W¦V�QRW�DW�SRVLWLRQ�0��VLQFH�WKH�FDSLWDOL]DWLRQ�GRHVQ¦W�PDWFK�WKH�VXEVWULQJ�GRHVQ¦W�PDWFK�

Answers to Chapter 15 Exercises�� +HUH¦V�RQH�ZD\�WR�UHZULWH� WKH�QXPEHU�JXHVVLQJ�SURJUDP�IURP�&KDSWHU�����:H

GRQ¦W�KDYH�WR�XVH�D�VPDUW�PDWFK��EXW�ZH�GR�XVH�given�

use 5.010;

my $Verbose = $ENV{VERBOSE} // 1;

my $secret = int(1 + rand 100);

print "Don't tell anyone, but the secret number is $secret.\n" if $Verbose;

LOOP: {

print "Please enter a guess from 1 to 100: "; chomp(my $guess = <STDIN>);

my $found_it = 0;

given( $guess ) { when( ! /^\d+$/ ) { say "Not a number!" } when( $_ > $secret ) { say "Too high!" } when( $_ < $secret ) { say "Too low!" } default { say "Just right!"; $found_it++ } }

last LOOP if $found_it; redo LOOP;

}

,Q�WKH�ILUVW�when��ZH�FKHFN�WKDW�ZH�KDYH�D�QXPEHU�EHIRUH�ZH�JR�DQ\�IXUWKHU��,I�WKHUHDUH�QRQGLJLWV��RU�HYHQ�MXVW�WKH�HPSW\�VWULQJ��ZH�KHDG�RII�DQ\�ZDUQLQJV�LQ�WKH�QX�PHULF�FRPSDULVRQV�

288 | Appendix A:ಗExercise Answers

1RWLFH�WKDW�ZH�GRQ¦W�SXW�WKH�last�LQVLGH�WKH�default�EORFN��:H�DFWXDOO\�GLG�WKDWILUVW��EXW�LW�FDXVHV�D�ZDUQLQJ�ZLWK�3HUO���������EXW�PD\EH�WKDW�ZDUQLQJ�ZLOO�JR�DZD\LQ�IXWXUH�YHUVLRQV��

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

use 5.010;

for (1 .. 105) { my $what = ''; given ($_) { when (not $_ % 3) { $what .= ' fizz'; continue } when (not $_ % 5) { $what .= ' buzz'; continue } when (not $_ % 7) { $what .= ' sausage' } } say "$_$what";}

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

use 5.010;

for( @ARGV ) { say "Processing $_";

when( ! -e ) { say "\tFile does not exist!" } when( -r _ ) { say "\tReadable!"; continue } when( -w _ ) { say "\tWritable!"; continue } when( -x _ ) { say "\tExecutable!"; continue } }

:H�GRQ¦W�KDYH�WR�XVH�WKH�given�EHFDXVH�ZH�FDQ�SXW�WKH�when�GLUHFWO\�LQ�WKH�forEORFN��)LUVW��ZH�FKHFN�WKDW�WKH�ILOH�H[LVWV��RU��DFWXDOO\��WKDW�WKH�ILOH�GRHV�QRW�H[LVW�,I�ZH�H[HFXWH�WKDW�ILUVW�when�EORFN��ZH¦OO�UHSRUW�WKDW�WKH�ILOH�GRHV�QRW�H[LVW�DQG�UHO\RQ�WKH�LPSOLFLW�break�WR�NHHS�XV�IURP�JRLQJ�WKURXJK�WKH�UHVW�RI�WKH�when�WHVWV�

,Q�WKH�VHFRQG�when��ZH�WHVW�WKDW�WKH�ILOH�LV�UHDGDEOH�XVLQJ�-r��:H�DOVR�XVH�WKH�VSHFLDOYLUWXDO�ILOHKDQGOH�_�WKDW�XVHV�WKH�FDFKHG�LQIRUPDWLRQ�IURP�WKH�ODVW�ILOH�stat��ZKLFKLV�KRZ�WKH�ILOH�WHVWV�JHW�WKHLU�LQIRUPDWLRQ���<RX�FRXOG�KDYH�OHIW�RII�WKH�_�DQG�WKHSURJUDP�ZRXOG�ZRUN�WKH�VDPH�EXW�GR�D�OLWWOH�PRUH�ZRUN��$W�WKH�HQG�RI�WKDW�whenEORFN�ZH�XVH�continue�VR�ZH�WU\�WKH�QH[W�when�WRR�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�ZLWK�given�DQG�VPDUW�PDWFKLQJ�

use 5.010;

say "Checking the number <$ARGV[0]>";

given( $ARGV[0] ) { when( ! /^\d+$/ ) { say "Not a number!" }

my @divisors = divisors( $_ );

my @empty;

Answers to Chapter 15 Exercises | 289

when( @divisors ~~ @empty ) { say "Number is prime" }

default { say "$_ is divisible by @divisors" } }

sub divisors { my $number = shift;

my @divisors = (); foreach my $divisor ( 2 .. $number/2 ) { push @divisors, $divisor unless $number % $divisor; }

return @divisors; }

:H�ILUVW�UHSRUW�ZKLFK�QXPEHU�ZH¦UH�ZRUNLQJ�ZLWK��,W¦V�DOZD\V�JRRG�WR�OHW�RXUVHOYHVNQRZ�WKDW�WKH�SURJUDP�LV�UXQQLQJ��:H�SXW�WKH�$ARGV[0]�LQ�DQJOH�EUDFNHWV�WR�VHW�LWDSDUW�IURP�WKH�UHVW�RI�WKH�VWULQJ�

,Q�given��ZH�KDYH�D�FRXSOH�when�EORFNV��ZLWK�VRPH�RWKHU�VWDWHPHQWV�DURXQG�WKHP�7KH�ILUVW�when�FKHFNV�WKDW�ZH�KDYH�D�QXPEHU�E\�WU\LQJ�D�UHJXODU�H[SUHVVLRQ�WR�PDWFKRQO\�GLJLWV��,I�WKDW�UHJXODU�H[SUHVVLRQ�IDLOV��ZH�ZDQW�WR�UXQ�WKDW�EORFN�RI�FRGH�WRVD\��£1RW�D�QXPEHU�¤�7KDW�when�KDV�DQ�LPSOLFLW�break�WKDW�VWRSV�WKH�given�VWUXFWXUH�,I�ZH�JHW�SDVW�WKDW�SRLQW��ZH¦OO�FDOO�divisors()��:H�FRXOG�KDYH�GRQH�WKLV�RXWVLGHWKH�given��EXW�LI�ZH�GLGQ¦W�KDYH�D�QXPEHU��SHUKDSV�ZH�KDG�'Fred'���3HUO�ZRXOG�KDYHLVVXHG� D� ZDUQLQJ�� 2XU� ZD\� DYRLGV� WKH� ZDUQLQJ� E\� XVLQJ� WKH� when� DV� D� JXDUGFRQGLWLRQ�

2QFH�ZH�KDYH�WKH�GLYLVRUV��ZH�ZDQW�WR�NQRZ�LI�WKHUH�LV�DQ\WKLQJ�LQ�WKH�@divisorsDUUD\��:H�FRXOG�MXVW�XVH�WKH�DUUD\�LQ�VFDODU�FRQWH[W�WR�JHW�WKH�QXPEHU�RI�HOHPHQWV�EXW�ZH�KDYH�WR�XVH�VPDUW�PDWFKLQJ��:H�NQRZ�WKDW�LI�ZH�FRPSDUH�WZR�DUUD\V��WKH\KDYH� WR�KDYH� WKH� VDPH�HOHPHQWV� LQ� WKH� VDPH�RUGHU��:H�FUHDWH� DQ�HPSW\�DUUD\�@empty��WKDW�KDV�QRWKLQJ�LQ�LW��:KHQ�ZH�FRPSDUH�WKDW�WR�@divisors��WKH�VPDUW�PDWFKRQO\�VXFFHHGV�LI�WKHUH�ZHUH�QR�GLYLVRUV��,I�WKDW�LV�WUXH��ZH¦OO�UXQ�WKH�when�EORFN�ZKLFK�DOVR�KDV�DQ�LPSOLFLW�break�

)LQDOO\��LI�WKH�QXPEHU�LV�QRW�SULPH��ZH�UXQ�WKH�default�EORFN��ZKLFK�UHSRUWV�WKHOLVW�RI�GLYLVRUV�

+HUH¦V�D�ELW�RI�D�ERQXV�WKDW�ZH�VKRXOGQ¦W�UHDOO\�WDON�DERXW�LQ�/HDUQLQJ�3HUO�EHFDXVHZH�GRQ¦W�WDON�DERXW�UHIHUHQFHV�XQWLO�,QWHUPHGLDWH�3HUO��:H�GLG�H[WUD�ZRUN�WR�FKHFNLI�@divisors�LV�HPSW\�E\�FUHDWLQJ�DQ�HPSW\�QDPHG�DUUD\�WR�FRPSDUH�LW�WR��:H�FRXOGGR�WKLV�ZLWK�DQ�DQRQ\PRXV�DUUD\�DQG�VNLS�WKH�H[WUD�VWHS�

when( @divisors ~~ [] ) { ... }

�� +HUH¦V�RQH�ZD\�WR�GR�LW��EDVHG�RQ�WKH�DQVZHU�WR�WKH�SUHYLRXV�H[HUFLVH�

use 5.010;

say "Checking the number <$ARGV[0]>";

290 | Appendix A:ಗExercise Answers

my $favorite = 42;

given( $ARGV[0] ) { when( ! /^\d+$/ ) { say "Not a number!" }

my @divisors = divisors( $ARGV[0] );

when( @divisors ~~ 2 ) { # 2 is in @divisors say "$_ is even"; continue; }

when( !( @divisors ~~ 2 ) ) { # 2 isn't in @divisors say "$_ is odd"; continue; }

when( @divisors ~~ $favorite ) { say "$_ is divisible by my favorite number"; continue; }

when( $favorite ) { # $_ ~~ $favorite say "$_ is my favorite number"; continue; }

my @empty; when( @divisors ~~ @empty ) { say "Number is prime" }

default { say "$_ is divisible by @divisors" } }

sub divisors { my $number = shift;

my @divisors = (); foreach my $divisor ( 2 .. ($ARGV[0]/2 + 1) ) { push @divisors, $divisor unless $number % $divisor; }

return @divisors; }

7KLV�H[WHQVLRQ�RI�WKH�SUHYLRXV�H[HUFLVH�DGGV�PRUH�when�EORFNV�WR�KDQGOH�WKH�DGGL�WLRQDO�UHSRUWLQJ�VLWXDWLRQV��2QFH�ZH�KDYH�@divisors��ZH�XVH�WKH�VPDUW�PDWFK�RS�HUDWRU�WR�VHH�ZKDW¦V�LQ�LW��,I���LV�LQ�GLYLVRUV��WKHQ�LW¦V�DQ�HYHQ�QXPEHU��:H�UHSRUWWKDW�DQG�XVH�DQ�H[SOLFLW�continue�VR�given�WULHV�WKH�QH[W�when�WRR��)RU�RGG�QXPEHUV�ZH�GR�WKH�VDPH�VPDUW�PDWFK�EXW�QHJDWH�WKH�UHVXOW��7R�VHH�LI�RXU�IDYRULWH�QXPEHULV�LQ�@divisors��ZH�GR�WKH�VDPH�WKLQJ��:H�FDQ�HYHQ�FKHFN�LI�WKH�QXPEHU�LV�H[DFWO\RXU�IDYRULWH�QXPEHU�

Answers to Chapter 15 Exercises | 291

Answers to Chapter 16 Exercises�� +HUH¦V�RQH�ZD\�WR�GR�LW�

chdir "/" or die "Can't chdir to root directory: $!";exec "ls", "-l" or die "Can't exec ls: $!";

7KH�ILUVW�OLQH�FKDQJHV�WKH�FXUUHQW�ZRUNLQJ�GLUHFWRU\�WR�WKH�URRW�GLUHFWRU\��DV�RXUSDUWLFXODU�KDUGFRGHG�GLUHFWRU\��7KH�VHFRQG�OLQH�XVHV�WKH�PXOWLSOH�DUJXPHQW�execIXQFWLRQ�WR�VHQG�WKH�UHVXOW� WR�VWDQGDUG�RXWSXW��:H�FRXOG�KDYH�XVHG�WKH�VLQJOH�DUJXPHQW�IRUP�MXVW�DV�ZHOO��EXW�LW�GRHVQ¦W�KXUW�WR�GR�LW�WKLV�ZD\�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

open STDOUT, ">ls.out" or die "Can't write to ls.out: $!";open STDERR, ">ls.err" or die "Can't write to ls.err: $!";chdir "/" or die "Can't chdir to root directory: $!";exec "ls", "-l" or die "Can't exec ls: $!";

7KH�ILUVW�DQG�VHFRQG�OLQHV�UHRSHQ�STDOUT�DQG�STDERR�WR�D�ILOH�LQ�WKH�FXUUHQW�GLUHFWRU\�EHIRUH�ZH�FKDQJH�GLUHFWRULHV���7KHQ��DIWHU�WKH�GLUHFWRU\�FKDQJH��WKH�GLUHFWRU\�OLVW�LQJ�FRPPDQG�H[HFXWHV��VHQGLQJ�WKH�GDWD�EDFN�WR�WKH�ILOHV�RSHQHG�LQ�WKH�RULJLQDOGLUHFWRU\�

:KHUH�ZRXOG�WKH�PHVVDJH�IURP�WKH�ODVW�die�JR"�:K\��LW�ZRXOG�JR�LQWR�OV�HUU��RIFRXUVH��VLQFH�WKDW¦V�ZKHUH�STDERR�LV�JRLQJ�DW�WKDW�SRLQW��7KH�die�IURP�chdir�ZRXOGJR�WKHUH��WRR��%XW�ZKHUH�ZRXOG�WKH�PHVVDJH�JR�LI�ZH�FDQ¦W�UHRSHQ�STDERR�RQ�WKHVHFRQG�OLQH"�,W�JRHV�WR�WKH�ROG�STDERR��,I�UHRSHQLQJ�WKH�WKUHH�VWDQGDUG�ILOHKDQGOHV¢STDIN��STDOUT��DQG�STDERR¢IDLOV��WKH�ROG�ILOHKDQGOH�LV�VWLOO�RSHQ�

�� +HUH¦V�RQH�ZD\�WR�GR�LW�

if (`date` =~ /^S/) { print "go play!\n";} else { print "get to work!\n";}

:HOO��VLQFH�ERWK�6DWXUGD\�DQG�6XQGD\�VWDUW�ZLWK�DQ�6��DQG�WKH�GD\�RI�WKH�ZHHN�LVWKH�ILUVW�SDUW�RI�WKH�RXWSXW�RI�WKH�GDWH�FRPPDQG��WKLV�LV�SUHWW\�VLPSOH��-XVW�FKHFNWKH�RXWSXW�RI�WKH�GDWH�FRPPDQG�WR�VHH�LI�LW�VWDUWV�ZLWK�S��7KHUH�DUH�PDQ\�KDUGHUZD\V�WR�GR�WKLV�SURJUDP��DQG�ZH¦YH�VHHQ�PRVW�RI�WKHP�LQ�RXU�FODVVHV�

,I�ZH�KDG�WR�XVH�WKLV�LQ�D�UHDO�ZRUOG�SURJUDP��WKRXJK��ZH¦G�SUREDEO\�XVH�WKH�SDW�WHUQ�/^(Sat|Sun)/��,W¦V�D�WLQ\�ELW�OHVV�HIILFLHQW��EXW�WKDW�KDUGO\�PDWWHUV��EHVLGHV��LW¦VVR�PXFK�HDVLHU�IRU�WKH�PDLQWHQDQFH�SURJUDPPHU�WR�XQGHUVWDQG�

292 | Appendix A:ಗExercise Answers

Answer to Chapter 17 Exercise�� +HUH¦V�RQH�ZD\�WR�GR�LW�

my $filename = 'path/to/sample_text';open FILE, $filename or die "Can't open '$filename': $!";chomp(my @strings = <FILE>);while (1) { print "Please enter a pattern: "; chomp(my $pattern = <STDIN>); last if $pattern =~ /^\s*$/; my @matches = eval { grep /$pattern/, @strings; }; if ($@) { print "Error: $@"; } else { my $count = @matches; print "There were $count matching strings:\n", map "$_\n", @matches; } print "\n";}

7KLV�RQH�XVHV�DQ�eval�EORFN�WR�WUDS�DQ\�IDLOXUH�WKDW�PLJKW�RFFXU�ZKHQ�XVLQJ�WKHUHJXODU�H[SUHVVLRQ��,QVLGH�WKDW�EORFN��D�grep�SXOOV�WKH�PDWFKLQJ�VWULQJV�IURP�WKHOLVW�RI�VWULQJV�

2QFH�WKH�eval�LV�ILQLVKHG��ZH�FDQ�UHSRUW�HLWKHU�WKH�HUURU�PHVVDJH�RU�WKH�PDWFKLQJVWULQJV��1RWH�WKDW�ZH�£XQFKRPSHG¤�WKH�VWULQJV�IRU�RXWSXW�E\�XVLQJ�map�WR�DGG�DQHZOLQH�WR�HDFK�VWULQJ�

Answer to Chapter 17 Exercise | 293

APPENDIX B

Beyond the Llama

:H¦YH�FRYHUHG�D�ORW�LQ�WKLV�ERRN��EXW�WKHUH¦V�HYHQ�PRUH��,Q�WKLV�DSSHQGL[��ZH¦OO�WHOO�\RXD�OLWWOH�PRUH�DERXW�ZKDW�3HUO�FDQ�GR�DQG�JLYH�\RX�VRPH�UHIHUHQFHV�RQ�ZKHUH�WR�OHDUQWKH� GHWDLOV�� 6RPH�RI�ZKDW�ZH�PHQWLRQ�KHUH� LV� RQ� WKH� EOHHGLQJ� HGJH� DQG�PD\�KDYHFKDQJHG�E\�WKH�WLPH�\RX¦UH�UHDGLQJ�WKLV�ERRN��ZKLFK�LV�RQH�UHDVRQ�ZK\�ZH�IUHTXHQWO\VHQG�\RX�WR�WKH�GRFXPHQWDWLRQ�IRU�WKH�IXOO�VWRU\��:H�GRQ¦W�H[SHFW�PDQ\�UHDGHUV�WR�UHDGHYHU\�ZRUG�RI�WKLV�DSSHQGL[��EXW�ZH�KRSH�\RX¦OO�DW�OHDVW�VNLP�WKH�KHDGLQJV�VR�WKDW�\RX¦OOEH�SUHSDUHG�WR�ILJKW�EDFN�ZKHQ�VRPHRQH�WHOOV�\RX��£<RX�MXVW�FDQ¦W�XVH�3HUO�IRU�SURMHFW;�EHFDXVH�3HUO�FDQ¦W�GR�<�¤

7KH�PRVW� LPSRUWDQW� WKLQJ� WR�NHHS� LQ�PLQG� �VR� WKDW�ZH¦UH�QRW� UHSHDWLQJ� LW� LQ� HYHU\SDUDJUDSK��LV�WKDW�WKH�PRVW�LPSRUWDQW�SDUW�RI�ZKDW�ZH¦UH�QRW�FRYHULQJ�KHUH�LV�FRYHUHGLQ�,QWHUPHGLDWH�3HUO��2¦5HLOO\���DOVR�NQRZ�DV�£WKH�$OSDFD�¤�<RX�VKRXOG�GHILQLWHO\�UHDGWKH�$OSDFD��HVSHFLDOO\�LI�\RX¦OO�EH�ZULWLQJ�SURJUDPV�WKDW�DUH�ORQJHU�WKDQ�����OLQHV��HLWKHUDORQH��RU�ZLWK�RWKHU�SHRSOH���DQG�HVSHFLDOO\�LI�\RX¦UH�WLUHG�RI�KHDULQJ�DERXW�)UHG�DQG%DUQH\��DQG�ZDQW�WR�PRYH�RQ�WR�DQRWKHU�ILFWLRQDO�XQLYHUVH��IHDWXULQJ�VHYHQ�SHRSOH �ZKRJRW�WR�VSHQG�D�ORW�RI�WLPH�RQ�DQ�LVRODWHG�LVODQG�DIWHU�D�FUXLVH�

$IWHU�WKH�$OSDFD��\RX¦OO�EH�UHDG\�WR�PRYH�RQ�WR�0DVWHULQJ�3HUO��2¦5HLOO\���DOVR�NQRZ�DV£WKH�9LFXxDV�¤�,W�FRYHUV�WKH�HYHU\GD\�WDVNV�WKDW�\RX¦OO�ZDQW�WR�GR�ZKLOH�SURJUDPPLQJ3HUO��VXFK�DV�EHQFKPDUNLQJ�DQG�SURILOLQJ��SURJUDP�FRQILJXUDWLRQ��DQG�ORJJLQJ��,W�DOVRJRHV�WKURXJK�WKH�ZRUN�\RX¦OO�QHHG�WR�GR�WR�GHDO�ZLWK�FRGH�ZULWWHQ�E\�RWKHU�SHRSOH�DQGKRZ�WR�LQWHJUDWH�WKDW�LQWR�\RXU�RZQ�DSSOLFDWLRQV�

Further Documentation7KH�GRFXPHQWDWLRQ�WKDW�FRPHV�ZLWK�3HUO�PD\�VHHP�RYHUZKHOPLQJ�DW�ILUVW��)RUWXQDWHO\�\RX� FDQ� XVH� \RXU� FRPSXWHU� WR� VHDUFK� IRU� NH\ZRUGV� LQ� WKH� GRFXPHQWDWLRQ��:KHQVHDUFKLQJ� IRU� D� SDUWLFXODU� WRSLF�� LW¦V� RIWHQ� JRRG� WR� VWDUW� ZLWK� WKH� SHUOWRF� �WDEOH� RIFRQWHQWV�� DQG� SHUOIDT� �IUHTXHQWO\� DVNHG� TXHVWLRQV�� VHFWLRQV��2Q�PRVW� V\VWHPV�� WKHSHUOGRF�FRPPDQG�VKRXOG�EH�DEOH�WR�WUDFN�GRZQ�WKH�GRFXPHQWDWLRQ�IRU�3HUO��LQVWDOOHG

&DOO�WKHP�£FDVWDZD\V�¤

295

PRGXOHV��DQG�UHODWHG�SURJUDPV��LQFOXGLQJ�SHUOGRF�LWVHOI���<RX�FDQ�UHDG�WKH�VDPH�GRF�XPHQWDWLRQ�RQOLQH�DW�KWWS���SHUOGRF�SHUO�RUJ��DOWKRXJK�WKDW�LV�DOZD\V�IRU�WKH�ODWHVW�YHU�VLRQ�RI�3HUO�

Regular Expressions<HV��WKHUH¦V�HYHQ�PRUH�DERXW�UHJXODU�H[SUHVVLRQV�WKDQ�ZH�PHQWLRQHG��0DVWHULQJ�5HJ�XODU�([SUHVVLRQV�E\�-HIIUH\�)ULHGO��2¦5HLOO\��LV�RQH�RI�WKH�EHVW�WHFKQLFDO�ERRNV�ZH¦YHHYHU�UHDG� �,W¦V�KDOI�DERXW�UHJXODU�H[SUHVVLRQV�LQ�JHQHUDO��DQG�KDOI�DERXW�3HUO¦V�UHJXODUH[SUHVVLRQV��,W�JRHV�LQWR�JUHDW�GHWDLO�DERXW�KRZ�WKH�UHJXODU�H[SUHVVLRQ�HQJLQH�ZRUNVLQWHUQDOO\��DQG�ZK\�RQH�ZD\�RI�ZULWLQJ�D�SDWWHUQ�PD\�EH�PXFK�PRUH�HIILFLHQW� WKDQDQRWKHU��$Q\RQH�ZKR�LV�VHULRXV�DERXW�3HUO�VKRXOG�UHDG�WKLV�ERRN��$OVR�VHH�WKH�SHUOUHPDQSDJH��DQG�LWV�FRPSDQLRQ�PDQSDJHV�SHUOUHWXW�DQG�SHUOUHTXLFN�LQ�QHZHU�YHUVLRQV�RI3HUO���$QG��WKHUH¦V�PRUH�DERXW�UHJXODU�H[SUHVVLRQV�LQ�WKH�$OSDFD�DV�ZHOO�

Packages3DFNDJHV��DOORZ�\RX�WR�FRPSDUWPHQWDOL]H�QDPHVSDFHV��,PDJLQH�WKDW�\RX�KDYH����SUR�JUDPPHUV�DOO�ZRUNLQJ�RQ�RQH�ELJ�SURMHFW��,I�\RX�XVH�WKH�JOREDO�QDPHV�$fred��@barney�%betty��DQG�&wilma�LQ�\RXU�SDUW�RI�WKH�SURMHFW��ZKDW�KDSSHQV�ZKHQ�,�DFFLGHQWDOO\�XVHRQH�RI�WKRVH�VDPH�QDPHV�LQ�P\�SDUW"�3DFNDJHV�OHW�XV�NHHS�WKHP�VHSDUDWH��,�FDQ�DFFHVV\RXU�$fred��DQG�\RX�FDQ�DFFHVV�PLQH��EXW�QRW�E\�DFFLGHQW��3DFNDJHV�DUH�QHHGHG�WR�PDNH3HUO�VFDODEOH�VR�WKDW�ZH�FDQ�PDQDJH�ODUJH�SURJUDPV��3DFNDJHV�DUH�FRYHUHG�LQ�JUHDW�GHWDLOLQ�WKH�$OSDFD�

Extending Perl’s Functionality2QH�RI�WKH�PRVW�FRPPRQ�SLHFHV�RI�JRRG�DGYLFH�KHDUG�LQ�WKH�3HUO�GLVFXVVLRQ�IRUXPV�LVWKDW�\RX�VKRXOGQ¦W�UHLQYHQW�WKH�ZKHHO��2WKHU�IRONV�KDYH�ZULWWHQ�FRGH�WKDW�\RX�FDQ�SXWWR�XVH��7KH�PRVW�IUHTXHQW�ZD\�WR�DGG�WR�ZKDW�3HUO�FDQ�GR�LV�E\�XVLQJ�D�OLEUDU\�RU�PRGXOH�0DQ\�RI�WKHVH�FRPH�ZLWK�3HUO��ZKLOH�RWKHUV�DUH�DYDLODEOH�IURP�&3$1��2I�FRXUVH��\RXFDQ�HYHQ�ZULWH�\RXU�RZQ�OLEUDULHV�DQG�PRGXOHV�

$QG�ZH¦UH�QRW�MXVW�VD\LQJ�WKDW�EHFDXVH�LW¦V�DOVR�SXEOLVKHG�E\�2¦5HLOO\��,W¦V�UHDOO\�D�JUHDW�ERRN�

� 7KH�QDPH�£SDFNDJH¤�LV�SHUKDSV�DQ�XQIRUWXQDWH�FKRLFH��LQ�WKDW�LW�PDNHV�PDQ\�SHRSOH�WKLQN�RI�D�SDFNDJHG�XSFKXQN�RI�FRGH��LQ�3HUO��WKDW¦V�D�PRGXOH�RU�D�OLEUDU\���$OO�WKDW�D�SDFNDJH�GRHV�LV�GHILQH�D�QDPHVSDFH��D�FROOHFWLRQRI�JOREDO�V\PERO�QDPHV��OLNH�$fred�RU�&wilma���$�QDPHVSDFH�LV�QRW�D�FKXQN�RI�FRGH�

296 | Appendix B:ಗBeyond the Llama

Libraries0DQ\�SURJUDPPLQJ�ODQJXDJHV�RIIHU�VXSSRUW�IRU�OLEUDULHV�PXFK�DV�3HUO�GRHV��/LEUDULHVDUH�FROOHFWLRQV�RI��PRVWO\��VXEURXWLQHV�IRU�D�JLYHQ�SXUSRVH��,Q�PRGHUQ�3HUO��WKRXJK��LW¦VPRUH�FRPPRQ�WR�XVH�PRGXOHV�WKDQ�OLEUDULHV�

Modules$�PRGXOH�LV�D�£VPDUW�OLEUDU\�¤�$�PRGXOH�ZLOO�W\SLFDOO\�RIIHU�D�FROOHFWLRQ�RI�VXEURXWLQHVWKDW�DFW�DV�LI�WKH\�ZHUH�EXLOW�LQ�IXQFWLRQV��IRU�WKH�PRVW�SDUW��0RGXOHV�DUH�VPDUW�LQ�WKDWWKH\�NHHS�WKHLU�GHWDLOV�LQ�D�VHSDUDWH�SDFNDJH��RQO\�LPSRUWLQJ�ZKDW�\RX�UHTXHVW��7KLVNHHSV�D�PRGXOH�IURP�VWRPSLQJ�RQ�\RXU�FRGH¦V�V\PEROV�

$OWKRXJK�PDQ\�XVHIXO�PRGXOHV�DUH�ZULWWHQ� LQ�SXUH�3HUO��RWKHUV�DUH�ZULWWHQ�XVLQJ�DODQJXDJH�OLNH�&��)RU�H[DPSOH��WKH�0'��DOJRULWKP�LV�VRUW�RI�OLNH�D�KLJK�SRZHUHG�FKHFN�VXP� �,W�XVHV�D�ORW�RI�ORZ�OHYHO�ELW�WZLGGOLQJ�WKDW�FRXOG�EH�GRQH�LQ�3HUO��EXW�KXQGUHGVRI�WLPHV�PRUH�VORZO\���LW¦V�DQ�DOJRULWKP�WKDW�ZDV�GHVLJQHG�WR�EH�HIILFLHQWO\�LPSOHPHQWHGLQ�&��6R��WKH�Digest::MD5�PRGXOH�LV�PDGH�WR�XVH�WKH�FRPSLOHG�&�FRGH��:KHQ�\RX�XVHWKDW�PRGXOH��LW¦V�DV�LI�\RXU�3HUO�KDG�D�EXLOW�LQ�IXQFWLRQ�WR�FDOFXODWH�0'��GLJHVWV�

Finding and Installing Modules0D\EH�\RXU�V\VWHP�DOUHDG\�KDV�WKH�PRGXOH�\RX�QHHG��%XW�KRZ�FDQ�\RX�ILQG�RXW�ZKLFKPRGXOHV�DUH�LQVWDOOHG"�<RX�FDQ�XVH�WKH�SURJUDP�LQVLGH��ZKLFK�\RX�VKRXOG�EH�DEOH�WRGRZQORDG�IURP�&3$1�DW�KWWS���ZZZ�FSDQ�RUJ�DXWKRUV�LG�3�3+�3+2(1,;��

,I�QRQH�RI�WKH�PRGXOHV�DOUHDG\�DYDLODEOH�RQ�\RXU�V\VWHP�VXLWV�\RXU�QHHGV��\RX�FDQ�VHDUFKIRU�3HUO�PRGXOHV�RQ�&3$1�DW�KWWS���VHDUFK�FSDQ�RUJ���7R�LQVWDOO�D�PRGXOH�RQ�\RXU�V\V�WHP��VHH�WKH�SHUOPRGLQVWDOO�PDQSDJH�

:KHQ�XVLQJ�D�PRGXOH��\RX¦OO�JHQHUDOO\�SXW�WKH�UHTXLUHG�use�GLUHFWLYHV�DW�WKH�WRS�RI�\RXUSURJUDP��7KDW�PDNHV�LW�HDV\�IRU�VRPHRQH�ZKR�LV� LQVWDOOLQJ�\RXU�SURJUDP�RQ�D�QHZV\VWHP�WR�VHH�DW�D�JODQFH�ZKLFK�PRGXOHV�LW�QHHGV�

Writing Your Own Modules,Q�WKH�UDUH�FDVH�WKDW�WKHUH¦V�QR�PRGXOH�WR�GR�ZKDW�\RX�QHHG��DQ�DGYDQFHG�SURJUDPPHUFDQ�ZULWH�D�QHZ�RQH��HLWKHU�LQ�3HUO�RU�LQ�DQRWKHU�ODQJXDJH��RIWHQ�&���6HH�WKH�SHUOPRG

,W¦V�QRW�UHDOO\�D�FKHFNVXP��EXW�WKDW¦V�JRRG�HQRXJK�IRU�WKLV�H[SODQDWLRQ�

� 7KH�PRGXOH�Digest::Perl::MD5�LV�D�SXUH�3HUO�LPSOHPHQWDWLRQ�RI�WKH�0'��DOJRULWKP��$OWKRXJK�\RXU�PLOHDJHPD\�YDU\��ZH�IRXQG�LW�WR�EH�DERXW�����WLPHV�VORZHU�WKDQ�WKH�Digest::MD5�PRGXOH�RQ�RQH�VDPSOH�GDWD�VHW�5HPHPEHU�WKDW�PDQ\�RI�WKH�ELW�WZLGGOLQJ�RSHUDWLRQV�LQ�WKH�&�DOJRULWKP�FRPSLOH�GRZQ�WR�D�VLQJOH�PDFKLQHLQVWUXFWLRQ��WKXV��HQWLUH�OLQHV�RI�FRGH�FDQ�WDNH�D�PHUH�KDQGIXO�RI�FORFN�F\FOHV�WR�UXQ��3HUO�LV�IDVW��EXW�OHW¦V�QRWEH�XQUHDOLVWLF�

Extending Perl’s Functionality | 297

DQG�SHUOPRGOLE�PDQSDJHV�IRU�PRUH�LQIRUPDWLRQ��7KH�$OSDFD�FRYHUV�KRZ�WR�ZULWH��WHVW�DQG�GLVWULEXWH�PRGXOHV�

Some Important Modules:H�GHVFULEH�VRPH�RI�WKH�PRVW�LPSRUWDQW�IHDWXUHV �RI�WKH�PRVW�LPSRUWDQW�PRGXOHV��LQWKLV� VHFWLRQ��7KH�PRGXOHV� WKDW�ZH�GLVFXVV�KHUH�VKRXOG�JHQHUDOO\�EH� IRXQG�RQ�HYHU\PDFKLQH�WKDW�KDV�3HUO��H[FHSW�ZKHUH�QRWHG�RWKHUZLVH��<RX�FDQ�DOZD\V�JHW�WKH�ODWHVWRQHV�IURP�&3$1�

The CGI Modules0DQ\�SHRSOH�XVH�3HUO�WR�ZULWH�SURJUDPV�WKDW�D�ZHE�VHUYHU�ZLOO�UXQ��JHQHUDOO\�FDOOHG�&*,SURJUDPV��7KH�CGI�PRGXOH�FRPHV�ZLWK�3HUO��:H�VKRZHG�D�VLPSOH�H[DPSOH�LQ�&KDS�WHU�����DQG�\RX�FDQ�UHDG�PRUH�ODWHU�LQ�WKLV�DSSHQGL[�

The Cwd Module6RPHWLPHV�\RX�QHHG�WR�NQRZ�ZKDW�WKH�FXUUHQW�ZRUNLQJ�GLUHFWRU\¦V�QDPH�LV���:HOO��\RXFRXOG�RIWHQ�XVH�.��EXW�PD\EH�\RX�QHHG�WR�VDYH�WKH�QDPH�VR�WKDW�\RX�FDQ�FKDQJH�EDFNWR�WKLV�GLUHFWRU\�ODWHU���7KH�Cwd�PRGXOH¢ZKLFK�FRPHV�ZLWK�3HUO¢SURYLGHV�WKH�cwdIXQFWLRQ��ZKLFK�\RX�FDQ�XVH�WR�GHWHUPLQH�WKH�FXUUHQW�ZRUNLQJ�GLUHFWRU\�

use Cwd;

my $directory = cwd;

The Fatal Module,I�\RX�JHW�WLUHG�RI�ZULWLQJ��or die��DIWHU�HYHU\�LQYRFDWLRQ�RI�open�RU�chdir��WKHQ�PD\EHWKH�Fatal�PRGXOH�LV�IRU�\RX��-XVW�WHOO�LW�ZKLFK�IXQFWLRQV�WR�ZRUN�ZLWK��DQG�WKRVH�ZLOOEH�DXWRPDWLFDOO\�FKHFNHG�IRU�IDLOXUH��DV�LI�\RX¦G�ZULWWHQ��or die��DQG�D�VXLWDEOH�PHVVDJHDIWHU�HDFK�RQH��7KLV�ZRQ¦W�DIIHFW�VXFK�FDOOV�LQ�VRPHRQH�HOVH¦V�SDFNDJH��WKDW�LV��FRGHFRQWDLQHG�ZLWKLQ�D�PRGXOH�\RX¦UH�XVLQJ��IRU�H[DPSOH���VR�GRQ¦W�XVH�WKLV�WR�IL[�XS�SRRUO\ZULWWHQ�FRGH��,W¦V�MXVW�D�WLPHVDYHU��PRVWO\�IRU�VLPSOH�SURJUDPV�LQ�ZKLFK�\RX�GRQ¦W�QHHGGLUHFW�FRQWURO�RYHU�WKH�HUURU�PHVVDJH�LWVHOI��)RU�H[DPSOH�

use Fatal qw/ open chdir /;

chdir '/home/merlyn'; # "or die" is now supplied automatically

:H¦UH� LQFOXGLQJ� KHUH� PHUHO\� WKH� PRVW� LPSRUWDQW� IHDWXUHV� RI� HDFK� PRGXOH�� VHH� WKH� PRGXOH¦V� RZQGRFXPHQWDWLRQ�WR�OHDUQ�PRUH�

� 7R�EH�VXUH�� WKHUH�DUH�RWKHU� LPSRUWDQW�PRGXOHV�ZKRVH�XVH� LV� WRR�FRPSOH[� IRU�PRVW�UHDGHUV�RI� WKLV�ERRN�W\SLFDOO\�EHFDXVH�XVLQJ�WKH�PRGXOH�UHTXLUHV�XQGHUVWDQGLQJ�3HUO¦V�UHIHUHQFHV�RU�REMHFWV�

298 | Appendix B:ಗBeyond the Llama

The File::Basename Module:H�FRYHUHG�WKLV�PRGXOH�LQ�&KDSWHU�����,W¦V�SULPDU\�XVH�LV�WR�SRUWDEO\�SXOO�WKH�EDVHQDPHRU�GLUHFWRU\�QDPH�IURP�D�IXOO�ILOHQDPH�

use File::Basename;

for (@ARGV) { my $basename = basename $_; my $dirname = dirname $_; print "That's file $basename in directory $dirname.\n";}

The File::Copy Module:KHQ�\RX�QHHG�WR�FRS\�RU�PRYH�ILOHV��WKH�File::Copy�PRGXOH�LV�IRU�\RX���,W¦V�RIWHQWHPSWLQJ�WR�VLPSO\�FDOO�D�V\VWHP�SURJUDP�WR�GR�WKHVH�WKLQJV��EXW�WKDW¦V�QRW�SRUWDEOH��7KLV�PRGXOH�SURYLGHV�WKH�IXQFWLRQV�move�DQG�copy��ZKLFK�PD\�EH�XVHG�PXFK�DV�WKHFRUUHVSRQGLQJ�V\VWHP�SURJUDPV�ZRXOG�EH�XVHG�

use File::Copy;

copy("source", "destination") or die "Can't copy 'source' to 'destination': $!";

The File::Spec Module:KHQ�\RX�QHHG�WR�PDQLSXODWH�D�ILOHQDPH��PRUH�IRUPDOO\�FDOOHG�D�£ILOH�VSHFLILFDWLRQ¤��LW¦V�JHQHUDOO\�PRUH�SRUWDEOH�DQG�UHOLDEOH�WR�XVH�WKH�File::Spec�PRGXOH�WKDQ�WR�GR�WKHZRUN�\RXUVHOI�IURP�3HUO��)RU�H[DPSOH��\RX�FDQ�XVH�WKH�catfile�IXQFWLRQ�WR�SXW�WRJHWKHUD� GLUHFWRU\� QDPH� DQG� D� ILOHQDPH� WR� SURGXFH� D� ORQJ� ILOHQDPH� �DV�ZH� VDZ� LQ�&KDS�WHU������EXW�\RX�GRQ¦W�KDYH�WR�NQRZ�ZKHWKHU�WKH�V\VWHP�\RXU�SURJUDP�LV�UXQQLQJ�RQXVHV�D�IRUZDUG�VODVK�RU�VRPH�RWKHU�FKDUDFWHU�WR�VHSDUDWH�WKRVH��2U�\RX�FRXOG�XVH�WKHcurdir�IXQFWLRQ�WR�JHW�WKH�QDPH�RI�WKH�FXUUHQW�GLUHFWRU\��.��RQ�8QL[�V\VWHPV��

7KH�File::Spec�PRGXOH�LV�REMHFW�RULHQWHG��EXW�\RX�GRQ¦W�QHHG�WR�XQGHUVWDQG�REMHFWVWR�XVH�LW��-XVW�FDOO�HDFK�IXQFWLRQ��£PHWKRG�¤�UHDOO\��E\�XVLQJ�File::Spec�DQG�D�VPDOODUURZ�EHIRUH�WKH�IXQFWLRQ¦V�QDPH��OLNH�WKLV�

use File::Spec;

my $current_directory = File::Spec->curdir;opendir DOT, $current_directory or die "Can't open current directory '$current_directory': $!";

The Image::Size Module:KHQ�\RX�KDYH�DQ�LPDJH�ILOH��\RX¦OO�RIWHQ�ZDQW�WR�NQRZ�ZKDW�LWV�KHLJKW�DQG�ZLGWK�DUH��7KLV�LV�KDQG\�IRU�PDNLQJ�SURJUDPV�WKDW�ZULWH�+70/�LI�\RX�ZLVK�IRU�DQ�,0*�WDJ�WRLQGLFDWH�WKH� LPDJH¦V�GLPHQVLRQV���7KH�Image::Size�PRGXOH��ZKLFK�LV�DYDLODEOH�IURP

Some Important Modules | 299

&3$1��XQGHUVWDQGV�WKH�FRPPRQ�*,)��-),)��-3(*���DQG�31*�LPDJH�W\SHV��DQG�VRPHRWKHUV��)RU�H[DPSOH�

use Image::Size;

# Get the size of fred.pngmy($fred_height, $fred_width) = imgsize("fred.png");die "Couldn't get the size of the image" unless defined $fred_height;

The Net::SMTP Module,I�\RX�ZDQW�\RXU�SURJUDP�WR�EH�DEOH�WR�VHQG�HPDLO�WKURXJK�DQ�6073�VHUYHU��ZKLFK�LVWKH�ZD\�PRVW�RI�XV�VHQG�HPDLO�WKHVH�GD\V��ZKHWKHU�\RX�NQHZ�WKDW�RU�QRW���\RX�PD\�XVHWKH�Net::SMTP�PRGXOH�WR�GR�WKH�ZRUN� �7KLV�PRGXOH��ZKLFK�LV�DYDLODEOH�IURP�&3$1��LVREMHFW�RULHQWHG��EXW�\RX�PD\�VLPSO\�IROORZ�WKH�V\QWD[�WR�XVH�LW��<RX�ZLOO�QHHG�WR�FKDQJHWKH�QDPH�RI�\RXU�6073�KRVW�DQG�WKH�RWKHU�LWHPV�WR�PDNH�WKLV�ZRUN�RQ�\RXU�V\VWHP�<RXU�V\VWHP�DGPLQLVWUDWRU�RU�ORFDO�H[SHUW�FDQ�WHOO�\RX�ZKDW�WR�XVH��)RU�H[DPSOH�

use Net::SMTP;

my $from = 'YOUR_ADDRESS_GOES_HERE'; # maybe fred@bedrock.edumy $site = 'YOUR_SITE_NAME_GOES_HERE'; # maybe bedrock.edumy $smtp_host = 'YOUR_SMTP_HOST_GOES_HERE'; # maybe mail or mailhostmy $to = 'president@whitehouse.gov';

my $smtp = Net::SMTP->new($smtp_host, Hello => $site);

$smtp->mail($from);$smtp->to($to);$smtp->data( );

$smtp->datasend("To: $to\n");$smtp->datasend("Subject: A message from my Perl program.\n");$smtp->datasend("\n");$smtp->datasend("This is just to let you know,\n");$smtp->datasend("I don't care what those other people say about you,\n");$smtp->datasend("I still think you're doing a great job.\n");$smtp->datasend("\n");$smtp->datasend("Have you considered enacting a law naming Perl \n");$smtp->datasend("the national programming language?\n");

$smtp->dataend( ); # Not datasend!$smtp->quit;

<HV��WKLV�PHDQV�WKDW�\RX�DUH�QRZ�DEOH�WR�XVH�3HUO�WR�VHQG�VSDP��3OHDVH�GRQ¦W�

300 | Appendix B:ಗBeyond the Llama

The POSIX Module,I�\RX�QHHG�DFFHVV�WR�WKH�326,;��,(((�6WG���������IXQFWLRQV��WKH�POSIX�PRGXOH�LV�IRU\RX��,W�SURYLGHV�PDQ\�IXQFWLRQV�WKDW�&�SURJUDPPHUV�PD\�EH�XVHG�WR��VXFK�DV�WULJRQR�PHWULF�IXQFWLRQV��asin��cosh���JHQHUDO�PDWKHPDWLFDO�IXQFWLRQV��floor��frexp���FKDUDFWHU�LGHQWLILFDWLRQ�IXQFWLRQV��isupper��isalpha���ORZ�OHYHO�,�2�IXQFWLRQV��creat��open���DQGVRPH�RWKHUV��asctime��clock���<RX¦OO�SUREDEO\�ZDQW�WR�FDOO�HDFK�RI�WKHVH�ZLWK�LWV�£IXOO¤QDPH��WKDW�LV��ZLWK�POSIX�DQG�D�SDLU�RI�FRORQV�DV�D�SUHIL[�WR�WKH�IXQFWLRQ¦V�QDPH�

use POSIX;

print "Please enter a number: ";chomp(my $str = <STDIN>);

$! = 0; # Clear out the error indicatormy($num, $leftover) = POSIX::strtod($str);

if ($str eq '') { print "That string was empty!\n";} elsif ($leftover) { my $remainder = substr $str, -$leftover; print "The string '$remainder' was left after the number $num.\n";} elsif ($!) { print "The conversion function complained: $!\n";} else { print "The seemingly-valid number was $num.\n";}

The Sys::Hostname Module7KH�Sys::Hostname�PRGXOH�SURYLGHV�WKH�hostname�IXQFWLRQ��ZKLFK�ZLOO�EH�WKH�QHWZRUNQDPH�RI�\RXU�PDFKLQH�LI�WKDW�FDQ�EH�GHWHUPLQHG���,I�LW�FDQ¦W�EH�GHWHUPLQHG��SHUKDSVEHFDXVH�\RXU�PDFKLQH�LV�QRW�RQ�WKH�,QWHUQHW�RU�QRW�SURSHUO\�FRQILJXUHG��WKH�IXQFWLRQZLOO�GLH�DXWRPDWLFDOO\��WKHUH¦V�QR�SRLQW�LQ�XVLQJ�or die�KHUH���)RU�H[DPSOH�

use Sys::Hostname;my $host = hostname;print "This machine is known as '$host'.\n";

The Text::Wrap Module7KH�Text::Wrap�PRGXOH�VXSSOLHV�WKH�wrap�IXQFWLRQ��ZKLFK�OHWV�\RX�LPSOHPHQW�VLPSOHZRUG�ZUDSSLQJ��7KH�ILUVW�WZR�SDUDPHWHUV�VSHFLI\�WKH�LQGHQWDWLRQ�RI�WKH�ILUVW�OLQH�DQGWKH�RWKHUV��UHVSHFWLYHO\��WKH�UHPDLQLQJ�SDUDPHWHUV�PDNH�XS�WKH�SDUDJUDSK¦V�WH[W�

use Text::Wrap;

my $message = "This is some sample text which may be longer " . "than the width of your output device, so it needs to " . "be wrapped to fit properly as a paragraph. ";$message x= 5;

Some Important Modules | 301

print wrap("\t", "", "$message\n");

The Time::Local Module,I�\RX�KDYH�D�WLPH��IRU�H[DPSOH��IURP�WKH�time�IXQFWLRQ��WKDW�QHHGV�WR�EH�FRQYHUWHG�WRD�OLVW�RI�\HDU��PRQWK��GD\��KRXU��PLQXWH��DQG�VHFRQG�YDOXHV��\RX�FDQ�GR�WKDW�ZLWK�3HUO¦VEXLOW�LQ�localtime�IXQFWLRQ�LQ�D�OLVW�FRQWH[W� ��,Q�D�VFDODU�FRQWH[W��WKDW�JLYHV�D�QLFHO\IRUPDWWHG�VWULQJ�UHSUHVHQWLQJ�WKH�WLPH��ZKLFK�LV�PRUH�RIWHQ�ZKDW�\RX¦G�ZDQW���%XW�LI\RX�QHHG�WR�JR�LQ�WKH�RWKHU�GLUHFWLRQ��\RX�PD\�XVH�WKH�timelocal�IXQFWLRQ�IURP�WKHTime::Local�PRGXOH�LQVWHDG��,W¦V�LPSRUWDQW�WR�QRWH�WKDW�WKH�YDOXH�RI�$mon�DQG�$year�IRU0DUFK������DUH�QRW�3�DQG�2008�DV�\RX�PLJKW�H[SHFW��VR�EH�VXUH�WR�UHDG�WKH�GRFXPHQ�WDWLRQ�EHIRUH�\RX�XVH�WKLV�PRGXOH��)RU�H[DPSOH�

use Time::Local;

my $time = timelocal($sec, $min, $hr, $day, $mon, $year);

Pragmas3UDJPDV�DUH�VSHFLDO�PRGXOHV�WKDW�FRPH�ZLWK�HDFK�UHOHDVH�RI�3HUO�DQG�WHOO�3HUO¦V�LQWHUQDOFRPSLOHU� VRPHWKLQJ�DERXW�\RXU�FRGH��<RX¦YH�DOUHDG\�XVHG� WKH�strict�SUDJPD��7KHSUDJPDV�DYDLODEOH�IRU�\RXU�UHOHDVH�RI�3HUO�VKRXOG�EH�OLVWHG�LQ�WKH�SHUOPRGOLE�PDQSDJH�

<RX�XVH�SUDJPDV�PXFK�OLNH�\RX¦G�XVH�RUGLQDU\�PRGXOHV��ZLWK�D�use�GLUHFWLYH��6RPHSUDJPDV�DUH�OH[LFDOO\�VFRSHG��OLNH�OH[LFDO��my��YDULDEOHV�DUH��DQG�WKH\�WKHUHIRUH�DSSO\�WRWKH�VPDOOHVW�HQFORVLQJ�EORFN�RU�ILOH��2WKHUV�PD\�DSSO\�WR�WKH�HQWLUH�SURJUDP�RU�WR�WKHFXUUHQW�SDFNDJH�� �,I� \RX�GRQ¦W�XVH� DQ\�SDFNDJHV�� WKH�SUDJPDV� DSSO\� WR� \RXU� HQWLUHSURJUDP���3UDJPDV� VKRXOG�JHQHUDOO\� DSSHDU�QHDU� WKH� WRS�RI� \RXU� VRXUFH� FRGH��7KHGRFXPHQWDWLRQ�IRU�HDFK�SUDJPD�VKRXOG�WHOO�\RX�KRZ�LW¦V�VFRSHG�

The constant Pragma,I�\RX¦YH�XVHG�RWKHU�ODQJXDJHV��\RX¦YH�SUREDEO\�VHHQ�WKH�DELOLW\�WR�GHFODUH�FRQVWDQWV�LQRQH�ZD\�RU�DQRWKHU��&RQVWDQWV�DUH�KDQG\�IRU�PDNLQJ�D�VHWWLQJ�MXVW�RQFH��QHDU�WKH�EH�JLQQLQJ�RI�D�SURJUDP��EXW�WKDW�FDQ�HDVLO\�EH�XSGDWHG�LI�WKH�QHHG�DULVHV��3HUO�FDQ�GR�WKLVZLWK�WKH�SDFNDJH�VFRSHG�constant�SUDJPD��ZKLFK�WHOOV�WKH�FRPSLOHU�WKDW�D�JLYHQ�LGHQ�WLILHU� KDV� D� FRQVWDQW� YDOXH��ZKLFK�PD\� WKXV� EH� RSWLPL]HG�ZKHUHYHU� LW� DSSHDUV�� )RUH[DPSOH�

use constant DEBUGGING => 0;use constant ONE_YEAR => 365.2425 * 24 * 60 * 60;

if (DEBUGGING) {

7KH�DFWXDO� UHWXUQ�YDOXH�RI�localtime� LQ� D� OLVW� FRQWH[W� LV� D� OLWWOH�GLIIHUHQW� WKDQ�\RX�PLJKW� H[SHFW�� VHH� WKHGRFXPHQWDWLRQ�

302 | Appendix B:ಗBeyond the Llama

# This code will be optimized away unless DEBUGGING is turned on ...}

The diagnostics Pragma3HUO¦V�GLDJQRVWLF�PHVVDJHV�RIWHQ�VHHP�VRPHZKDW�FU\SWLF��DW�OHDVW�WKH�ILUVW�WLPH�\RX�VHHWKHP��%XW�\RX�FDQ�DOZD\V�ORRN�WKHP�XS�LQ�WKH�SHUOGLDJ�PDQSDJH�WR�ILQG�RXW�ZKDW�WKH\PHDQ��DQG�RIWHQ�D�OLWWOH�DERXW�ZKDW¦V�OLNHO\�WR�EH�WKH�SUREOHP�DQG�KRZ�WR�IL[�LW��%XW�\RXFDQ�VDYH�\RXUVHOI� WKH� WURXEOH�RI� VHDUFKLQJ� WKDW�PDQSDJH� LI�\RX�XVH� WKH�diagnosticsSUDJPD��ZKLFK�WHOOV�3HUO�WR�WUDFN�GRZQ�DQG�SULQW�RXW�WKH�UHODWHG�LQIRUPDWLRQ�IRU�DQ\PHVVDJH��8QOLNH�PRVW�SUDJPDV��WKRXJK��WKLV�RQH�LV�QRW�LQWHQGHG�IRU�HYHU\GD\�XVH��DV�LWPDNHV�\RXU�SURJUDP�UHDG�WKH�HQWLUH�SHUOGLDJ�PDQSDJH�MXVW�WR�JHW�VWDUWHG���7KLV�LV�SR�WHQWLDOO\�D�VLJQLILFDQW�DPRXQW�RI�RYHUKHDG��ERWK�LQ�WHUPV�RI�WLPH�DQG�PHPRU\���8VH�WKLVSUDJPD�RQO\�ZKHQ�\RX¦UH�GHEXJJLQJ�DQG�H[SHFWLQJ�WR�JHW�HUURU�PHVVDJHV�\RX�GRQ¦W�\HWXQGHUVWDQG��,W�DIIHFWV�\RXU�HQWLUH�SURJUDP��7KH�V\QWD[�LV�

use diagnostics;

The lib Pragma,W¦V�QHDUO\�DOZD\V�EHVW� WR� LQVWDOO�PRGXOHV� LQ� WKH�VWDQGDUG�GLUHFWRULHV�VR� WKDW� WKH\¦UHDYDLODEOH�IRU�HYHU\RQH��EXW�RQO\�WKH�V\VWHP�DGPLQLVWUDWRU�FDQ�GR�WKDW��,I�\RX�LQVWDOO�\RXURZQ�PRGXOHV��\RX¦OO�KDYH�WR�VWRUH�WKHP�LQ�\RXU�RZQ�GLUHFWRULHV¢VR��KRZ�ZLOO�3HUONQRZ�ZKHUH�WR�ILQG�WKHP"�7KDW¦V�ZKDW�WKH�lib�SUDJPD�LV�DOO�DERXW��,W�WHOOV�3HUO�WKDW�WKHJLYHQ�GLUHFWRU\�LV�WKH�ILUVW�SODFH�WR�ORRN�IRU�PRGXOHV���7KDW�PHDQV�WKDW�LW¦V�DOVR�XVHIXOIRU�WU\LQJ�RXW�D�QHZ�UHOHDVH�RI�D�JLYHQ�PRGXOH���,W�DIIHFWV�DOO�PRGXOHV�ORDGHG�IURP�WKLVSRLQW�RQ��7KH�V\QWD[�LV�

use lib '/home/rootbeer/experimental';

%H�VXUH�WR�XVH�D�QRQUHODWLYH�SDWKQDPH�DV�WKH�DUJXPHQW��VLQFH�WKHUH¦V�QR�WHOOLQJ�ZKDWZLOO�EH� WKH�FXUUHQW�ZRUNLQJ�GLUHFWRU\�ZKHQ�\RXU�SURJUDP� LV� UXQ��7KLV� LV� HVSHFLDOO\LPSRUWDQW�IRU�&*,�SURJUDPV��WKDW�LV��SURJUDPV�UXQ�E\�D�ZHE�VHUYHU��

The strict Pragma<RX¦YH�EHHQ�XVLQJ�use strict�IRU�D�ZKLOH�DOUHDG\�ZLWKRXW�KDYLQJ�WR�XQGHUVWDQG�WKDWLW¦V�D�SUDJPD��,W¦V�OH[LFDOO\�VFRSHG��DQG�LW�HQIRUFHV�VRPH�JRRG�SURJUDPPLQJ�UXOHV��6HHLWV�GRFXPHQWDWLRQ�WR�OHDUQ�ZKDW�UHVWULFWLRQV�DUH�DYDLODEOH�LQ�\RXU�UHOHDVH�RI�3HUO��7KH$OSDFD�WDONV�DERXW�RWKHU�WKLQJV�WKDW�WKH�strict�PRGXOH�DFWXDOO\�SHUIRUPV�

Pragmas | 303

The vars Pragma,Q�WKH�UDUH�FDVH�WKDW�\RX�WUXO\�QHHG�D�JOREDO�YDULDEOH�ZKLOH�use strict�LV�LQ�HIIHFW��\RXPD\�GHFODUH�LW�ZLWK�WKH�vars�SUDJPD� �7KLV�SDFNDJH�VFRSHG�SUDJPD�WHOOV�3HUO�WKDW�\RXDUH�LQWHQWLRQDOO\�XVLQJ�RQH�RU�PRUH�JOREDO�YDULDEOHV�

use strict;use vars qw/ $fred $barney /;

$fred = "This is a global variable, but that's all right.\n";

7KLV�LV�FRYHUHG�LQ�JUHDWHU�GHDO�LQ�WKH�$OSDFD�

The warnings Pragma6WDUWLQJ�LQ�3HUO�YHUVLRQ������\RX�PD\�FKRRVH�WR�KDYH�OH[LFDOO\�VFRSHG�ZDUQLQJV�ZLWK�WKHwarnings�SUDJPD���7KDW�LV��UDWKHU�WKDQ�XVLQJ�WKH�-w�RSWLRQ�FUXGHO\�WR�WXUQ�ZDUQLQJV�RQRU�RII�IRU�WKH�HQWLUH�SURJUDP�DW�RQFH��\RX�PD\�VSHFLI\�WKDW�\RX�ZDQW�QR�ZDUQLQJV�DERXWXQGHILQHG�YDOXHV�LQ�MXVW�RQH�VHFWLRQ�RI�FRGH��ZKLOH�RWKHU�ZDUQLQJV�VKRXOG�EH�DYDLODEOH�7KLV�DOVR�VHUYHV�DV�D�VLJQDO�WR�WKH�PDLQWHQDQFH�SURJUDPPHU�WKDW�VD\V��£,�NQRZ�WKDW�WKLVFRGH�ZRXOG�SURGXFH�ZDUQLQJV��EXW�,�NQRZ�ZKDW�,¦P�GRLQJ�DQ\ZD\�¤�6HH�WKH�GRFX�PHQWDWLRQ�IRU�WKLV�SUDJPD�WR�OHDUQ�DERXW�WKH�FDWHJRULHV�RI�ZDUQLQJV�DYDLODEOH�LQ�\RXUUHOHDVH�RI�3HUO�

Databases,I� \RX¦YH�JRW�D�GDWDEDVH��3HUO� FDQ�ZRUN�ZLWK� LW��7KLV� VHFWLRQ�GHVFULEHV� VRPH�RI� WKHFRPPRQ�W\SHV�RI�GDWDEDVHV��:H¦YH�DOUHDG\�VHHQ�WKH�DBI�PRGXOH�EULHIO\�LQ�&KDSWHU����

Direct System Database Access3HUO�FDQ�GLUHFWO\�DFFHVV�VRPH�V\VWHP�GDWDEDVHV��VRPHWLPHV�ZLWK�WKH�KHOS�RI�D�PRGXOH�7KHVH�DUH�GDWDEDVHV�OLNH�WKH�:LQGRZV�5HJLVWU\��ZKLFK�KROGV�PDFKLQH�OHYHO�VHWWLQJV��RU� WKH�8QL[�SDVVZRUG�GDWDEDVH� �ZKLFK� OLVWV�ZKLFK�XVHUQDPH�FRUUHVSRQGV� WR�ZKLFKQXPEHU��DQG�UHODWHG�LQIRUPDWLRQ���DV�ZHOO�DV�WKH�GRPDLQ�QDPH�GDWDEDVH��ZKLFK�OHWV\RX�WUDQVODWH�DQ�,3�QXPEHU�LQWR�D�PDFKLQH�QDPH��DQG�YLFH�YHUVD��

,I�\RXU�SURJUDP�ZLOO�QHYHU�EH�XVHG�ZLWK�D�YHUVLRQ�RI�3HUO�SULRU�WR������\RX�VKRXOG�XVH�WKH�our�NH\ZRUG�LQVWHDGRI�WKH�vars�SUDJPD�

� ,I�\RXU�SURJUDP�PD\�EH�XVHG�ZLWK�D�YHUVLRQ�RI�3HUO�SULRU�WR������\RX�VKRXOG�QRW�XVH�WKH�warnings�SUDJPD�

304 | Appendix B:ಗBeyond the Llama

Flat-file Database Access,I�\RX¦G�OLNH�WR�DFFHVV�\RXU�RZQ�IODW�ILOH�GDWDEDVHV�IURP�3HUO��WKHUH�DUH�PRGXOHV�WR�KHOS\RX�ZLWK�GRLQJ�WKDW��VHHPLQJO\�D�QHZ�RQH�HYHU\�PRQWK�RU�WZR��VR�DQ\�OLVW�KHUH�ZRXOGEH�RXW�RI�GDWH��

Other Operators and Functions<HV��WKHUH�DUH�PRUH�RSHUDWRUV�DQG�IXQFWLRQV�WKDQ�ZH�FDQ�ILW�KHUH��IURP�WKH�VFDODU�..RSHUDWRU�WR�WKH�VFDODU�,�RSHUDWRU��IURP�wantarray�WR�goto�����IURP�caller�WR�chr��6HH�WKHSHUORS�DQG�SHUOIXQF�PDQSDJHV�

Transliteration with tr///7KH�tr///�RSHUDWRU�ORRNV�OLNH�D�UHJXODU�H[SUHVVLRQ��EXW�LW¦V�UHDOO\�IRU�WUDQVOLWHUDWLQJ�RQHJURXS�RI�FKDUDFWHUV�LQWR�DQRWKHU��,W�FDQ�DOVR�HIILFLHQWO\�FRXQW�VHOHFWHG�FKDUDFWHUV��6HHWKH�SHUORS�PDQSDJH�

Here Documents+HUH�GRFXPHQWV�DUH�D�XVHIXO�IRUP�RI�PXOWLOLQH�VWULQJ�TXRWLQJ��VHH�WKH�SHUOGDWD�PDQSDJH�

Mathematics3HUO�FDQ�GR�MXVW�DERXW�DQ\�NLQG�RI�PDWKHPDWLFV�\RX�FDQ�GUHDP�XS�

Advanced Math Functions$OO�RI�WKH�EDVLF�PDWKHPDWLFDO�IXQFWLRQV��VTXDUH�URRW��FRVLQH��ORJDULWKP��DEVROXWH�YDOXH�DQG�PDQ\�RWKHUV��DUH�DYDLODEOH�DV�EXLOW�LQ�IXQFWLRQV��VHH�WKH�SHUOIXQF�PDQSDJH�IRU�GH�WDLOV��6RPH�RWKHUV��OLNH�WDQJHQW�RU�EDVH����ORJDULWKP��DUH�RPLWWHG��EXW�WKRVH�PD\�EHHDVLO\�FUHDWHG�IURP�WKH�EDVLF�RQHV��RU�ORDGHG�IURP�D�VLPSOH�PRGXOH�WKDW�GRHV�VR���6HHWKH�POSIX�PRGXOH�IRU�PDQ\�FRPPRQ�PDWK�IXQFWLRQV��

Imaginary and Complex Numbers$OWKRXJK�WKH�FRUH�RI�3HUO�GRHVQ¦W�GLUHFWO\�VXSSRUW�WKHP��WKHUH�DUH�PRGXOHV�DYDLODEOHIRU�ZRUNLQJ�ZLWK�FRPSOH[�QXPEHUV��7KHVH�RYHUORDG�WKH�QRUPDO�RSHUDWRUV�DQG�IXQF�WLRQV�VR�WKDW�\RX�FDQ�VWLOO�PXOWLSO\�ZLWK�*�DQG�JHW�D�VTXDUH�URRW�ZLWK�sqrt��HYHQ�ZKHQXVLQJ�FRPSOH[�QXPEHUV��6HH�WKH�Math::Complex�PRGXOH�

Other Operators and Functions | 305

Large and High-Precision Numbers<RX�FDQ�GR�PDWK�ZLWK�DUELWUDULO\�ODUJH�QXPEHUV�ZLWK�DQ�DUELWUDU\�QXPEHU�RI�GLJLWV�RIDFFXUDF\��)RU�H[DPSOH��\RX�FRXOG�FDOFXODWH�WKH�IDFWRULDO�RI��������RU�GHWHUPLQH�˭�WR�������GLJLWV��6HH�WKH�Math::BigInt�DQG�Math::BigFloat�PRGXOHV�

Lists and Arrays3HUO�KDV�D�QXPEHU�RI�IHDWXUHV�WKDW�PDNH�LW�HDV\�WR�PDQLSXODWH�DQ�HQWLUH�OLVW�RU�DUUD\�

map and grep:H�PHQWLRQHG��LQ�&KDSWHU�����WKH�map�DQG�grep�OLVW�SURFHVVLQJ�RSHUDWRUV��7KH\�FDQ�GRPRUH�WKDQ�ZH�FRXOG�LQFOXGH�KHUH��VHH�WKH�SHUOIXQF�PDQSDJH�IRU�PRUH�LQIRUPDWLRQ�DQGH[DPSOHV��$QG�FKHFN�RXW�WKH�$OSDFD�IRU�PRUH�ZD\V�WR�XVH�map�DQG�grep�

The splice Operator:LWK�WKH�splice�RSHUDWRU��\RX�FDQ�DGG�LWHPV�WR�WKH�PLGGOH�RI�DQ�DUUD\��RU�UHPRYH�WKHP�OHWWLQJ�WKH�DUUD\�JURZ�RU�VKULQN�DV�QHHGHG���5RXJKO\��WKLV�LV�OLNH�ZKDW�substr�OHWV�\RXGR�ZLWK�VWULQJV���7KLV�HIIHFWLYHO\�HOLPLQDWHV�WKH�QHHG�IRU� OLQNHG�OLVWV� LQ�3HUO��6HH�WKHSHUOIXQF�PDQSDJH�

Bits and Pieces<RX�FDQ�ZRUN�ZLWK�DQ�DUUD\�RI�ELWV��D�ELWVWULQJ���ZLWK�WKH�vec�RSHUDWRU��VHWWLQJ�ELW�QXPEHU�����FOHDULQJ�ELW�QXPEHU������DQG�FKHFNLQJ�WR�VHH�WKH�VWDWH�RI�ELW������%LWVWULQJV�PD\EH�RI�DUELWUDU\�VL]H��7KH�vec�RSHUDWRU�FDQ�DOVR�ZRUN�ZLWK�FKXQNV�RI�RWKHU�VL]HV��DV�ORQJDV�WKH�VL]H�LV�D�VPDOO�SRZHU�RI�WZR��VR�LW¦V�XVHIXO�LI�\RX�QHHG�WR�YLHZ�D�VWULQJ�DV�D�FRPSDFWDUUD\�RI�Q\EEOHV��VD\��6HH�WKH�SHUOIXQF�PDQSDJH�

Formats3HUO¦V�IRUPDWV�DUH�DQ�HDV\�ZD\�WR�PDNH�IL[HG�IRUPDW�WHPSODWH�GULYHQ�UHSRUWV�ZLWK�DX�WRPDWLF�SDJH�KHDGHUV��,Q�IDFW��WKH\�DUH�RQH�RI�WKH�PDLQ�UHDVRQV�/DUU\�GHYHORSHG�3HUO�LQWKH�ILUVW�SODFH��DV�D�3UDFWLFDO�([WUDFWLRQ�DQG�5HSRUW�/DQJXDJH��%XW��DODV��WKH\¦UH�OLPLWHG�7KH�KHDUWEUHDN�RI�IRUPDWV�KDSSHQV�ZKHQ�VRPHRQH�GLVFRYHUV�WKDW�KH�RU�VKH�QHHGV�DOLWWOH�PRUH�WKDQ�ZKDW�IRUPDWV�SURYLGH��7KLV�XVXDOO\�PHDQV�ULSSLQJ�RXW�WKH�SURJUDP¦VHQWLUH�RXWSXW�VHFWLRQ�DQG�UHSODFLQJ�LW�ZLWK�FRGH�WKDW�GRHVQ¦W�XVH�IRUPDWV��6WLOO��LI�\RX¦UHVXUH�WKDW�IRUPDWV�GR�ZKDW�\RX�QHHG��DOO�WKDW�\RX¦OO�QHHG��DQG�DOO�WKDW�\RX¦OO�HYHU�QHHG�WKH\�DUH�SUHWW\�FRRO��6HH�WKH�SHUOIRUP�PDQSDJH�

306 | Appendix B:ಗBeyond the Llama

Networking and IPC,I�WKHUH¦V�D�ZD\�WKDW�SURJUDPV�RQ�\RXU�PDFKLQH�FDQ�WDON�ZLWK�RWKHUV��3HUO�FDQ�SUREDEO\GR�LW��7KLV�VHFWLRQ�VKRZV�VRPH�FRPPRQ�ZD\V�

System V IPC7KH�VWDQGDUG�IXQFWLRQV�IRU�6\VWHP�9�,3&��LQWHUSURFHVV�FRPPXQLFDWLRQ��DUH�DOO�VXS�SRUWHG�E\�3HUO��VR�\RX�FDQ�XVH�PHVVDJH�TXHXHV��VHPDSKRUHV��DQG�VKDUHG�PHPRU\��2IFRXUVH��DQ�DUUD\�LQ�3HUO�LVQ¦W�VWRUHG�LQ�D�FKXQN�RI�PHPRU\�LQ�WKH�VDPH�ZD\ �WKDW�DQ�DUUD\LV�VWRUHG�LQ�&��VR�VKDUHG�PHPRU\�FDQ¦W�VKDUH�3HUO�GDWD�DV�LV��%XW�WKHUH�DUH�PRGXOHV�WKDWZLOO�WUDQVODWH�GDWD��VR�WKDW�\RX�FDQ�SUHWHQG�WKDW�\RXU�3HUO�GDWD�LV�LQ�VKDUHG�PHPRU\��6HHWKH�SHUOIXQF�PDQSDJH�DQG�WKH�SHUOLSF�PRGXOH�

Sockets3HUO�KDV�IXOO�VXSSRUW�IRU�7&3�,3�VRFNHWV��ZKLFK�PHDQV�WKDW�\RX�FRXOG�ZULWH�D�ZHE�VHUYHULQ�3HUO��RU�D�ZHE�EURZVHU��8VHQHW�QHZV�VHUYHU�RU�FOLHQW��ILQJHU�GDHPRQ�RU�FOLHQW��)73GDHPRQ�RU�FOLHQW��6073�RU�323�RU�62$3�VHUYHU�RU�FOLHQW��RU�HLWKHU�HQG�RI�SUHWW\�PXFKDQ\�RWKHU�NLQG�RI�SURWRFRO�LQ�XVH�RQ�WKH�,QWHUQHW��2I�FRXUVH��WKHUH¦V�QR�QHHG�WR�JHW�LQWRWKH�ORZ�OHYHO�GHWDLOV�\RXUVHOI��WKHUH�DUH�PRGXOHV�DYDLODEOH�IRU�DOO�RI�WKH�FRPPRQ�SUR�WRFROV��)RU�H[DPSOH��\RX�FDQ�PDNH�D�ZHE�VHUYHU�RU�FOLHQW�ZLWK�WKH�LWP�PRGXOH�DQG�RQHRU�WZR�OLQHV�RI�DGGLWLRQDO�FRGH���7KH�LWP�PRGXOH��DFWXDOO\��D�WLJKWO\�LQWHJUDWHG�VHW�RIPRGXOHV�WKDW�WRJHWKHU�LPSOHPHQW�QHDUO\�HYHU\WKLQJ�WKDW�KDSSHQV�RQ�WKH�:HE��LV�DOVRD�JUHDW�H[DPSOH�RI�KLJK�TXDOLW\�3HUO�FRGH��LI�\RX¦G�OLNH�WR�FRS\�IURP�WKH�EHVW��)RU�RWKHUSURWRFROV��VHDUFK�IRU�D�PRGXOH�ZLWK�WKH�SURWRFRO¦V�QDPH�

Security3HUO�KDV�D�QXPEHU�RI�VWURQJ�VHFXULW\�UHODWHG�IHDWXUHV�WKDW�FDQ�PDNH�D�SURJUDP�ZULWWHQLQ�3HUO�PRUH�VHFXUH�WKDQ�WKH�FRUUHVSRQGLQJ�SURJUDP�ZULWWHQ�LQ�&��3UREDEO\�WKH�PRVWLPSRUWDQW�RI�WKHVH�LV�GDWD�IORZ�DQDO\VLV��EHWWHU�NQRZQ�DV�WDLQW�FKHFNLQJ��:KHQ�WKLV�LVHQDEOHG��3HUO�NHHSV�WUDFN�RI�ZKLFK�SLHFHV�RI�GDWD�VHHP�WR�KDYH�FRPH�IURP�WKH�XVHU�RUHQYLURQPHQW��DQG�DUH�WKHUHIRUH�XQWUXVWZRUWK\���*HQHUDOO\��LI�DQ\�VXFK�SLHFH�RI�VR�FDOOHG£WDLQWHG¤�GDWD�LV�XVHG�WR�DIIHFW�DQRWKHU�SURFHVV��ILOH��RU�GLUHFWRU\��3HUO�ZLOO�SURKLELW�WKH

,Q�IDFW��LW�ZRXOG�JHQHUDOO\�EH�D�OLH�WR�VD\�WKDW�D�3HUO�DUUD\�LV�VWRUHG�LQ�£D�FKXQN�RI�PHPRU\¤�DW�DOO��DV�LW¦V�DOPRVWFHUWDLQO\�VSUHDG�DPRQJ�PDQ\�VHSDUDWH�FKXQNV�

� $OWKRXJK�LWP�PDNHV� LW� HDV\� WR�PDNH�D� VLPSOH�£ZHE�EURZVHU¤� WKDW�SXOOV�GRZQ�D�SDJH�RU� LPDJH��DFWXDOO\UHQGHULQJ�WKDW�WR�WKH�XVHU�LV�DQRWKHU�SUREOHP��<RX�FDQ�GULYH�DQ�;���GLVSOD\�ZLWK�7N�RU�*WN�ZLGJHWV�WKRXJK�RU�XVH�FXUVHV�WR�GUDZ�RQ�D�FKDUDFWHU�WHUPLQDO��,W¦V�DOO�D�PDWWHU�RI�GRZQORDGLQJ�DQG�LQVWDOOLQJ�WKH�ULJKW�PRGXOHVIURP�&3$1�

Networking and IPC | 307

RSHUDWLRQ�DQG�DERUW�WKH�SURJUDP��,W¦V�QRW�SHUIHFW��EXW�LW¦V�D�SRZHUIXO�ZD\�WR�SUHYHQWVRPH�VHFXULW\�UHODWHG�PLVWDNHV��7KHUH¦V�PRUH�WR�WKH�VWRU\��VHH�WKH�SHUOVHF�PDQSDJH�

Debugging7KHUH¦V�D�YHU\�JRRG�GHEXJJHU�WKDW�FRPHV�ZLWK�3HUO�DQG�VXSSRUWV�EUHDNSRLQWV��ZDWFK�SRLQWV��VLQJOH�VWHSSLQJ��DQG�JHQHUDOO\�HYHU\WKLQJ�\RX¦G�ZDQW�LQ�D�FRPPDQG�OLQH�3HUOGHEXJJHU��,W¦V�DFWXDOO\�ZULWWHQ�LQ�3HUO��VR��LI�WKHUH�DUH�EXJV�LQ�WKH�GHEXJJHU��ZH¦UH�QRWVXUH�KRZ�WKH\�JHW�WKRVH�RXW���%XW�WKDW�PHDQV�WKDW��LQ�DGGLWLRQ�WR�DOO�RI�WKH�XVXDO�GHEXJJHUFRPPDQGV��\RX�FDQ�DFWXDOO\�UXQ�3HUO�FRGH�IURP�WKH�GHEXJJHU¢FDOOLQJ�\RXU�VXEURX�WLQHV��FKDQJLQJ�YDULDEOHV��HYHQ�UHGHILQLQJ�VXEURXWLQHV¢ZKLOH�\RXU�SURJUDP�LV�UXQQLQJ�6HH� WKH�SHUOGHEXJ�PDQSDJH� IRU� WKH� ODWHVW�GHWDLOV��7KH�$OSDFD�JLYHV�D�GHWDLOHG�ZDON�WKURXJK�RI�WKH�GHEXJJHU�

$QRWKHU�GHEXJJLQJ�WDFWLF� LV� WR�XVH� WKH�B::Lint�PRGXOH��ZKLFK�FDQ�ZDUQ�\RX�DERXWSRWHQWLDO�SUREOHPV�WKDW�HYHQ�WKH�-w�VZLWFK�PLVVHV�

The Common Gateway Interface (CGI)2QH�RI�WKH�PRVW�SRSXODU�XVHV�IRU�3HUO�RQ�WKH�:HE�LV�ZULWLQJ�&*,�SURJUDPV��7KHVH�UXQRQ�D�ZHE�VHUYHU�WR�SURFHVV�WKH�UHVXOWV�RI�D�IRUP��SHUIRUP�D�VHDUFK��SURGXFH�G\QDPLFZHE�FRQWHQW��RU�FRXQW�WKH�QXPEHU�RI�DFFHVVHV�WR�D�ZHE�SDJH�

7KH�CGI�PRGXOH��ZKLFK�FRPHV�ZLWK�3HUO��SURYLGHV�DQ�HDV\�ZD\�WR�DFFHVV�WKH�IRUP�SD�UDPHWHUV�DQG�WR�JHQHUDWH�VRPH�+70/�LQ�UHVSRQVHV��,W�PD\�EH�WHPSWLQJ�WR�VNLS�WKHPRGXOH�DQG�VLPSO\�FRS\�DQG�SDVWH�RQH�RI�WKH�VQLSSHWV�RI�FRGH�WKDW�SXUSRUW�WR�JLYHDFFHVV�WR�WKH�IRUP�SDUDPHWHUV��EXW�QHDUO\�DOO�RI�WKHVH�DUH�EXJJ\� �:KHQ�ZULWLQJ�&*,SURJUDPV��WKRXJK��WKHUH�DUH�VHYHUDO�ELJ�LVVXHV�WR�NHHS�LQ�PLQG��7KHVH�PDNH�WKLV�WRSLFWRR�EURDG�WR�IXOO\�LQFOXGH�LQ�WKLV�ERRN��

6HFXULW\��VHFXULW\��VHFXULW\:H�FDQ¦W�RYHUHPSKDVL]H�VHFXULW\��6RPHZKHUH�DURXQG�KDOI�RI�WKH�VXFFHVVIXO�DWWDFNVRQ�FRPSXWHUV�DURXQG�WKH�ZRUOG�LQYROYH�D�VHFXULW\�UHODWHG�EXJ�LQ�D�&*,�SURJUDP�

&RQFXUUHQF\�LVVXHV,W¦V�HDV\�WR�KDYH�VHYHUDO�SURFHVVHV�WKDW�DUH�FRQFXUUHQWO\�WU\LQJ�WR�DFFHVV�D�VLQJOH�ILOHRU�UHVRXUFH�

7KHUH�DUH�VRPH�GHWDLOV�RI�WKH�LQWHUIDFH�WKDW�WKHVH�VQLSSHWV�GRQ¦W�VXSSRUW��7UXVW�XV��LW¦V�EHWWHU�WR�XVH�D�PRGXOH�

� 6HYHUDO�RI�WKH�UHYLHZHUV�ZKR�ORRNHG�RYHU�D�GUDIW�RI�WKLV�ERRN�IRU�XV�ZLVKHG�ZH�FRXOG�FRYHU�PRUH�DERXW�&*,SURJUDPPLQJ��:H�DJUHH��EXW�LW�ZRXOGQ¦W�EH�IDLU�WR�WKH�UHDGHU�WR�JLYH�MXVW�HQRXJK�NQRZOHGJH�WR�EH�GDQJHURXV�$�SURSHU�GLVFXVVLRQ�RI�WKH�SUREOHPV�LQKHUHQW�LQ�&*,�SURJUDPPLQJ�ZRXOG�SUREDEO\�DGG�DW�OHDVW�����WR�WKHVL]H��DQG�FRVW��RI�WKLV�ERRN�

308 | Appendix B:ಗBeyond the Llama

6WDQGDUGV�FRPSOLDQFH1R�PDWWHU�KRZ�KDUG�\RX�WU\��\RX�SUREDEO\�ZRQ¦W�EH�DEOH�WR�WHVW�\RXU�SURJUDPWKRURXJKO\�ZLWK�PRUH�WKDQ�DERXW���RU����RI�WKH�ZHE�EURZVHUV�DQG�VHUYHUV�WKDW�DUHLQ�XVH�WRGD\� �7KDW¦V�EHFDXVH�WKHUH�DUH�OLWHUDOO\�WKRXVDQGV�RI�GLIIHUHQW�SURJUDPVDYDLODEOH��ZLWK�QHZ�RQHV�SRSSLQJ�XS�HYHU\�ZHHN��7KH�VROXWLRQ� LV� WR� IROORZ�WKHVWDQGDUGV��VR�\RXU�SURJUDP�ZLOO�ZRUN�ZLWK�DOO�RI�WKHP��

7URXEOHVKRRWLQJ�DQG�GHEXJJLQJ6LQFH�WKH�&*,�SURJUDP�UXQV�LQ�D�GLIIHUHQW�HQYLURQPHQW�WKDQ�\RX¦UH�OLNHO\�WR�EH�DEOHWR�DFFHVV�GLUHFWO\�� \RX¦OO�KDYH� WR� OHDUQ�QHZ� WHFKQLTXHV� IRU� WURXEOHVKRRWLQJ�DQGGHEXJJLQJ�

6HFXULW\��VHFXULW\��VHFXULW\�7KHUH��ZH¦YH�VDLG�LW�DJDLQ��'RQ¦W�IRUJHW�VHFXULW\¢LW¦V�WKH�ILUVW�DQG�ODVW�WKLQJ�WR�WKLQNDERXW�ZKHQ�\RXU�SURJUDP�LV�JRLQJ�WR�EH�DYDLODEOH�WR�HYHU\RQH�LQ�WKH�ZRUOG�ZKRZDQWV�WR�WU\�EUHDNLQJ�LW�

$QG�WKDW�OLVW�GLGQ¦W�HYHQ�PHQWLRQ�85,�HQFRGLQJ��+70/�HQWLWLHV��+773�DQG�UHVSRQVHFRGHV��6HFXUH�6RFNHWV�/D\HU��66/���6HUYHU�6LGH�,QFOXGHV��66,���KHUH�GRFXPHQWV��FUHDWLQJJUDSKLFV�RQ�WKH�IO\��SURJUDPPDWLFDOO\�JHQHUDWLQJ�+70/�WDEOHV��IRUPV��DQG�ZLGJHWV�KLGGHQ�IRUP�HOHPHQWV��JHWWLQJ�DQG�VHWWLQJ�FRRNLHV��SDWK�LQIR��HUURU�WUDSSLQJ��UHGLUHF�WLRQ��WDLQW�FKHFNLQJ��LQWHUQDWLRQDOL]DWLRQ�DQG�ORFDOL]DWLRQ��HPEHGGLQJ�3HUO�LQWR�+70/�RU�WKH�RWKHU�ZD\�DURXQG���ZRUNLQJ�ZLWK�$SDFKH�DQG�mod_perl��DQG�XVLQJ�WKH�LWP�PRG�XOH�®�0RVW�RU�DOO�RI�WKRVH�WRSLFV�VKRXOG�EH�FRYHUHG�LQ�DQ\�JRRG�ERRN�RQ�XVLQJ�3HUO�ZLWKWKH�:HE��&*,�3URJUDPPLQJ�ZLWK�3HUO�E\�6FRWW�*XHOLFK�HW�DO���2¦5HLOO\��LV�PLJKW\�QLFHKHUH��DV�LV�/LQFROQ�6WHLQ¦V�1HWZRUN�3URJUDPPLQJ�ZLWK�3HUO��$GGLVRQ�:HVOH\��

Command-Line Options7KHUH�DUH�PDQ\�GLIIHUHQW�FRPPDQG�OLQH�RSWLRQV�DYDLODEOH�LQ�3HUO��PDQ\�OHW�\RX�ZULWHXVHIXO�SURJUDPV�GLUHFWO\�IURP�WKH�FRPPDQG�OLQH��6HH�WKH�SHUOUXQ�PDQSDJH�

Built-in Variables3HUO�KDV�GR]HQV�RI�EXLOW�LQ�YDULDEOHV��OLNH�@ARGV�DQG�$0���ZKLFK�SURYLGH�XVHIXO�LQIRUPD�WLRQ�RU�FRQWURO�WKH�RSHUDWLRQ�RI�3HUO�LWVHOI��6HH�WKH�SHUOYDU�PDQSDJH�

5HPHPEHU�WKDW�HYHU\�QHZ�UHOHDVH�RI�HDFK�EUDQG�RI�EURZVHU�RQ�HDFK�GLIIHUHQW�SODWIRUP�FRXQWV�DV�D�QHZ�RQHWKDW�\RX¦UH�SUREDEO\�QRW�JRLQJ�WR�EH�DEOH�WR�WHVW��:H�UHDOO\�FKXFNOH�ZKHQ�ZH�KHDU�VRPHRQH�WHVWHG�D�ZHE�VLWHZLWK�£ERWK�EURZVHUV¤�RU�ZKHQ�WKH\�VD\��£,�GRQ¦W�NQRZ�LI�LW�ZRUNV�ZLWK�WKH�RWKHU�RQH�¤

� $W�WKH�YHU\�OHDVW��IROORZLQJ�WKH�VWDQGDUGV�OHWV�\RX�SXW�WKH�EODPH�VTXDUHO\�RQ�WKH�RWKHU�SURJUDPPHU��ZKRGLGQ¦W�

® 'R�\RX�VHH�ZK\�ZH�GLGQ¦W�WU\�WR�ILW�DOO�RI�WKDW�LQWR�WKLV�ERRN"

Command-Line Options | 309

Syntax Extensions7KHUH�DUH�PRUH�WULFNV�\RX�FRXOG�GR�ZLWK�3HUO�V\QWD[��LQFOXGLQJ�WKH�continue�EORFN�DQGWKH�BEGIN�EORFN��6HH�WKH�SHUOV\Q�DQG�SHUOPRG�PDQSDJHV�

References3HUO¦V�UHIHUHQFHV�DUH�VLPLODU�WR�&¦V�SRLQWHUV��EXW�LQ�RSHUDWLRQ��WKH\¦UH�PRUH�OLNH�ZKDW\RX�KDYH�LQ�3DVFDO�RU�$GD��$�UHIHUHQFH�£SRLQWV¤�WR�D�PHPRU\�ORFDWLRQ��EXW�EHFDXVHWKHUH¦V�QR�SRLQWHU�DULWKPHWLF�RU�GLUHFW�PHPRU\�DOORFDWLRQ�DQG�GHDOORFDWLRQ��\RX�FDQ�EHVXUH�WKDW�DQ\�UHIHUHQFH�\RX�KDYH�LV�D�YDOLG�RQH��5HIHUHQFHV�DOORZ�REMHFW�RULHQWHG�SUR�JUDPPLQJ�DQG�FRPSOH[�GDWD�VWUXFWXUHV��DPRQJ�RWKHU�QLIW\�WULFNV��6HH�WKH�SHUOUHIWXW�DQGSHUOUHI�PDQSDJHV��7KH�$OSDFD�FRYHUV�UHIHUHQFHV�LQ�JUHDW�GHWDLO�

Complex Data Structures5HIHUHQFHV�DOORZ�XV�WR�PDNH�FRPSOH[�GDWD�VWUXFWXUHV�LQ�3HUO��)RU�H[DPSOH��VXSSRVH\RX�ZDQW�D�WZR�GLPHQVLRQDO�DUUD\��<RX�FDQ�GR�WKDW� �RU�\RX�FDQ�GR�VRPHWKLQJ�PXFKPRUH�LQWHUHVWLQJ��OLNH�KDYH�DQ�DUUD\�RI�KDVKHV��D�KDVK�RI�KDVKHV��RU�D�KDVK�RI�DUUD\V�RIKDVKHV���6HH�WKH�SHUOGVF��GDWD�VWUXFWXUHV�FRRNERRN��DQG�SHUOORO��OLVWV�RI�OLVWV��PDQSDJHV�$JDLQ��WKH�$OSDFD�FRYHUV�WKLV�TXLWH�WKRURXJKO\��LQFOXGLQJ�WHFKQLTXHV�IRU�FRPSOH[�GDWDPDQLSXODWLRQ��OLNH�VRUWLQJ�DQG�VXPPDUL]LQJ�

Object-Oriented Programming<HV�� 3HUO� KDV� REMHFWV�� LW¦V� EX]]ZRUG� FRPSDWLEOH� ZLWK� DOO� RI� WKRVH� RWKHU� ODQJXDJHV�2EMHFW�RULHQWHG��22��SURJUDPPLQJ�OHWV�\RX�FUHDWH�\RXU�RZQ�XVHU�GHILQHG�GDWD�W\SHVZLWK� DVVRFLDWHG� DELOLWLHV�� XVLQJ� LQKHULWDQFH�� RYHUULGLQJ�� DQG� G\QDPLF�PHWKRG� ORRN�XS�®�8QOLNH�VRPH�REMHFW�RULHQWHG�ODQJXDJHV��WKRXJK��3HUO�GRHVQ¦W�IRUFH�\RX�WR�XVH�RE�MHFWV���(YHQ�PDQ\�REMHFW�RULHQWHG�PRGXOHV�FDQ�EH�XVHG�ZLWKRXW�XQGHUVWDQGLQJ�REMHFWV��%XW�LI�\RXU�SURJUDP�LV�JRLQJ�WR�EH�ODUJHU�WKDQ�1�OLQHV�RI�FRGH��LW�PD\�EH�PRUH�HIILFLHQWIRU�WKH�SURJUDPPHU��LI�D�WLQ\�ELW�VORZHU�DW�UXQWLPH��WR�PDNH�LW�REMHFW�RULHQWHG��1R�RQHNQRZV�WKH�SUHFLVH�YDOXH�RI�1��EXW�ZH�HVWLPDWH�LW¦V�DURXQG�D�IHZ�WKRXVDQG�RU�VR��6HH�WKHSHUOREM� DQG�SHUOERRW�PDQSDJHV� IRU� D� VWDUW�� DQG�'DPLDQ�&RQZD\¦V� H[FHOOHQW�2EMHFW�2ULHQWHG�3HUO��0DQQLQJ�3UHVV��IRU�PRUH�DGYDQFHG�LQIRUPDWLRQ��7KH�$OSDFD�ERRN�FRYHUVREMHFWV�WKRURXJKO\�DV�ZHOO�

:HOO��QRW�UHDOO\��EXW�\RX�FDQ�IDNH�LW�VR�ZHOO�WKDW�\RX¦OO�KDUGO\�UHPHPEHU�WKDW�WKHUH¦V�D�GLIIHUHQFH�

� $FWXDOO\��\RX�FDQ¦W�PDNH�DQ\�RI�WKHVH�WKLQJV��WKHVH�DUH�MXVW�YHUEDO�VKRUWKDQGV�IRU�ZKDW¦V�UHDOO\�KDSSHQLQJ�:KDW�ZH�FDOO�£DQ�DUUD\�RI�DUUD\V¤�LQ�3HUO�LV�UHDOO\�DQ�DUUD\�RI�UHIHUHQFHV�WR�DUUD\V�

® 22�KDV�LWV�RZQ�VHW�RI�MDUJRQ�ZRUGV��,Q�IDFW��WKH�WHUPV�XVHG�LQ�DQ\�RQH�22�ODQJXDJH�DUHQ¦W�HYHQ�WKH�VDPHRQHV�WKDW�DUH�W\SLFDOO\�XVHG�LQ�DQRWKHU�

310 | Appendix B:ಗBeyond the Llama

Anonymous Subroutines and Closures2GG�DV�LW�PD\�VRXQG�DW�ILUVW��LW�FDQ�EH�XVHIXO�WR�KDYH�D�VXEURXWLQH�ZLWKRXW�D�QDPH��6XFKVXEURXWLQHV�FDQ�EH�SDVVHG�DV�SDUDPHWHUV�WR�RWKHU�VXEURXWLQHV��RU�WKH\�FDQ�EH�DFFHVVHGYLD�DUUD\V�RU�KDVKHV�WR�PDNH�MXPS�WDEOHV��&ORVXUHV�DUH�D�SRZHUIXO�FRQFHSW�WKDW�FRPHVWR�3HUO�IURP�WKH�ZRUOG�RI�/LVS��$�FORVXUH�LV��URXJKO\�VSHDNLQJ��DQ�DQRQ\PRXV�VXEURXWLQHZLWK�LWV�RZQ�SULYDWH�GDWD��$JDLQ��FRYHUHG�LQ�WKH�$OSDFD�ERRN�

Tied Variables$�WLHG�YDULDEOH�PD\�EH�DFFHVVHG�OLNH�DQ\�RWKHU��EXW�XVLQJ�\RXU�RZQ�FRGH�EHKLQG�WKHVFHQHV��6R�\RX�FRXOG�PDNH�D�VFDODU�WKDW�LV�UHDOO\�VWRUHG�RQ�D�UHPRWH�PDFKLQH��RU�DQDUUD\�WKDW�DOZD\V�VWD\V�VRUWHG��6HH�WKH�SHUOWLH�PDQSDJH�

Operator Overloading<RX�FDQ�UHGHILQH�RSHUDWRUV�OLNH�DGGLWLRQ��FRQFDWHQDWLRQ��FRPSDULVRQ��RU�HYHQ�WKH�LP�SOLFLW�VWULQJ�WR�QXPEHU�FRQYHUVLRQ�ZLWK�WKH�overload�PRGXOH��7KLV�LV�KRZ�D�PRGXOHLPSOHPHQWLQJ�FRPSOH[�QXPEHUV��IRU�H[DPSOH��FDQ�OHW�\RX�PXOWLSO\�D�FRPSOH[�QXPEHUE\�8�WR�JHW�D�FRPSOH[�QXPEHU�DV�D�UHVXOW�

Dynamic Loading7KH�EDVLF�LGHD�RI�G\QDPLF�ORDGLQJ�LV�WKDW�\RXU�SURJUDP�GHFLGHV�DW�UXQWLPH�WKDW�LW�QHHGVPRUH�IXQFWLRQDOLW\�WKDQ�ZKDW¦V�FXUUHQWO\�DYDLODEOH��VR�LW�ORDGV�LW�XS�DQG�NHHSV�UXQQLQJ�<RX�FDQ�DOZD\V�G\QDPLFDOO\�ORDG�3HUO�FRGH��EXW�LW¦V�HYHQ�PRUH�LQWHUHVWLQJ�WR�G\QDPL�FDOO\�ORDG�D�ELQDU\�H[WHQVLRQ� �7KLV�LV�KRZ�QRQ�3HUO�PRGXOHV�DUH�PDGH�

Embedding7KH�UHYHUVH�RI�G\QDPLF�ORDGLQJ��LQ�D�VHQVH��LV�HPEHGGLQJ�

6XSSRVH�\RX�ZDQW�WR�PDNH�D�UHDOO\�FRRO�ZRUG�SURFHVVRU��DQG�\RX�VWDUW�ZULWLQJ�LW�LQ��VD\�&�����1RZ��\RX�GHFLGH�\RX�ZDQW�WKH�XVHUV�WR�EH�DEOH�WR�XVH�3HUO¦V�UHJXODU�H[SUHVVLRQVIRU�DQ�H[WUD�SRZHUIXO�VHDUFK�DQG�UHSODFH�IHDWXUH��VR�\RX�HPEHG�3HUO�LQWR�\RXU�SURJUDP�7KHQ�\RX�UHDOL]H�WKDW�\RX�FRXOG�RSHQ�XS�VRPH�RI�WKH�SRZHU�RI�3HUO�WR�\RXU�XVHUV��$

'\QDPLF�ORDGLQJ�RI�ELQDU\�H[WHQVLRQV�LV�JHQHUDOO\�DYDLODEOH�LI�\RXU�V\VWHP�VXSSRUWV�WKDW��,I�LW�GRHVQ¦W��\RXFDQ�FRPSLOH�WKH�H[WHQVLRQV�VWDWLFDOO\¢WKDW�LV��\RX�FDQ�PDNH�D�3HUO�ELQDU\�ZLWK�WKH�H[WHQVLRQ�EXLOW�LQ��UHDG\IRU�XVH�

� 7KDW¦V�SUREDEO\�WKH�ODQJXDJH�ZH¦G�XVH�IRU�ZULWLQJ�D�ZRUG�SURFHVVRU��+H\��ZH�ORYH�3HUO��EXW�ZH�GLGQ¦W�VZHDUDQ�RDWK�LQ�EORRG�WR�XVH�QR�RWKHU�ODQJXDJH��:KHQ�ODQJXDJH�;�LV�WKH�EHVW�FKRLFH��XVH�ODQJXDJH�;��%XW�RIWHQ��;HTXDOV�3HUO�

Tied Variables | 311

SRZHU�XVHU�FRXOG�ZULWH�D�VXEURXWLQH�LQ�3HUO�WKDW�FRXOG�EHFRPH�D�PHQX�LWHP�LQ�\RXUSURJUDP��8VHUV�FDQ�FXVWRPL]H�WKH�RSHUDWLRQ�RI�\RXU�ZRUG�SURFHVVRU�E\�ZULWLQJ�D�OLWWOH3HUO��1RZ�\RX�RSHQ�XS�D�OLWWOH�VSDFH�RQ�\RXU�ZHE�VLWH�ZKHUH�XVHUV�FDQ�VKDUH�DQG�H[�FKDQJH�WKHVH�3HUO�VQLSSHWV��DQG�\RX¦YH�JRW�WKRXVDQGV�RI�QHZ�SURJUDPPHUV�H[WHQGLQJZKDW�\RXU�SURJUDP�FDQ�GR�DW�QR�H[WUD�FRVW�WR�\RXU�FRPSDQ\��$QG�KRZ�PXFK�GR�\RXKDYH�WR�SD\�/DUU\�IRU�DOO�WKLV"�1RWKLQJ¢VHH�WKH�OLFHQVHV�WKDW�FRPH�ZLWK�3HUO��/DUU\�LVD�UHDOO\�QLFH�JX\��<RX�VKRXOG�DW�OHDVW�VHQG�KLP�D�WKDQN�\RX�QRWH�

$OWKRXJK�ZH�GRQ¦W�NQRZ�RI�VXFK�D�ZRUG�SURFHVVRU��VRPH�IRONV�KDYH�DOUHDG\�XVHG�WKLVWHFKQLTXH� WR� PDNH� RWKHU� SRZHUIXO� SURJUDPV�� 2QH� VXFK� H[DPSOH� LV� $SDFKH¦Vmod_perl��ZKLFK�HPEHGV�3HUO�LQWR�DQ�DOUHDG\�SRZHUIXO�ZHE�VHUYHU��,I�\RX¦UH�WKLQNLQJDERXW�HPEHGGLQJ�3HUO��\RX�VKRXOG�FKHFN�RXW�mod_perl��VLQFH�LW¦V�DOO�RSHQ�VRXUFH��\RXFDQ�VHH�MXVW�KRZ�LW�ZRUNV�

Converting Other Languages to Perl,I�\RX¦YH�JRW�ROG�VHG�DQG�DZN�SURJUDPV�WKDW�\RX�ZLVK�ZHUH�ZULWWHQ�LQ�3HUO��\RX¦UH�LQOXFN��1RW�RQO\�FDQ�3HUO�GR�HYHU\WKLQJ�WKDW�WKRVH�FDQ�GR��WKHUH¦V�DOVR�D�FRQYHUVLRQ�SUR�JUDP�DYDLODEOH��DQG�LW¦V�SUREDEO\�DOUHDG\�LQVWDOOHG�RQ�\RXU�V\VWHP��&KHFN�WKH�GRFX�PHQWDWLRQ�IRU�V�S��IRU�FRQYHUWLQJ�IURP�VHG��RU�D�S��IRU�FRQYHUWLQJ�IURP�DZN�� �6LQFHSURJUDPV�GRQ¦W�ZULWH�SURJUDPV�DV�ZHOO�DV�SHRSOH�GR��WKH�UHVXOWV�ZRQ¦W�QHFHVVDULO\�EHWKH�EHVW�3HUO¢EXW�LW¦V�D�VWDUW��DQG�LW¦V�HDV\�WR�WZHDN��7KH�WUDQVODWHG�SURJUDP�PD\�EHIDVWHU�RU�VORZHU�WKDQ�WKH�RULJLQDO��WRR��%XW�DIWHU�\RX¦YH�IL[HG�XS�DQ\�JURVV�LQHIILFLHQFLHVLQ�WKH�PDFKLQH�ZULWWHQ�3HUO�FRGH��LW�VKRXOG�EH�FRPSDUDEOH�

'R�\RX�KDYH�&�DOJRULWKPV�\RX�ZDQW�WR�XVH�IURP�3HUO"�:HOO��\RX¦YH�VWLOO�JRW�VRPH�OXFNRQ�\RXU�VLGH��LW¦V�QRW�WRR�KDUG�WR�SXW�&�FRGH�LQWR�D�FRPSLOHG�PRGXOH�WKDW�FDQ�EH�XVHGIURP�3HUO��,Q�IDFW��DQ\�ODQJXDJH�WKDW�FRPSLOHV�WR�PDNH�REMHFW�FRGH�FDQ�JHQHUDOO\�EHXVHG�WR�PDNH�D�PRGXOH��6HH�WKH�SHUO[V�PDQSDJH��DQG�WKH�Inline�PRGXOH��DV�ZHOO�DV�WKH6:,*�V\VWHP�

'R�\RX�KDYH�D�VKHOO�VFULSW�WKDW�\RX�ZDQW�WR�FRQYHUW�WR�3HUO"�<RXU�OXFN�MXVW�UDQ�RXW�7KHUH¦V�QR�DXWRPDWLF�ZD\�WR�FRQYHUW�VKHOO�WR�3HUO��7KDW¦V�EHFDXVH�WKH�VKHOO�KDUGO\�GRHVDQ\WKLQJ�E\�LWVHOI��LW�VSHQGV�DOO�RI�LWV�WLPH�UXQQLQJ�RWKHU�SURJUDPV��6XUH��ZH�FRXOG�PDNHD�SURJUDP�WKDW�ZRXOG�PRVWO\�MXVW�FDOO�system�IRU�HDFK�OLQH�RI�WKH�VKHOO��EXW�WKDW�ZRXOGEH�PXFK�VORZHU�WKDQ�MXVW�OHWWLQJ�WKH�VKHOO�GR�WKLQJV�LQ�WKH�ILUVW�SODFH��,W�UHDOO\�WDNHV�DKXPDQ�OHYHO�RI�LQWHOOLJHQFH�WR�VHH�KRZ�WKH�VKHOO¦V�XVH�RI�FXW��UP��VHG��DZN��DQG�JUHS�FDQEH�WXUQHG�LQWR�HIILFLHQW�3HUO�FRGH��,W¦V�EHWWHU�WR�UHZULWH�WKH�VKHOO�VFULSW�IURP�VFUDWFK�

,I�\RX¦UH�XVLQJ�JDZN�RU�QDZN�RU�VRPH�RWKHU�YDULDQW��D�S�PD\�QRW�EH�DEOH�WR�FRQYHUW�LW��%RWK�RI�WKHVH�FRQYHUVLRQSURJUDPV�ZHUH�ZULWWHQ�ORQJ�DJR�DQG�KDYH�KDG�IHZ�XSGDWHV�H[FHSW�ZKHQ�QHHGHG�WR�NHHS�ZRUNLQJ�ZLWK�QHZUHOHDVHV�RI�3HUO�

312 | Appendix B:ಗBeyond the Llama

Converting find Command Lines to Perl$�FRPPRQ�WDVN�IRU�D�V\VWHP�DGPLQLVWUDWRU�LV�WR�UHFXUVLYHO\�VHDUFK�WKH�GLUHFWRU\�WUHH�IRUFHUWDLQ�LWHPV��2Q�8QL[��WKLV�LV�W\SLFDOO\�GRQH�ZLWK�WKH�ILQG�FRPPDQG��:H�FDQ�GR�WKDWGLUHFWO\�IURP�3HUO��WRR�

7KH�ILQG�SHUO�FRPPDQG��ZKLFK�FRPHV�ZLWK�3HUO��WDNHV�WKH�VDPH�DUJXPHQWV�WKDW�ILQGGRHV��,QVWHDG�RI�ILQGLQJ�WKH�UHTXHVWHG�LWHPV��KRZHYHU��WKH�RXWSXW�RI�ILQG�SHUO�LV�D�3HUOSURJUDP�WKDW�ILQGV�WKHP��6LQFH�LW¦V�D�SURJUDP��\RX�FDQ�HGLW�LW�IRU�\RXU�RZQ�QHHGV���7KHSURJUDP�LV�ZULWWHQ�LQ�D�VRPHZKDW�RGG�VW\OH��

2QH�XVHIXO�DUJXPHQW�WKDW¦V�DYDLODEOH�LQ�ILQG�SHUO�EXW�QRW�LQ�WKH�VWDQGDUG�ILQG� LV�WKH-eval�RSWLRQ��7KLV�VD\V�WKDW�ZKDW�IROORZV�LW�LV�DFWXDO�3HUO�FRGH�WKDW�VKRXOG�EH�UXQ�HDFKWLPH�WKDW�D�ILOH�LV�IRXQG��:KHQ�LW¦V�UXQ��WKH�FXUUHQW�GLUHFWRU\�ZLOO�EH�WKH�GLUHFWRU\�LQZKLFK�VRPH�LWHP�LV�IRXQG��DQG�$_�ZLOO�FRQWDLQ�WKH�LWHP¦V�QDPH�

+HUH¦V� DQ� H[DPSOH� RI� KRZ� \RX�PLJKW� XVH� ILQG�SHUO�� 6XSSRVH� WKDW� \RX¦UH� D� V\VWHPDGPLQLVWUDWRU�RQ�D�8QL[�PDFKLQH��DQG�\RX�ZDQW�WR�ILQG�DQG�UHPRYH�DOO�RI�WKH�ROG�ILOHVLQ�WKH��WPS�GLUHFWRU\� �+HUH¦V�WKH�FRPPDQG�WKDW�ZULWHV�WKH�SURJUDP�WR�GR�WKDW�

$ find2perl /tmp -atime +14 -eval unlink >Perl-program

7KDW�FRPPDQG�VD\V�WR�VHDUFK�LQ��WPS��DQG�UHFXUVLYHO\�LQ�VXEGLUHFWRULHV��IRU�LWHPV�ZKRVHDWLPH��ODVW�DFFHVV�WLPH��LV�DW�OHDVW����GD\V�DJR��)RU�HDFK�LWHP��WKH�SURJUDP�VKRXOG�UXQWKH�3HUO�FRGH�unlink��ZKLFK�ZLOO�XVH�$_�E\�GHIDXOW�DV�WKH�QDPH�RI�D�ILOH�WR�UHPRYH��7KHRXWSXW��UHGLUHFWHG�WR�JR�LQWR�WKH�ILOH�3HUO�SURJUDP��LV�WKH�SURJUDP�WKDW�GRHV�DOO�RI�WKLV�1RZ�\RX�PHUHO\�QHHG�WR�DUUDQJH�IRU�LW�WR�EH�UXQ�DV�QHHGHG�

Command-Line Options in Your Programs,I�\RX¦G�OLNH�WR�PDNH�SURJUDPV�WKDW�WDNH�FRPPDQG�OLQH�RSWLRQV��OLNH�3HUO¦V�RZQ�-w�IRUZDUQLQJV��IRU�H[DPSOH���WKHUH�DUH�PRGXOHV�WKDW�OHW�\RX�GR�WKLV�LQ�D�VWDQGDUG�ZD\��6HHWKH�GRFXPHQWDWLRQ�IRU�WKH�Getopt::Long�DQG�Getopt::Std�PRGXOHV�

Embedded Documentation3HUO¦V�RZQ�GRFXPHQWDWLRQ�LV�ZULWWHQ�LQ�SRG��SODLQ�ROG�GRFXPHQWDWLRQ��IRUPDW��<RX�FDQHPEHG�WKLV�GRFXPHQWDWLRQ�LQ�\RXU�RZQ�SURJUDPV��DQG�LW�FDQ�WKHQ�EH�WUDQVODWHG�WR�WH[W�+70/��RU�PDQ\�RWKHU�IRUPDWV�DV�QHHGHG��6HH�WKH�SHUOSRG�PDQSDJH��7KH�$OSDFD�ERRNFRYHUV�WKLV��WRR�

7KLV�LV�D�WDVN�W\SLFDOO\�GRQH�E\�D�FURQ�MRE�DW�VRPH�HDUO\�PRUQLQJ�KRXU�HDFK�GD\�

Converting find Command Lines to Perl | 313

More Ways to Open Filehandles7KHUH�DUH�RWKHU�PRGHV�WR�XVH�LQ�RSHQLQJ�D�ILOHKDQGOH��VHH�WKH�SHUORSHQWXW�PDQSDJH�

Locales and Unicode,W¦V�D�VPDOO�ZRUOG��DIWHU�DOO��,Q�RUGHU�WR�ZRUN�SURSHUO\�LQ�SODFHV�ZKHUH�HYHQ�WKH�DOSKDEHWLV�GLIIHUHQW��3HUO�KDV�VXSSRUW�IRU�ORFDOHV�DQG�8QLFRGH�

/RFDOHV�WHOO�3HUO�KRZ�WKLQJV�DUH�GRQH�ORFDOO\��)RU�H[DPSOH��GRHV�WKH�FKDUDFWHU���VRUW�DWWKH�HQG�RI�WKH�DOSKDEHW��RU�EHWZHHQ�Ð�DQG��"�$QG�ZKDW¦V�WKH�ORFDO�QDPH�IRU�WKH�WKLUGPRQWK"�6HH�WKH�SHUOORFDOH�PDQSDJH��QRW�WR�EH�FRQIXVHG�ZLWK�WKH�SHUOORFDO�PDQSDJH��

6HH�WKH�SHUOXQLFRGH�PDQSDJH�IRU�WKH�ODWHVW�RQ�KRZ�\RXU�YHUVLRQ�RI�3HUO�GHDOV�ZLWK�8QL�FRGH�� $V� RI� WKLV� ZULWLQJ�� HDFK� QHZ� UHOHDVH� RI� 3HUO� KDV� PDQ\� QHZ� 8QLFRGH�UHODWHGFKDQJHV��EXW�ZH�KRSH�WKLQJV�ZLOO�VHWWOH�GRZQ�VRRQ�

Threads and Forking3HUO�QRZ�KDV�VXSSRUW�IRU�WKUHDGV��$OWKRXJK�WKLV�LV�H[SHULPHQWDO��DV�RI�WKLV�ZULWLQJ���LWFDQ�EH�D�XVHIXO�WRRO�IRU�VRPH�DSSOLFDWLRQV��8VLQJ�fork��ZKHUH�LW¦V�DYDLODEOH��LV�EHWWHUVXSSRUWHG��VHH�WKH�SHUOIRUN�DQG�SHUOWKUWXW�PDQSDJHV�

Graphical User Interfaces (GUIs)$�ODUJH�DQG�SRZHUIXO�PRGXOH�VHW�LV�Tk��ZKLFK�OHWV�\RX�PDNH�RQVFUHHQ�LQWHUIDFHV�WKDWZRUN�RQ�PRUH�WKDQ�RQH�SODWIRUP��6HH�0DVWHULQJ�3HUO�7N�E\�1DQF\�:DOVK�DQG�6WHYH/LGLH��2¦5HLOO\��

And More…,I�\RX�FKHFN�RXW�WKH�PRGXOH�OLVW�RQ�&3$1��\RX¦OO�ILQG�PRGXOHV�IRU�HYHQ�PRUH�SXUSRVHV�IURP�JHQHUDWLQJ� JUDSKV� DQG�RWKHU� LPDJHV� WR� GRZQORDGLQJ� HPDLO�� IURP� ILJXULQJ� WKHDPRUWL]DWLRQ�RI�D�ORDQ�WR�ILJXULQJ�WKH�WLPH�RI�VXQVHW��1HZ�PRGXOHV�DUH�DGGHG�DOO�WKHWLPH��VR�3HUO�LV�HYHQ�PRUH�SRZHUIXO�WRGD\�WKDQ�LW�ZDV�ZKHQ�ZH�ZURWH�WKLV�ERRN��:HFDQ¦W�NHHS�XS�ZLWK�LW�DOO��VR�ZH¦OO�VWRS�KHUH�

/DUU\�KLPVHOI�VD\V�KH�QR�ORQJHU�NHHSV�XS�ZLWK�DOO�RI�WKH�GHYHORSPHQW�RI�3HUO�EHFDXVHWKH�3HUO�XQLYHUVH�LV�ELJ�DQG�NHHSV�H[SDQGLQJ��$QG�EHFDXVH�KH�FDQ�DOZD\V�ILQG�DQRWKHUFRUQHU�RI�WKLV�HYHU�H[SDQGLQJ�XQLYHUVH��KH�FDQ¦W�JHW�ERUHG�ZLWK�3HUO��DQG��ZH�VXVSHFW�QHLWKHU�ZLOO�ZH��7KDQN�\RX��/DUU\�

314 | Appendix B:ಗBeyond the Llama

Index

Symbols���H[FODPDWLRQ�PDUN�

� ��QRW�HTXDO��RSHUDWRU����QRW�RSHUDWRU����

�����TXRWHV��GRXEOH�LQWHUSRODWLRQ�LQWR�SDWWHUQV�����LQ�VWULQJ�OLWHUDOV����

���SRXQG�VLJQ���LQ�FRPPHQWV�������VKHEDQJ��OLQH�LQ�SURJUDPV�������GROODU�VLJQ�

����LQ�HUURU�PHVVDJHV�������YDULDEOH�������PDWFK�YDULDEOH�������PDWFK�YDULDEOH������������PDWFK�YDULDEOHV������A,�YDULDEOH������B�GHIDXOW����������C�PDWFK�YDULDEOH�����HQG�RI�VWULQJ�DQFKRU�LQ�UHJXODU�H[SUHVVLRQV�

��������HVFDSLQJ�LQ�GRXEOH�TXRWHG�VWULQJV�����LQ�VFDODU�YDULDEOH�QDPHV����VFDODU�FRQWH[W�����VFDODU�FRQWH[W�VOLFHV�����

���SHUFHQW�VLJQ�KDVK�VOLFHV�DQG�����PRGXOXV�RSHUDWRU���������SULQWLQJ�ZLWK�SULQWI����UHIHUULQJ�WR�DQ�HQWLUH�KDVK����

�I�FRQYHUVLRQ������DPSHUVDQG�

��ORJLFDO�$1'��RSHUDWRU�����ELWZLVH�DQG�RSHUDWRU�����RPLWWLQJ�LQ�VXEURXWLQH�FDOOV����

LQ�VXEURXWLQH�QDPHV�������TXRWHV��VLQJOH�

HVFDSLQJ�VKHOO�PHWDFKDUDFWHUV�����LQ�VWULQJ�OLWHUDOV����

�����SDUHQWKHVHV�FDSWXULQJ�����LQ�ILOH�WHVWV�����JURXSLQJ�LQ�UHJXODU�H[SUHVVLRQ�SDWWHUQV�

���QRQ�FDSWXULQJ��"�������RSWLRQDO��IRU�SULQW����SUHFHGHQFH�LQ�UHJXODU�H[SUHVVLRQV�����

��DVWHULVN� ��H[SRQHQWLDWLRQ��RSHUDWRU���� "��QRQJUHHG\��TXDQWLILHU�����PXOWLSOLFDWLRQ�RSHUDWRU����TXDQWLILHU�LQ�UHJXODU�H[SUHVVLRQV�����

���SOXV�VLJQ�����DXWRLQFUHPHQW��RSHUDWRU������"��QRQ�JUHHG\��TXDQWLILHU�����DGGLWLRQ�RSHUDWRU����TXDQWLILHU�LQ�UHJXODU�H[SUHVVLRQV�����

���FRPPD���XVLQJ�ELJ�DUURZ�� !��IRU��������K\SKHQ���VSHFLI\LQJ�UDQJHV�LQ�D�FKDUDFWHU

FODVV��������PLQXV�VLJQ�

�����DXWRGHFUHPHQW��RSHUDWRU�����VXEWUDFWLRQ�RSHUDWRU����

�!��VPDOO�DUURZ���������GRW�

���GRW��DQG�����GRW�GRW��LQ�GLUHFWRU\�KDQGOHV���������

� ��GRW�VWDU��SDUDPHWHU��JORE�RSHUDWRU���������UDQJH��RSHUDWRU����

FRXQWLQJ�GRZQZDUG����

:H¦G�OLNH�WR�KHDU�\RXU�VXJJHVWLRQV�IRU�LPSURYLQJ�RXU�LQGH[HV��6HQG�HPDLO�WR�LQGH[#RUHLOO\�FRP�

315

����GRW�DQG�VODVK���FXUUHQW�ZRUNLQJ�GLUHFWRU\���

� ��FRQFDWHQDWLRQ�DQG�DVVLJQPHQW�RSHUDWRU����

UHJXODU�H[SUHVVLRQ�PHWDFKDUDFWHU�����VWULQJ�FRQFDWHQDWLRQ�RSHUDWRU����XVLQJ�ZLWK��V�WR�PDWFK�QHZOLQHV�����

���VODVK�����GHILQHG�RU��RSHUDWRU�����HQFORVLQJ�SDWWHUQV�����LQ�SDWWHUQ�PDWFKHV�����

���VHPLFRORQ�HQGLQJ�VWDWHPHQWV����RPLWWLQJ�DW�HQG�RI�3HUO�FRGH�EORFNV����

���OHVV�WKDQ��RSHUDWRU�������������ELWZLVH�VKLIW�OHIW��RSHUDWRU������ ��OHVV�WKDQ�RU�HTXDO�WR��RSHUDWRU����� !��VSDFHVKLS��FRPSDULVRQ�RSHUDWRU������!��GLDPRQG��RSHUDWRU����

LQ�SODFH�HGLWLQJ�RI�ILOHV�����XVH�RI�#$5*9�DUUD\����XVLQJ�ZLWK�SULQW����

�!��ILOHKDQGOH�UHDGLQJ�DQG�JOREELQJ����� ��HTXDOV�VLJQ�

��HTXDO��RSHUDWRU���� a��ELQGLQJ��RSHUDWRU����������

XVLQJ�ZLWK�VXEVWU����� !��ELJ�DUURZ������

TXRWLQJ�KDVK�NH\V�����!��JUHDWHU�WKDQ��RSHUDWRU���������!��JUHDWHU�WKDQ��VLJQ��FUHDWLQJ�D�QHZ�ILOH�IRU

LQSXW����! ��JUHDWHU�WKDQ�RU�HTXDO�WR��RSHUDWRU����!!��ELWZLVH�VKLIW�ULJKW��RSHUDWRU�����"��TXHVWLRQ�PDUN�

"���WHUQDU\��RSHUDWRU�����XVLQJ�DV�FRQWURO�VWUXFWXUH�����

""�QRQ�JUHHG\�TXDQWLILHU�����UHJXODU�H[SUHVVLRQ�TXDQWLILHU�����

#��DW�VLJQ�HVFDSLQJ�LQ�GRXEOH�TXRWHG�VWULQJV�����OLVW�FRQWH[W�����OLVW�FRQWH[W�VOLFHV�����UHIHUHQFHV�WR�DUUD\V����

LQWHUSRODWLRQ�RI�DUUD\V�LQWR�VWULQJV����#$5*9�DUUD\����#B�DUUD\�YDULDEOH

FKHFNLQJ�IRU�FRUUHFW�QXPEHU�RI�DUJXPHQWV���

VWRULQJ�VXEURXWLQH�DUJXPHQWV����>�@��VTXDUH�EUDFNHWV�

DUUD\�RSHUDWRU�����DUUD\V�LQWHUSRODWHG�LQWR�VWULQJV����HQFORVLQJ�FKDUDFWHU�FODVVHV�����

?��EDFNVODVK�HVFDSHV�LQ�GRXEOH�TXRWHG�VWULQJ�OLWHUDOV����HVFDSLQJ�TZ�OLVWV�LQ�VWULQJV����HVFDSLQJ�UHJXODU�H[SUHVVLRQ�PHWDFKDUDFWHUV�

���HVFDSLQJ�ZKHQ�SDVVLQJ�WR�WKH�VKHOO�����LQ�EDFN�UHIHUHQFHV�����

A��FDUHW�ELWZLVH�[RU�RSHUDWRU�����QHJDWLQJ�FKDUDFWHU�FODVVHV����������VWDUW�RI�VWULQJ�DQFKRU�LQ�UHJXODU�H[SUHVVLRQV�

��������B��XQGHUVFRUH�

LQ�YDULDEOH�QDPHV����YLUWXDO�ILOHKDQGOH�����

CC��EDFNTXRWHV�����XVLQJ�LQ�OLVW�FRQWH[W�����XVLQJ�WR�FDSWXUH�RXWSXW�����¡���

^�`��FXUO\�EUDFHV�GHOLPLWLQJ�YDULDEOH�QDPHV����HQFORVLQJ�FRGH�EORFNV����HQFORVLQJ�VXEURXWLQH�ERG\����KDVK�HOHPHQW�DFFHVV����LQ�KDVKHV�����P����SDWWHUQ�PDWFK��GHOLPLWHU�����UHJXODU�H[SUHVVLRQ�TXDQWLILHUV�����^�`"�QRQJUHHG\�TXDQWLILHU�����

_��YHUWLFDO�EDU�DOWHUQDWLRQ�LQ�UHJXODU�H[SUHVVLRQ�SDWWHUQ

PDWFKLQJ�����DOWHUQDWLRQ�LQ�UHJXODU�H[SUHVVLRQV�����ELWZLVH�RU�RSHUDWRU�����SLSH�FKDUDFWHU�����__��ORJLFDO�25��RSHUDWRU�����

a��WLOGH�ELWZLVH�QHJDWLRQ�RSHUDWRU�����aa��VPDUW�PDWFK��RSHUDWRU�����¡���

A$FFHVV�&RQWURO�/LVWV��$&/V������$FWLYH3HUO��[L$FWLYH6WDWH�SRUW�RI�3HUO�����DQFKRUV��UHJXODU�H[SUHVVLRQ�����

SUHFHGHQFH�����

316 | Index

DQG�RSHUDWRU�����$1'�RSHUDWRU���ORJLFDO�$1'������DQRQ\PRXV�VXEURXWLQHV�����$SDFKH�ZHE�VHUYHU��PRGBSHUO�����DUJXPHQWV

LQYRFDWLRQ��IRU�D�SURJUDP����VXEURXWLQH����

$5*9����$5*9287����DUUD\V

DFFHVVLQJ�HOHPHQWV����#$5*9�DUUD\����RI�ELWV��ELWVWULQJV������FRPSDULQJ�����IHDWXUHV�WR�PDQLSXODWH�DQ�HQWLUH�DUUD\�����ILQGLQJ�LQGH[�IRU�DQ�HOHPHQW����LQGH[LQJ��DYRLGLQJ�E\�XVLQJ�RSHUDWRUV����LQWHUSRODWLQJ�LQWR�VWULQJV��������

XVH�RI�TXRWDWLRQ�PDUNV����DQG�OLVWV��DQVZHUV�WR�H[HUFLVHV�����RI�VWULQJV����SULQWI�RSHUDWRU�DQG����VOLFLQJ�HOHPHQWV�IURP�����VSHFLDO�LQGLFHV����DV�VWDWH�YDULDEOHV����

$6&,,�PRGH����$6&,,��VRUWLQJ����DVVLJQPHQW����

ELQDU\�RSHUDWRUV����KDVKHV����OLVW�WR�D�KDVK�����OLVW�YDOXHV����¡��WR�OLVWV�DQG�DUUD\V��FRQWH[W����

DVVRFLDWLYLW\��RSHUDWRU����DWRPV�LQ�UHJXODU�H[SUHVVLRQV��SUHFHQGHQFH�RI�

���DXWRGHFUHPHQW�RSHUDWRU�����������DXWRLQFUHPHQW�RSHUDWRU����������

B?%��QRQZRUG�ERXQGDU\��DQFKRU�����?E��ZRUG�ERXQGDU\��DQFKRU�����EDFN�UHIHUHQFHV�����

SUHFHGHQFH�LQ�UHJXODU�H[SUHVVLRQV�����UHODWLYH��[Y

EDFNJURXQG�SURFHVVHV�����EDFNTXRWHV��VHH�C�C��XQGHU�6\PEROV�EDUHZRUGV�����

XQTXRWHG�KDVK�NH\V�����

EDVHQDPH�����)LOH��%DVHQDPH�PRGXOH�����

EDVHQDPH�IXQFWLRQ�����ELJ�DUURZ�� !�����������ELQDU\�ILOHV�����ELQGLQJ�RSHUDWRU�� a�����������

XVLQJ�ZLWK�VXEVWU�����ELWVWULQJV����������ELWZLVH�RSHUDWRUV�����EODQN�OLQHV��PDWFKLQJ�ZLWK�UHJXODU�H[SUHVVLRQV�

���EORFNV

ODEHOHG�����W\SHV�LQ�3HUO�����

EORJV��3HUO�UHODWHG�SRVWV����ERG\�RI�D�VXEURXWLQH����%RROHDQ�YDOXHV����

KDVK�XVHG�DV�����%RXUQH�6KHOO�����EXIIHULQJ�RXWSXW����EXJV���

UHSRUWLQJ����%XLOG�PRGXOH�����E\WHV��ILOH�VL]H�LQ�����

C&�ODQJXDJH���

FRQWURO�VWUXFWXUHV�����FRQYHUWLQJ�&�FRGH�WR�3HUO�����RSHUDWRUV�����VZLWFK�VWDWHPHQW�����

&�VKHOO�����FDSWXUHV

QDPHG�����QRQ�FDSWXULQJ�SDUHQWKHVHV�����

FDVHLQ�VWULQJ�FRPSDULVRQV����YDULDEOH�QDPHV����

FDVH�VKLIWLQJ�����FDVH�VWDWHPHQW��HPXODWLQJ�����FDVH�LQVHQVLWLYH���L��PDWFKLQJ�����FDW�FRPPDQG����FG�FRPPDQG�����&*,��&RPPRQ�*DWHZD\�,QWHUIDFH������&*,�PRGXOHV�����&*,�VFULSWLQJ���&*,�SP�PRGXOH�����FKDUDFWHU�FODVVHV�����

SUHFHGHQFH�LQ�UHJXODU�H[SUHVVLRQV�����

Index | 317

VKRUWFXWV�����FKDUDFWHUV��SUHFHGHQFH�LQ�UHJXODU�H[SUHVVLRQV�

���FKGLU�RSHUDWRU�����FKPRG�FRPPDQG����FKPRG�IXQFWLRQ�����FKRPS�FRPPDQG��UHPRYLQJ�QHZOLQHV�IURP

DUUD\�KROGLQJ�OLVW�RI�OLQHV����FKRPS�RSHUDWRU����FKRZQ�IXQFWLRQ�����FORVXUHV�����FPS�RSHUDWRU�����FRPPD������XVLQJ�ELJ�DUURZ�� !��IRU�����FRPPD�VHSDUDWHG�YDOXHV��&69���OLVW�OLWHUDOV����FRPPDQG�OLQH

LQ�SODFH�HGLWLQJ�IURP�����VWDUWLQJ�XS�&3$1�SP�����

FRPPDQG�OLQH�RSWLRQV�����LQ�\RXU�SURJUDPV�����

FRPPDQGV��H[WHUQDO���RXWSXW�RI����FRPPHQWV����

LQFOXGHG�LQ�ZKLWHVSDFH�LQ�D�SDWWHUQ�����TZ�OLVWV�DQG����

FRPS�ODQJ�SHUO �QHZVJURXSV����FRPSDULVRQ�RSHUDWRUV����FRPSDULVRQV

LQ�UHJXODU�PDWFKLQJ�����LQ�VPDUW�PDWFKLQJ�����

FRPSLODWLRQ�RI�SURJUDPV����FRPSOH[�QXPEHUV�����&21),*�ILOHKDQGOH����FRQQHFW�PHWKRG��'%,�PRGXOH������FRQVWDQW�SUDJPD�����FRQVWDQWV�LQ�OLVW�OLWHUDOV����FRQWH[W����¡��

IRUFLQJ�VFDODU�FRQWH[W����VFDODU�SURGXFLQJ�H[SUHVVLRQV�LQ�OLVW�FRQWH[W�

��FRQWLQXH�VWDWHPHQW��XVLQJ�DW�HQG�RI�ZKHQ

VWDWHPHQWV�����FRQWURO�VWUXFWXUHV�����¡���

DQVZHUV�WR�H[HUFLVHV�����DXWRLQFUHPHQW�DQG�DXWRGHFUHPHQW�����FRQQHFWLRQ�EHWZHHQ�IRUHDFK�DQG�IRU�����HOVLI�FODXVH�����H[SUHVVLRQ�PRGLILHUV�����IRU�����JLYHQ�ZKHQ�����ODEHOHG�EORFNV�����

ORJLFDO�RSHUDWRUV�����¡���ORRS�FRQWUROV�����¡���QDNHG�EORFN�����SDUWLDO�HYDOXDWLRQ�RSHUDWRUV�����WHUQDU\�RSHUDWRU��"�������XQOHVV�����XQWLO�����

&RQWURO�'��LQGLFDWLQJ�HQG�RI�ILOH�RQ�8QL[�EDVHG�V\VWHPV����

&RQWURO�=��LQGLFDWLQJ�HQG�RI�ILOH�RQ�:LQGRZVV\VWHPV����

FRQYHUVLRQV��SULQWI�IRUPDW�VWULQJ�����&3$1��&RPSUHKHQVLYH�3HUO�$UFKLYH�1HWZRUN��

������¡��������������VHH�DOVR�PRGXOHV�ILQGLQJ�PRGXOHV�����

FSDQ�VFULSW�����&3$1�SP�PRGXOH�����FWLPH�YDOXH�����FXUUHQF\�ILJXUHV��IRUPDWWLQJ�ZLWK�VSULQWI�����FXUUHQW�ZRUNLQJ�GLUHFWRU\����&ZG�PRGXOH�����

D?G��GLJLW��FKDUDFWHU�FODVV�����?'��QRQGLJLW��FKDUDFWHU��PDWFKLQJ�LQ�UHJXODU

H[SUHVVLRQV�����'$7$����GDWD�VWUXFWXUHV�����GDWDEDVHV�����GDWH�DQG�WLPH�YDOXHV

FKDQJLQJ�WLPHVWDPSV�����7LPH��/RFDO�PRGXOH�����WLPHVWDPSV�����

GDWH�FRPPDQG����������'%,��'DWDEDVH�,QWHUIDFH��PRGXOH�����GHEXJJLQJ�����GHFODUDWLRQV��PRGXOH�����GHIDXOWV���

�B����GHILQHG�IXQFWLRQ���������GHILQHG�RU������RSHUDWRU�����GHOHWH�IXQFWLRQ�����GHOLPLWHUV

QRQSDLUHG�����TZ�OLVWV����V�����VXEVWLWXWLRQ��RSHUDWRU�����

GHYLFH�QXPEHU��ILOHV������GLDJQRVWLFV�SUDJPD���������

318 | Index

GLDPRQG�RSHUDWRU��VHH��!��XQGHU�6\PEROV�GLH�IXQFWLRQ����GLUHFWRULHV�����

FKDQJLQJ�RZQHUVKLS�RI�ILOHV�����FKDQJLQJ�WLPHVWDPSV�����FUHDWLQJ�DQG�UHPRYLQJ�����GLUHFWRU\�KDQGOHV�����ILOHQDPH�JOREELQJ�����OLQNV�DQG�ILOHV�����¡���PRGLI\LQJ�SHUPLVVLRQV�����PRYLQJ�DURXQG�GLUHFWRU\�WUHH�����QDPHV�RQ�GLIIHUHQW�RSHUDWLQJ�V\VWHPV�����RSHUDWLRQV��DQVZHUV�WR�H[HUFLVHV�����UHFXUVLYH�OLVWLQJ�����UHPRYLQJ�ILOHV�����UHQDPLQJ�ILOHV�����VSHFLI\LQJ�IRU�PRGXOH�LQVWDOODWLRQ�����

GLUQDPH�IXQFWLRQ�����GLVFXVVLRQ�JURXSV����GRFXPHQWDWLRQ�����

GLVSOD\LQJ�ZLWK�SHUOGRF�FRPPDQG����HPEHGGLQJ�LQWR�SURJUDPV�����PRGXOHV�����

GRXEOH�TXRWH�LQWHUSRODWLRQ����GRXEOH�TXRWHG�VWULQJ�OLWHUDOV����GRXEOH�TXRWHG�VWULQJV

FDVH�VKLIWLQJ�LQ�����LQWHUSRODWLQJ�DUUD\V�LQWR����LQWHUSRODWLRQ�RI�D�KDVK�HOHPHQW�����

GRZQORDGV�IRU�WKLV�ERRN��[LLLG\QDPLF�ORDGLQJ�����

E�H��H[HFXWDEOH��FRPPDQG�OLQH�RSWLRQ�����HDFK�IXQFWLRQ�����HFKR�FRPPDQG�����HOHPHQWV��DUUD\�DQG�OLVW����HOVH�FODXVH��XQOHVV�VWDWHPHQW�����HOVH�NH\ZRUG����HOVLI�FODXVH�����HPDFV����HPDLO�DGGUHVVHV�LQ�GRXEOH�TXRWHG�VWULQJV����HPDLO��1HW��6073�PRGXOH�����HPEHGGLQJ�3HUO�LQWR�DSSOLFDWLRQV�����HPSW\�VWULQJV����HQG�RI�ILOH����

LQGLFDWLQJ�IRU�NH\ERDUG�LQSXW�����(19�KDVK����������HQYLURQPHQW�YDULDEOHV����������

(SRFK�����HUURUV

IDWDO�HUURUV�ZLWK�GLH�IXQFWLRQ����VWDQGDUG�HUURU�VWUHDP��67'(55�����WUDSSLQJ�ZLWK�HYDO�����

HYDO�VWDWHPHQWVDQVZHUV�WR�H[HUFLVHV�����WUDSSLQJ�HUURUV�����

H[FHSWLRQV�WR�UXOHV�LQ�3HUO���H[HF�IXQFWLRQ�����H[HFXWDEOH�SURJUDPV����H[HUFLVHV�DQG�WKHLU�DQVZHUV���H[LVWV�IXQFWLRQ�����H[LW�VWDWXV����H[LW�YDOXHV��8QL[������H[LWLQJ�ORRS�EORFNV�����H[SRQHQWLDWLRQ�RSHUDWRU����H[SRUW�WDJ�����H[SUHVVLRQ�PRGLILHUV�����H[SUHVVLRQV

FRQWH[W����¡��OLVW�SURGXFLQJ��XVLQJ�LQ�VFDODU�FRQWH[W����

H[WHQVLRQV�����3HUO�V\QWD[�����

H[WHQVLRQV��ILOH���3HUO�SURJUDPV�DQG����H[WHUQDO�FRPPDQGV��RXWSXW�RI����

F)DWDO�PRGXOH�����ILOH�WHVWV�����¡���

DQVZHUV�WR�H[HUFLVHV�����ELWZLVH�RSHUDWRUV�����OLVWHG��ZLWK�WKHLU�PHDQLQJV�����ORFDOWLPH�IXQFWLRQ�����OVWDW�IXQFWLRQ�����VWDFNHG�ILOH�WHVW�RSHUDWRUV�����VWDW�IXQFWLRQ�����WHVWLQJ�VHYHUDO�DWWULEXWHV�RI�D�ILOH�����

)LOH��%DVHQDPH�PRGXOH����������)LOH��%DVHQDPH��GLUQDPH�IXQFWLRQ�����)LOH��&RS\�PRGXOH�����)LOH��)LQG�PRGXOH�����)LOH��3DWK�PRGXOH�����)LOH��6SHF�PRGXOH����������ILOHKDQGOHV����

FKDQJLQJ�GHIDXOW�RXWSXW�ILOHKDQGOH����FORVLQJ����RSHQLQJ����RWKHU�ZD\V�WR�RSHQ�����

Index | 319

SURFHVVHV�DV�����UHDGLQJ�IURP��JOREELQJ�YHUVXV�����VWDQGDUG��UHRSHQLQJ����XVLQJ����XVLQJ�ZLWK�SULQW�RU�SULQWI�IXQFWLRQV����XVLQJ�ZLWK�VD\����B��XQGHUVFRUH���YLUWXDO�ILOHKDQGOH�����

ILOHQDPHV�����JOREELQJ�����IRU�3HUO�SURJUDPV����

ILOHV������VHH�DOVR�GLUHFWRULHV�UHQDPLQJ�����

ILQG�FRPPDQG��8QL[������ILQG�SHUO�FRPPDQG�����IODJV�����IODW�ILOH�GDWDEDVHV�����IORDWLQJ�SRLQW�QXPEHUV����

URXQGLQJ�RII����IRU�ORRS�����

FRQQHFWLRQ�ZLWK�IRUHDFK�����H[LWLQJ�ZLWK�ODVW�RSHUDWRU�����

IRUHDFK�FRQWURO�VWUXFWXUH����ZUDSSLQJ�JLYHQ�ZKHQ�VWUXFWXUH�����

IRUHDFK�ORRSH[LWLQJ�ZLWK�ODVW�RSHUDWRU�����LWHUDWLQJ�RYHU�D�UHWXUQ�YDOXH�VSOLW�����

IRUHDFK�PRGLILHU�����IRUNLQJ�����

WKUHDGV�DQG�����IRUPDWV�����IXQFWLRQV

EXLOW�LQWR�3HUO�����GHIDXOW���GRFXPHQWDWLRQ�����IRU�KDVKHV�����PDWKHPDWLFDO�����XVHU�GHILQHG��VHH�VXEURXWLQHV�XVLQJ�RQO\�VRPH�IURP�D�PRGXOH�����

G�J��JOREDO��PRGLILHU

XVLQJ�ZLWK�P����SDWWHUQ�PDWFK��RSHUDWRU����

XVLQJ�ZLWK�V�����VXEVWLWXWLRQ��RSHUDWRU�����JHWJUQDP�IXQFWLRQ�����JHWSZQDP�IXQFWLRQ�����JLG��JURXS�,'������JLYHQ�ZKHQ�FRQWURO�VWUXFWXUH��[YL�����¡���

DQVZHUV�WR�H[HUFLVHV�����ZKHQ�FODXVHV�ZLWK�PDQ\�LWHPV�����

JORE�RSHUDWRU�����XVLQJ�ZLWK�XQOLQN�����

JOREDO�YDULDEOHV�ZLWKLQ�VXEURXWLQH�ERG\����JOREELQJ�����JOREV�����JOXH�VWULQJ�����JPWLPH�IXQFWLRQ�����JUDSKLFDO�XVHU�LQWHUIDFHV��*8,V������JUHS�FRPPDQG�����JUHS�RSHUDWRU�����

SLFNLQJ�LWHPV�IURP�D�OLVW�����JURXS�,'��JLG������JURXSLQJ�LQ�SDWWHUQV�����*8,V��JUDSKLFDO�XVHU�LQWHUIDFHV������

H?�K��KRUL]RQWDO��ZKLWHVSDFH�����KDVKHV����¡���

DFFHVVLQJ�DQ�HOHPHQW����DQVZHUV�WR�H[HUFLVHV�����DVVLJQPHQW����GHILQHG�����(19�KDVK�����H[DPSOH�RI�W\SLFDO�XVH�����IXQFWLRQV�IRU�����LQWHUSRODWLRQ�RI�DQ�HOHPHQW�LQWR�D�VWULQJ�

���SDLULQJ�XS�NH\V�DQG�YDOXHV�ZLWK� !��WKH�ELJ

DUURZ������UHIHUULQJ�WR�WKH�HQWLUH�KDVK����VOLFLQJ�HOHPHQWV�IURP�����VRUWLQJ�E\�PXOWLSOH�NH\V�����VRUWLQJ�E\�YDOXH�����DV�VWDWH�YDULDEOHV����XQTXRWHG�NH\V�����XVHV�RI����

+DVNHOO��3HUO���LQ��3XJV�����+HOOR��ZRUOG��SURJUDP����

XVLQJ�VD\�LQVWHDG�RI�SULQW����+HUH�GRFXPHQWV�����KLJK�OHYHO�ODQJXDJHV���KLJK�SUHFLVLRQ�QXPEHUV�����KLJK�ZDWHU�PDUN�DOJRULWKP����KRPH�GLUHFWRU\�����KRVWQDPH�IXQFWLRQ�����+70/�����

320 | Index

I�L��FDVH�LQVHQVLWLYH��PDWFKLQJ������L�FRPPDQG�OLQH�RSWLRQ�����LI�FRQWURO�VWUXFWXUH���������LI�ORRS��H[LWLQJ�ZLWK�ODVW�RSHUDWRU�����LI�PRGLILHU�����LI�HOVHLI�HOVH�VWDWHPHQW�����,PDJH��6L]H�PRGXOH�����LPDJLQDU\�QXPEHUV�����LPSRUW�OLVWV�����LQGHQWDWLRQ�LQ�SURJUDPV����LQGH[�IXQFWLRQ�����

XVLQJ�ZLWK�VXEVWU�����LQGLFHV

DUUD\�DQG�OLVW��VWDUWLQJ�DW�]HUR����DUUD\��QRW�XVLQJ����VSHFLDO�DUUD\�LQGLFHV����VXEVWULQJ�����

LQGLUHFW�ILOHKDQGOH�UHDGV�����LQILQLWH�ORRSV�����LQRGHV�����

FKDQWHV�WR�����IRU�QHZ�ILOHV�LQ�D�GLUHFWRU\�����QXPEHU�IRU�D�ILOH�����

LQSXW�DQG�RXWSXW����DQVZHUV�WR�H[HUFLVHV�����DUUD\V�DQG�SULQWI�IXQFWLRQ����FDSWXULQJ�RXWSXW�XVLQJ�EDFNTXRWHV�����¡

���FKDQJLQJ�GHIDXOW�RXWSXW�ILOHKDQGOH����FORVLQJ�ILOHKDQGOHV����FUHDWLQJ�ZDUQLQJ�PHVVDJHV�ZLWK�ZDUQ

IXQFWLRQ����ILOHKDQGOHV����IRUPDWWHG�RXWSXW�ZLWK�SULQWI����JHWWLQJ�LQSXW�IURP�XVHUV����LQSXW�IURP�VWDQGDUG�LQSXW����LQSXW�IURP�WKH�GLDPRQG�RSHUDWRU���!�����NH\ERDUG�LQSXW��LQGLFDWLQJ�HQG�RI�ILOH����RSHQLQJ�ILOHKDQGOHV����RXWSXW�WR�VWDQGDUG�RXWSXW����RXWSXW�ZLWK�SULQW����RXWSXW�ZLWK�VD\����VWDQGDUG�ILOHKDQGOH��UHRSHQLQJ����XVLQJ�ILOHKDQGOHV�IRU�LQSXW����

LQWHJHU�OLWHUDOV����QRQGHFLPDO����

LQWHJHUV����XVLQJ�ELWZLVH�RSHUDWRUV�ZLWK�����

LQWHUSRODWLRQKDVK�HOHPHQW�LQWR�D�GRXEOH�TXRWHG�VWULQJ�

���LQWR�SDWWHUQV�����

LQWHUSUHWHUFRPSLOLQJ�DQG�UXQQLQJ�SURJUDPV����3DUURWW���SHUO���

LQWHUUXSW�VLJQDOV�����LQYRFDWLRQ�DUJXPHQWV��������,3&��LQWHUSURFHVV�FRPPXQLFDWLRQV������LWHPV��W\SHV�RI��RQ�8QL[�ILOHV\VWHP�����LWHUDWLRQ����

JMRLQ�IXQFWLRQ�����

KNH\V�IXQFWLRQ�����

L?/��ORZHUFDVH��HVFDSH�����ODEHOV�����ODUJH�QXPEHUV�����ODVW�RSHUDWRU�����OH[LFDO�YDULDEOHV��������OLE�SUDJPD�����OLEUDULHV�����OLFHQVHV�IRU�3HUO���OLQH�EUHDNV�����

�VHH�DOVR�QHZOLQHV�PDWFKLQJ�LQ�UHJXODU�H[SUHVVLRQV�����

OLQH�LQSXW�RSHUDWRUV�����VHH�DOVR��67',1!�RSHUDWRU��!��GLDPRQG��RSHUDWRU�����67',1!����

OLQN�FRXQW�����OLQN�IXQFWLRQ�����OLQNV�����¡���

QXPEHU�RI�KDUG�OLQNV�WR�D�ILOH�RU�GLUHFWRU\����

UHPRYLQJ�����V\PEROLF�����

OLVW�FRQWH[W����EDFNTXRWHV�LQ�����FDOOLQJ�VXEURXWLQHV�LQ����H[DPSOH�H[SUHVVLRQV�SURYLGLQJ����OLVW�VOLFH�����

Index | 321

P����SDWWHUQ�PDWFK��RSHUDWRU�XVHG�LQ�����XVLQJ�VFDODU�SURGXFLQJ�H[SUHVVLRQV�LQ����

OLVWV����DQG�DUUD\V��DQVZHUV�WR�H[HUFLVHV�����DVVLJQPHQW����¡��FRQYHUWLQJ�EHWZHHQ�D�KDVK�DQG����IHDWXUHV�WR�PDQLSXODWH�DQ�HQWLUH�OLVW�����OLWHUDOV����VHOHFWLQJ�LWHPV�ZLWK�JUHS�����VOLFLQJ�LWHPV�IURP�����WUDQVIRUPLQJ�OLVW�LWHPV�XVLQJ�PDS�����

OLWHUDOVIORDWLQJ�SRLQW����LQWHJHU����OLVW����QRQGHFLPDO�LQWHJHU����VWULQJ����

ORDGLQJ��G\QDPLF�����ORFDOHV�����ORFDOWLPH�IXQFWLRQ���������������ORJLFDO�RSHUDWRUV�����¡���

DQG�RSHUDWRU�����GHILQHG�RU����������RU�RSHUDWRU�����XVLQJ�DV�FRQWURO�VWUXFWXUHV�����YDOXH�RI�D�VKRUW�FLUFXLW�RSHUDWRU�����

ORRS�FRQWUROV�����ODVW�RSHUDWRU�����QH[W�RSHUDWRU�����UHGR�RSHUDWRU�����

ORRSV�������������VHH�DOVR�FRQWURO�VWUXFWXUHV�IRUHDFK��LWHUDWLRQ�WKURXJK����

OVWDW�IXQFWLRQ�����/:3�PRGXOH�����

M�P��PXOWLSOH�OLQH��UHJXODU�H[SUHVVLRQ�RSWLRQ�

���P����SDWWHUQ�PDWFK��RSHUDWRU�����

LQ�OLVW�FRQWH[W�����PDLOLQJ�OLVWV����0DNH0DNHU�PRGXOH�����PDS�RSHUDWRU����������PDWFK�YDULDEOHV�����

SHUVLVWHQFH�RI�����PDWKHPDWLFV�����PHPRU\

SHUVLVWHQFH�LQ�SDWWHUQ�PDWFKLQJ�����

WULJJHULQJ�LQ�SDWWHUQ�PDWFKLQJ�����PHWDFKDUDFWHUV�����

SUHFHGHQFH�LQ�UHJXODU�H[SUHVVLRQV�����VKHOO�����

PHWKRGV�����PNGLU�IXQFWLRQ�����PRGHV��ILOH�����0RGXOH��%XLOG�����PRGXOHV���������¡��������¡���

&*,�����&*,�SP�����&3$1�����&ZG�����'%,��'DWDEDVH�,QWHUIDFH������H[HUFLVH��DQVZHU�WR�����)DWDO�PRGXOH�����)LOH��%DVHQDPH����������)LOH��&RS\�����)LOH��6SHF����������ILQGLQJ�����,PDJH��6L]H�����LQVWDOOLQJ�����1HW��6073�����326,;�����6\V��+RVWQDPH�����7H[W��:UDS�����7LPH��/RFDO�����XVLQJ�RQO\�VRPH�IXQFWLRQV�����XVLQJ�VLPSOH�PRGXOHV�����ZULWLQJ�\RXU�RZQ�����

PRGXOXV�RSHUDWRU��������PRGBSHUO�PRGXOH��$SDFKH������PRQH\�QXPEHUV��IRUPDWWLQJ�ZLWK�VSULQWI�����PRXQWHG�YROXPH�����P\�QDPHVSDFH�����P\�RSHUDWRU��������P\�YDULDEOHV�����

N�Q�FRPPDQG�OLQH�RSWLRQ�����QDNHG�EORFN�����

H[LWLQJ�ZLWK�ODVW�RSHUDWRU�����QDPHV

ILOHKDQGOHV����KDVK����VXEURXWLQH����

QDPHVSDFHV��VXEURXWLQHV����1HW��6073�PRGXOH�����QHWZRUNLQJ�����

322 | Index

QHZOLQHVHQGLQJ�HUURU�PHVVDJHV����PDWFKLQJ�LQ�UHJXODU�H[SUHVVLRQV�����SULQWLQJ�DQG����UHPRYLQJ�ZLWK�FKRPS�RSHUDWRU����?Q��QHZOLQH�FKDUDFWHU�����

LQ�VWULQJ�OLWHUDOV����QHZVJURXSV����QH[W�RSHUDWRU�����QRQSDLUHG�GHOLPLWHUV�����QRW�RSHUDWRU�����QRW�RSHUDWRU��������18/�FKDUDFWHU����QXPEHUV����

LQ�DUUD\V����DXWRPDWLF�FRQYHUVLRQ�EHWZHHQ�VWULQJV����FRPSDULVRQ�RSHUDWRUV����FRQYHUVLRQV�E\�SULQWI�IRUPDW�VWULQJ����IORDWLQJ�SRLQW�OLWHUDOV����LQWHJHU�OLWHUDOV����LQWHUQDO�IRUPDW����QRQGHFLPDO�LQWHJHU�OLWHUDOV����QXPHULF�RSHUDWRUV����

QXPHULF�RSHUDWRUV����

OREMHFW�RULHQWHG��22��PRGXOHV�����REMHFW�RULHQWHG��22��SURJUDPPLQJ�����RFW�IXQFWLRQ�����RSHUDWLQJ�V\VWHPV

����VKHEDQJ��OLQH����HQYLURQPHQW�YDULDEOHV�����ILOH�DQG�GLUHFWRU\�QDPHV�����3HUO�RQ���ZRUNLQJ�GLUHFWRU\�����

RSHUDWRUVELQDU\�DVVLJQPHQW����ELWZLVH�����FKRPS����GRFXPHQWDWLRQ�����ILOH�WHVW�����ORJLFDO�����¡���QXPHULF����RYHUORDGLQJ�����SDUWLDO�HYDOXDWLRQ�RSHUDWRUV�����SUHFHGHQFH�DQG�DVVRFLDWLYLW\����VWULQJ����WHUQDU\��"���RSHUDWRU�����

RSWLRQ�PRGLILHUV�����

FRPELQLQJ�����GRFXPHQWDWLRQ�����VXEVWLWXWLRQV�����

RU�RSHUDWRU�����25�RSHUDWRU�__��ORJLFDO�25������RU�RSHUDWRU��GHILQHG�RU�����RXWSXW��VHH�LQSXW�DQG�RXWSXW�RYHUORDGLQJ��RSHUDWRU�����RZQHUVKLS��FKDQJLQJ�IRU�ILOHV�����

P�S�FRPPDQG�OLQH�RSWLRQ�����SDFNDJHV�����SDUDPHWHU�OLVWV

HPSW\����YDULDEOH�OHQJWK����

SDUHQW�GLUHFWRU\�����3DUURWW��LQWHUSUHWHU����SDUWLDO�HYDOXDWLRQ�RSHUDWRUV�����SDWWHUQ�PDWFK��P����RSHUDWRU�����

LQ�OLVW�FRQWH[W�����SDWWHUQ�PDWFKLQJ�����

�VHH�DOVR�UHJXODU�H[SUHVVLRQV�VPDUW�PDWFKLQJ�����¡���

SDWWHUQV������VHH�DOVR�UHJXODU�H[SUHVVLRQV�WHVW�SURJUDP�IRU�����

3HUOFRPSLODWLRQ�RI�SURJUDPV����FRQYHUWLQJ�RWKHU�ODQJXDJHV�WR�����FUHDWLQJ�SURJUDPV����H[DPSOH�SURJUDP����H[FHSWLRQV�WR�WKH�UXOHV���ILQGLQJ�RQ�GLIIHUHQW�V\VWHPV����OLPLWDWLRQV�RI���PDLQWHQDQFH�DQG�VXSSRUW���REWDLQLQJ�DQG�LQVWDOOLQJ���UHFHQW�GHYHORSPHQWV���VLWXDWLRQV�IRU�XVH�RI���WUDQVIHUULQJ�SURJUDPV�DPRQJ�GLIIHUHQW

PDFKLQHV����XVHV�RI���

3HUO���3RUWHUV���3HUO�������[L

QHZ�IHDWXUHV��[YXVLQJ�VD\�LQVWHDG�RI�SULQW�FRPPDQG����

3HUO�0RQJHUV����3HUO�3DFNDJH�0DQDJHU��330������SHUOGRF��������������

Index | 323

SHUOIDF�����SHUPLVVLRQ�ELWV�����

�PRGH�YDULDEOH�����SHUPLVVLRQ�YDOXHV�����SHUPLVVLRQV��PRGLI\LQJ�����SHUVLVWHQW��SULYDWH�YDULDEOHV�LQ�VXEURXWLQHV����SLSHOLQHV�����SP��3HUO�PRGXOH��ILOH�H[WHQVLRQ�����SRS�RSHUDWRU����SRUWDELOLW\���SRUWV�RI�3HUO�WR�QRQ�8QL[�V\VWHPV���326,;�PRGXOH�����SRVWGHFUHPHQW�����SRVWLQFUHPHQW�����SUDJPDV�����

GLDJQRVWLFV����VWULFW�FOHDQ����XVH�VWULFW����ZDUQLQJV��������

SUHFHGHQFHRSHUDWRU���������LQ�UHJXODU�H[SUHVVLRQV�����LQ�VPDUW�PDWFKLQJ�����

SUHGHFUHPHQW�����SUHLQFUHPHQW�����SULQW�FRPPDQG����SULQW�RSHUDWRU����

RXWSXW�WR�VWDQGDUG�RXWSXW����SULQWI�IXQFWLRQ����SULQWI�RSHUDWRU����SURFHGXUHV����SURFHVVHV�����¡���

DYRLGLQJ�XVH�RI�WKH�VKHOO�����EDFNJURXQG�����DV�ILOHKDQGOHV�����IRUNLQJ�����ODXQFKLQJ�D�FKLOG�SURFHVV�ZLWK�V\VWHP

IXQFWLRQ�����PDQDJHPHQW�RI��DQVZHUV�WR�H[HUFLVHV�����VHQGLQJ�DQG�UHFHLYLQJ�VLJQDOV�����

SURJUDPPLQJ�FRQFHSWV��EDVLF��[LSURJUDPPLQJ�ODQJXDJHV��FRQYHUWLQJ�WR�3HUO�

���SURJUDPV��FRQWHQWV�DQG�IRUPDWWLQJ����SURWRW\SHV��VXEURXWLQH����3XJV���SXVK�RSHUDWRU����

QTXDQWLILHUV�����

JHQHUDO�����QRQ�JUHHG\�����SUHFHGHQFH�LQ�UHJXODU�H[SUHVVLRQV�����

TXRWDWLRQ�PDUNVXQTXRWHG�KDVK�NH\V�����XVLQJ�ZLWK�LQWHUSRODWHG�DUUD\V����

TZ��TXRWHG�ZRUGV��VKRUWFXW����

R?5��OLQH�EUHDNV���PDWFKLQJ�LQ�UHJXODU

H[SUHVVLRQV�����UDQJH�RSHUDWRU�������

UHWXUQLQJ�OLVW�RI�YDOXHV��UHYHUVHG�RUGHU����UDQJH�RSHUDWRU����������UHDGGLU�RSHUDWRU�����UHDGOLQH�RSHUDWRU�����UHDGOLQN�IXQFWLRQ�����UHGR�RSHUDWRU�����UHIHUHQFHV�����UHJXODU�H[SUHVVLRQV�����¡���

DQFKRUV�����DQVZHUV�WR�H[HUFLVHV�����DXWRPDWLF�PDWFK�YDULDEOHV�����ELQGLQJ�RSHUDWRU�� a������FKDUDFWHU�FODVVHV�����GRFXPHQWDWLRQ�����JOREV�YHUVXV�����LQWHUSRODWLQJ�LQWR�SDWWHUQV�����MRLQ�IXQFWLRQ�����P����SDWWHUQ�PDWFK��RSHUDWRU�LQ�OLVW�FRQWH[W�

���PDWFK�YDULDEOHV�����PDWFKLQJ�PXOWLSOH�OLQHV�RI�WH[W�����PDWFKLQJ�ZLWK�DQVZHUV�WR�H[HUFLVHV�����QDPHG�FDSWXUHV�����QRQ�FDSWXULQJ�SDUHQWKHVHV�����QRQ�JUHHG\�TXDQWLILHUV�����RSWLRQ�PRGLILHUV����������SDWWHUQ�WHVW�SURJUDP�����SURFHVVLQJ�WH[W��DQVZHUV�WR�H[HUFLVHV�����TXDQWLILHUV����������UHJXODU�SDWWHUQ�PDWFKLQJ�����UHVRXUFHV�IRU�IXUWKHU�LQIRUPDWLRQ�����VPDUW�PDWFKLQJ�����VSOLW�RSHUDWRU�����VXEVWLWXWLRQV�ZLWK�V����RSHUDWRU�����¡���

324 | Index

XSGDWLQJ�PDQ\�ILOHV�����XVLQJ�VLPSOH�SDWWHUQV�����

UHODWLYH�EDFN�UHIHUHQFHV��[Y�����UHQDPH�IXQFWLRQ�����UHSRUWV��WHPSODWHV�IRU�����UHWXUQ�RSHUDWRU����UHWXUQ�YDOXHV��VXEURXWLQH����UHYHUVH�RSHUDWRU����

GHVFHQGLQJ�RUGHU�VRUWV�����UHWXUQV�LQ�OLVW�DQG�VFDODU�FRQWH[W����

ULQGH[�IXQFWLRQ�����UPGLU�IXQFWLRQ����������UPWUHH�IXQFWLRQ�����URXQGLQJ�QXPEHUV�����

S?6��QRQZKLWHVSDFH��FKDUDFWHU��PDWFKLQJ�LQ

UHJXODU�H[SUHVVLRQV�����?V��VSDFH��FKDUDFWHU�FODVV������V�PRGLILHU��PDWFKLQJ�DQ\�FKDUDFWHU�ZLWK�����V�����VXEVWLWXWLRQ��RSHUDWRU�����¡���

FDVH�VKLIWLQJ�����FKDQJLQJ�GHOLPLWHUV�����FKDQJLQJ�WDUJHW�ZLWK� a��ELQGLQJ��RSHUDWRU�

���JOREDO�UHSODFHPHQWV�ZLWK��J�����XVLQJ�LQ�PXOWLOLQH�VWULQJ�����

VD\�FRPPDQG����VD\�IXQFWLRQ����VFDODU�FRQWH[W����

H[DPSOH�H[SUHVVLRQV�SURYLGLQJ����IRUFLQJ����OLVW�VOLFH�����XVLQJ�OLVW�SURGXFLQJ�H[SUHVVLRQV����

VFDODU�YDOXHV����¡��DQVZHUV�WR�H[HUFLVHV�����DVVLJQPHQW�IRU�YDULDEOHV����LQWHUSRODWLRQ�RI�YDULDEOHV�LQWR�VWULQJV����QXPEHUV����RSHUDWRU�SUHFHGHQFH�DQG�DVVRFLDWLYLW\����SULQWLQJ�SURJUDP�RXWSXW����VXEURXWLQH�UHWXUQV��QRQ�VFDODU�YDOXHV����XVLQJ�VFDODU�SURGXFLQJ�H[SUHVVLRQV�LQ�OLVW

FRQWH[W����YDULDEOHV����

VFRSHPDWFK�YDULDEOHV�����P\�QDPHVSDFH�����P\�YDULDEOH�����

WHPSRUDU\�OH[LFDO�YDULDEOHV�����VHFXULW\�����

&*,�SURJUDPV�����VHTXHQFH�LQ�UHJXODU�H[SUHVVLRQV�����VKHOO�SURPSW����VKHOO�VFULSWV��FRQYHUWLQJ�WR�3HUO�����VKHOOV

DYRLGLQJ�XVH�RI�����HQYLURQPHQW�YDULDEOHV�����ILOHQDPH�PDWFKLQJ�SDWWHUQV��JOREV������PHWDFKDUDFWHUV�����ZRUNLQJ�GLUHFWRU\�����

VKLIW�RSHUDWRU����VKRUW�FLUFXLW�ORJLFDO�RSHUDWRUV�����VKRUWFXWV���VLGH�HIIHFWV�RI�FRQWUROOHG�H[SUHVVLRQV�����VLJQDOV��VHQGLQJ�DQG�UHFHLYLQJ�����VLQJOH�TXRWHG�VWULQJ�OLWHUDOV����VLQJOH�TXRWHG�VWULQJV

LQWHUSRODWLRQ�RI�DVVLJQHG�OLVWV����TZ�OLVWV�ZLWKLQ����

VL]H�LQ�E\WHV��ILOHV������VOLFHV�����¡���

DUUD\�����KDVK�����OLVW�LWHPV�����

VPDOO�DUURZ���!������VPDUW�PDWFK�RSHUDWRU��aa������¡���VPDUW�PDWFKLQJ�����

DQVZHUV�WR�H[HUFLVHV�����PL[LQJ�ZLWK�GXPE�PDWFKLQJ�����RUGHU�RI�RSHUDQGV�����VLWXDWLRQV�LQ�ZKLFK�LW�LVQW�XVHG�����XVLQJ�ZLWK�JLYHQ�ZKHQ�FRQWURO�VWUXFWXUH�

���VRFNHWV�����VRIW�OLQNV�����

�VHH�DOVR�V\PEROLF�OLQNV�VRUW�FRPPDQG����VRUW�RSHUDWRU����

FRQWH[W����VRUWLQJ�����¡���

D�KDVK�E\�PXOWLSOH�NH\V�����D�KDVK�E\�YDOXH�����XVLQJ�VRUW�VXEURXWLQH�����

VSOLFH�RSHUDWRU�����VSOLW�RSHUDWRU�����VSULQWI�IXQFWLRQ�����

IRUPDWWLQJ�FXUUHQF\�ILJXUHV�����

Index | 325

VWDFNLQJ�ILOH�WHVW�RSHUDWRUV�����VWDQGDUG�HUURU�VWUHDP��67'(55�����VWDQGDUG�LQSXW�VWUHDP��67',1�����VWDQGDUG�RXWSXW�VWUHDP��67'287�����VWDW�IXQFWLRQ�����VWDWH�YDULDEOHV����VWDWHPHQWV����67'(55�����67',1!�RSHUDWRU��������

LQ�OLVW�FRQWH[W����UHWXUQLQJ�XQGHI�YDOXH����

67'287����VWULFW�FOHDQ�SUDJPD����VWULQJ�FRQFDWHQDWLRQ�RSHUDWRU��������VWULQJ�UHSHWLWLRQ�RSHUDWRU��[�����VWULQJV����¡�������

LQ�DUUD\V����DUUD\V�RI����ELWVWULQJV�����FRPSDULQJ��RSHUDWRUV�IRU����FRPSDULVRQ�RSHUDWRUV����FRQYHUVLRQV�EHWZHHQ�QXPEHUV�DQG����FRQYHUVLRQV�E\�SULQWI�IRUPDW�VWULQJ����GRXEOH�TXRWHG�VWULQJ�OLWHUDOV����ILQGLQJ�D�VXEVWULQJ�XVLQJ�DQG�LQGH[�����IRUPDWWLQJ�ZLWK�VSULQWI�����KDVK�NH\����LQWHUSRODWLQJ�DUUD\�VOLFHV�LQWR�����LQWHUSRODWLQJ�DUUD\V�LQWR����LQWHUSRODWLQJ�KDVK�VOLFHV�LQWR�����LQWHUSRODWLRQ�RI�VFDODU�YDULDEOHV����MRLQLQJ�SLHFHV�LQWR�D�VLQJOH�VWULQJ�����OLWHUDOV����PXOWLOLQH�TXRWLQJ��+HUH�GRFXPHQWV������RFWDO�UHSUHVHQWDWLRQ�����RSHUDWRUV�IRU����VKHOO�PHWDFKDUDFWHUV��HVFDSLQJ�����VLQJOH�TXRWHG�VWULQJ�OLWHUDOV����VRUWLQJ����������VSOLWWLQJ�����VXEVWULQJV��PDQLSXODWLQJ�����

VWUXFWXUHG�SURJUDPPLQJ�ODQJXDJHV�����VWW\�FRPPDQG����VXE�NH\ZRUG����VXEURXWLQHV����¡��

DQRQ\PRXV�����DQVZHUV�WR�H[HUFLVHV�����DUJXPHQWV����GHILQLQJ����

LQYRNLQJ����OH[LFDO��P\��YDULDEOHV����QRQ�VFDODU�UHWXUQ�YDOXHV����RPLWWLQJ�DPSHUVDQG�LQ�FDOOV����SHUVLVWHQW��SULYDWH�YDULDEOHV����SULYDWH�YDULDEOHV�LQ����UHWXUQ�RSHUDWRU����UHWXUQ�YDOXHV����XVH�VWULFW�SUDJPD����YDULDEOH�OHQJWK�SDUDPHWHU�OLVWV����

VXEVWLWXWLRQ�RSHUDWRU��VHH�V����VXEVWU�RSHUDWRU�����VXEVWULQJV

ILQGLQJ��XVLQJ�DQ�LQGH[�����PDQLSXODWLQJ�ZLWK�VXEVWU�����

VXSSRUW�IRU�3HUO���VZLWFK�VWDWHPHQW��[YL

HPXODWLQJ�����V\PEROLF�OLQNV�����

JHWWLQJ�LQIRUPDWLRQ�RQ�����LPSOHPHQWDWLRQ�RQ�QRQ�8QL[�V\VWHPV�����

V\PEROV��LPSRUW�OLVWV�����V\POLQN�IXQFWLRQ�����6\V��+RVWQDPH�PRGXOH�����V\VWHP�GDWDEDVHV�����V\VWHP�IXQFWLRQ�����6\VWHP�9�,3&�����

TWHUQDU\�RSHUDWRU��"�������

XVLQJ�DV�FRQWURO�VWUXFWXUH�����WH[W�HGLWRUV����WH[W�ILOHV�����WH[W�PRGH����WH[W�SURFHVVLQJ�ZLWK�UHJXODU�H[SUHVVLRQV�����¡

���DQVZHUV�WR�H[HUFLVHV�����

7H[W��:UDS�PRGXOH�����WKUHDGV�����WLHG�YDULDEOHV�����WLPH�IXQFWLRQ����������7LPH��/RFDO�PRGXOH�����WLPHORFDO�IXQFWLRQ�����WLPHVWDPSV�����

FKDQJLQJ�����FRQYHUWLQJ�WR�KXPDQ�UHDGDEOH�IRUP�����

7N�PRGXOHV�����WRROER[�IRU�8QL[��[LWU�����WUDQVOLWHUDWLRQ��RSHUDWRU�����

326 | Index

WUXWK�YDOXH����

U?8��XSSHUFDVH��HVFDSH�����XQGHI�YDOXHV����

LQ�DUUD\V����FRQWH[W�DQG����FUHDWLQJ����LWHPV�DVVLJQHG�WR�D�OLVW�����LQ�OLVW�DVVLJQPHQW����

8QLFRGH�����8QLYHUVDO�7LPH�����8QL[

����VKHEDQJ��OLQH����ILOH�DQG�GLUHFWRU\�PRGHO�����PDUNLQJ�H[HFXWDEOH�SURJUDPV����WH[W�HGLWRUV�IRU�SURJUDPPLQJ����WRROER[��[L

XQOHVV�ORRS�����HOVH�FODXVH�����

XQOLQN�IXQFWLRQ�����XQOLQN�RSHUDWRU�����XQVKLIW�RSHUDWRU����XQWLO�ORRS�����XQZLQGLQJ�D�KDVK����XVH�GLUHFWLYH�����XVH�VWULFW�SUDJPD���������XVH�ZDUQLQJV�SUDJPD����8VHQHW�QHZVJURXSV����XVHU�LQSXW����XVHU�GHILQHG�IXQFWLRQV��VHH�VXEURXWLQHV�XVHU�,'��XLG������XVHUV�JURXSV����XWLPH�IXQFWLRQ�����

V?Y��YHUWLFDO��ZKLWHVSDFH�����YDOXHV�IXQFWLRQ�����YDULDEOH�LQWHUSRODWLRQ����YDULDEOH�LQWHUSRODWHG�VWULQJ�OLWHUDOV����YDULDEOH�OHQJWK�SDUDPHWHU�OLVWV����YDULDEOHV����

DXWRPDWLF�PDWFK�����EXLOW�LQ�����GHFODUDWLRQ�RI����GHIDXOW���OH[LFDO����OLVW�YDOXHV�DVVLJQHG�WR����

PDWFK�����QDPLQJ����SHUVLVWHQW��SULYDWH�YDULDEOHV����SULYDWH��LQ�VXEURXWLQHV����VFDODU����VFRSH�RI�����WLHG�����XVH�VWULFW�SUDJPD�ZLWK����

YDUV�SUDJPD�����YHF�RSHUDWRU�����YL����YRLG�FRQWH[W����

W�Z��ZDUQLQJV��FRPPDQG�OLQH�RSWLRQ��������?:��QRQZRUG��FKDUDFWHU��PDWFKLQJ�LQ�UHJXODU

H[SUHVVLRQV������Z��ZDUQLQJV��FRPPDQG�OLQH�RSWLRQ�����?Z��ZRUG�FKDUDFWHU���PDWFKLQJ�LQ�UHJXODU

H[SUHVVLRQV�����:DOO��/DUU\���ZDUQLQJ�PHVVDJHV��FUHDWLQJ�ZLWK�ZDUQ�IXQFWLRQ�

��ZDUQLQJV�����

EXLOW�LQWR�3HUO����ZDUQLQJV�SUDJPD���������ZHE�DSSOLFDWLRQV�����ZHE�FRPPXQLWLHV��3HUO�GLVFXVVLRQV����ZHE�VLWH�IRU�WKLV�ERRN��[LLL:HE��3HUO�DQG���ZKHQ�FODXVHV

JLYHQ�VWDWHPHQW�����ZLWK�PDQ\�LWHPV��LQ�JLYHQ�ZKHQ�VWDWHPHQW�

���PL[HG�VPDUW�DQG�GXPE�PDWFKLQJ�����

ZKLOH�ORRS���������H[LWLQJ�ZLWK�ODVW�RSHUDWRU�����UHDGLQJ�OLQHV�RI�LQSXW�IURP�GLDPRQG

RSHUDWRU�����ZKLWHVSDFH

DGGLQJ�WR�D�SDWWHUQ�ZLWK��[�����LQ�FKDUDFWHU�FODVVHV�����FKDUDFWHU�FODVVHV�LQ�3HUO����������FROODSVLQJ�����OHDGLQJ�ZKLWHVSDFH�LQ�ILOHKDQGOHV����TXRWHG�E\�ZKLWHVSDFH��TZ��VKRUWFXW����?V��VSDFH��FKDUDFWHU�FODVV�����VWULSSLQJ�OHDGLQJ�DQG�WUDLOLQJ�ZKLWHVSDFH�

���

Index | 327

:LQGRZV�V\VWHPV$FWLYH3HUO��[LILOHQDPH�JOREELQJ�����LQGLFDWLQJ�HQG�RI�ILOH�ZLWK�&RQWURO�=����

ZRUG�DQFKRUV��UHJXODU�H[SUHVVLRQ������ZRUG�SURFHVVRUV����

X[��VWULQJ�UHSHWLWLRQ��RSHUDWRU���������[�PRGLILHU��DGGLQJ�ZKLWHVSDFH�WR�D�SDWWHUQ�

���[RU�RSHUDWRU�����

328 | Index

About the Authors5DQGDO�/��6FKZDUW]�LV�D�WZR�GHFDGH�YHWHUDQ�RI�WKH�VRIWZDUH�LQGXVWU\��+H�LV�VNLOOHG�LQVRIWZDUH�GHVLJQ��V\VWHP�DGPLQLVWUDWLRQ��VHFXULW\��WHFKQLFDO�ZULWLQJ��DQG�WUDLQLQJ��5DQ�GDO� KDV� FRDXWKRUHG� WKH� £PXVW�KDYH¤� VWDQGDUGV�� 3URJUDPPLQJ� 3HUO�� /HDUQLQJ� 3HUO�/HDUQLQJ�3HUO�IRU�:LQ���6\VWHPV��DQG�(IIHFWLYH�3HUO�/HDUQLQJ��DQG�LV�D�UHJXODU�FROXPQLVWIRU�:HE7HFKQLTXHV��3HUIRUPDQFH&RPSXWLQJ��6\V$GPLQ��DQG�/LQX[�0DJD]LQH�

+H� LV� DOVR� D� IUHTXHQW� FRQWULEXWRU� WR� WKH� 3HUO� QHZVJURXSV�� DQG� KDV� PRGHUDWHGFRPS�ODQJ�SHUO�DQQRXQFH�VLQFH�LWV�LQFHSWLRQ��+LV�RIIEHDW�KXPRU�DQG�WHFKQLFDO�PDVWHU\KDYH�UHDFKHG�OHJHQGDU\�SURSRUWLRQV�ZRUOGZLGH��EXW�KH�SUREDEO\�VWDUWHG�VRPH�RI�WKRVHOHJHQGV�KLPVHOI���5DQGDO¦V�GHVLUH�WR�JLYH�EDFN�WR�WKH�3HUO�FRPPXQLW\�LQVSLUHG�KLP�WRKHOS�FUHDWH�DQG�SURYLGH�LQLWLDO�IXQGLQJ�IRU�7KH�3HUO�,QVWLWXWH��+H�LV�DOVR�D�IRXQGLQJ�ERDUGPHPEHU� RI� WKH� 3HUO� 0RQJHUV� �SHUO�RUJ��� WKH� ZRUOGZLGH� 3HUO� JUDVVURRWV� DGYRFDF\RUJDQL]DWLRQ�� 6LQFH� ������ 5DQGDO� KDV� RZQHG� DQG� RSHUDWHG� 6WRQHKHQJH�&RQVXOWLQJ6HUYLFHV�� ,QF��5DQGDO� FDQ�EH� UHDFKHG� IRU� FRPPHQW�DW�PHUO\Q#VWRQHKHQJH�FRP�� DQGZHOFRPHV�TXHVWLRQV�RQ�3HUO�DQG�RWKHU�UHODWHG�WRSLFV�

7RP�3KRHQL[�KDV�EHHQ�ZRUNLQJ�LQ�WKH�HGXFDWLRQ�ILHOG�VLQFH�������$IWHU�PRUH�WKDQWKLUWHHQ� \HDUV� RI� GLVVHFWLRQV�� H[SORVLRQV�� ZRUN�ZLWK� LQWHUHVWLQJ� DQLPDOV�� DQG� KLJK�YROWDJH�VSDUNV�GXULQJ�KLV�ZRUN�DW�D�VFLHQFH�PXVHXP��KH�VWDUWHG�WHDFKLQJ�3HUO�FODVVHVIRU�6WRQHKHQJH�&RQVXOWLQJ�6HUYLFHV��ZKHUH�KH¦V�ZRUNHG�VLQFH�������6LQFH�WKHQ��KH�KDVWUDYHOHG�WR�PDQ\�LQWHUHVWLQJ�ORFDWLRQV��VR�\RX�PLJKW�VHH�KLP�VRRQ�DW�D�3HUO�0RQJHUVPHHWLQJ��:KHQ�KH�KDV�WLPH��KH�DQVZHUV�TXHVWLRQV�RQ�8VHQHW¦V�FRPS�ODQJ�SHUO�PLVF�DQGFRPS�ODQJ�SHUO�PRGHUDWHG�QHZVJURXSV��DQG�FRQWULEXWHV�WR�WKH�GHYHORSPHQW�DQG�XVH�IXOQHVV�RI�3HUO��%HVLGHV�KLV�ZRUN�ZLWK�3HUO��3HUO�KDFNHUV��DQG�UHODWHG�WRSLFV��7RP�VSHQGVKLV� WLPH� RQ� DPDWHXU� FU\SWRJUDSK\� DQG� VSHDNLQJ� (VSHUDQWR�� +H� OLYHV� LQ� 3RUWODQG�2UHJRQ�

EULDQ�G�IR\�KDV�EHHQ�DQ�LQVWUXFWRU�IRU�6WRQHKHQJH�&RQVXOWLQJ�6HUYLFHV�VLQFH�������D3HUO�XVHU�VLQFH�KH�ZDV�D�SK\VLFV�JUDGXDWH�VWXGHQW��DQG�D�GLH�KDUG�0DF�XVHU�VLQFH�KH�ILUVWRZQHG�D�FRPSXWHU��+H�IRXQGHG�WKH�ILUVW�3HUO�XVHU�JURXS��WKH�1HZ�<RUN�3HUO�0RQJHUV�DV�ZHOO�DV�WKH�3HUO�DGYRFDF\�QRQSURILW�3HUO�0RQJHUV��,QF���ZKLFK�KHOSHG�IRUP�PRUH�WKDQ����3HUO�XVHU�JURXSV�DFURVV�WKH�JOREH��+H�PDLQWDLQV�WKH�SHUOIDT�SRUWLRQV�RI�WKH�FRUH3HUO�GRFXPHQWDWLRQ��VHYHUDO�PRGXOHV�RQ�&3$1��DQG�VRPH�VWDQGDORQH�VFULSWV��+H¦V�WKHSXEOLVKHU�RI�7KH�3HUO�5HYLHZ��D�PDJD]LQH�GHYRWHG�WR�3HUO��DQG�LV�D�IUHTXHQW�VSHDNHU�DWFRQIHUHQFHV�LQFOXGLQJ�WKH�3HUO�&RQIHUHQFH��3HUO�8QLYHUVLW\��0DUFXV(YDQV�%LR,QIRUPDW�LFV� ¦����DQG�<$3&��+LV�ZULWLQJV�RQ�3HUO�DSSHDU� LQ�7KH�2¦5HLOO\�1HWZRUN��7KH�3HUO-RXUQDO��'U��'REEV��DQG�7KH�3HUO�5HYLHZ��RQ�XVH�SHUO�RUJ��DQG�LQ�VHYHUDO�3HUO�8VHQHWJURXSV�

Colophon7KH�DQLPDO�RQ�WKH�FRYHU�RI�/HDUQLQJ�3HUO��)LIWK�(GLWLRQ� LV�D� OODPD��/DPD�JODPD���DUHODWLRQ�RI�WKH�FDPHO�QDWLYH�WR�WKH�$QGHDQ�UDQJH��$OVR�LQFOXGHG�LQ�WKLV�OODPRLG�JURXS

LV�WKH�GRPHVWLF�DOSDFD�DQG�WKHLU�ZLOG�DQFHVWRUV��WKH�JXDQDFR�DQG�WKH�YLFXxD��%RQHVIRXQG�LQ�DQFLHQW�KXPDQ�VHWWOHPHQWV�VXJJHVW�WKDW�GRPHVWLFDWLRQ�RI�WKH�DOSDFD�DQG�WKHOODPD�GDWHV�EDFN�DERXW�������\HDUV��,Q�������ZKHQ�6SDQLVK�FRQTXLVWDGRUV�RYHUUDQ�WKH,QFD�(PSLUH� LQ�WKH�KLJK�$QGHV�� WKH\�IRXQG�ERWK�DQLPDOV�SUHVHQW� LQ�JUHDW�QXPEHUV�7KHVH� OODPDV�DUH� VXLWHG� IRU�KLJK�PRXQWDLQ� OLIH�� WKHLU�KHPRJORELQ�FDQ� WDNH� LQ�PRUHR[\JHQ�WKDQ�WKDW�RI�RWKHU�PDPPDOV�

/ODPDV�FDQ�ZHLJK�XS�WR�����SRXQGV�DQG�DUH�PRVWO\�XVHG�DV�EHDVWV�RI�EXUGHQ��$�SDFN�WUDLQ�PD\�FRQWDLQ�VHYHUDO�KXQGUHG�DQLPDOV�DQG�FDQ�WUDYHO�XS�WR����PLOHV�SHU�GD\��/ODPDVZLOO�FDUU\�ORDGV�XS�WR����SRXQGV��EXW�KDYH�D�WHQGHQF\�WR�EH�VKRUW�WHPSHUHG�DQG�UHVRUWWR�VSLWWLQJ�DQG�ELWLQJ�WR�GHPRQVWUDWH�GLVSOHDVXUH��7R�RWKHU�SHRSOH�RI�WKH�$QGHV��OODPDVDOVR�SURYLGH�PHDW��ZRRO�IRU�FORWKLQJ��KLGHV�IRU�OHDWKHU��DQG�IDW�IRU�FDQGOHV��7KHLU�ZRROFDQ�DOVR�EH�EUDLGHG�LQWR�URSHV�DQG�UXJV��DQG�WKHLU�GULHG�GXQJ�LV�XVHG�IRU�IXHO�

7KH�FRYHU� LPDJH�LV�D���WK�FHQWXU\�HQJUDYLQJ�IURP�WKH�'RYHU�3LFWRULDO�$UFKLYH��7KHFRYHU�IRQW�LV�$GREH�,7&�*DUDPRQG��7KH�WH[W�IRQW�LV�/LQRW\SH�%LUND��WKH�KHDGLQJ�IRQWLV� $GREH� 0\ULDG� &RQGHQVHG�� DQG� WKH� FRGH� IRQW� LV� /XFDV)RQW¦V� 7KH6DQV� 0RQR&RQGHQVHG�